找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7812|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

第17章-DS1302時(shí)鐘芯片的單片機(jī)驅(qū)動(dòng)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
51單片機(jī)輕松入門—基于STC15W4K系列(C語(yǔ)言版)
李友全
編著 詳見:http://www.torrancerestoration.com/bbs/dpj-37954-1.html

第17章 DS1302時(shí)鐘芯片
1 電路圖
2 程序移植

使用單片機(jī)的定時(shí)器可以實(shí)現(xiàn)時(shí)鐘功能,

但程序較為復(fù)雜,單片機(jī)斷電后重新上電 時(shí)間需要重新設(shè)置,為了降低程序的復(fù)雜程度,解決斷電后重新上電的時(shí)間設(shè)置

問題,我們需要使用專用的時(shí)鐘芯片DS1302
1 電 路 圖
配套實(shí)驗(yàn)板1號(hào)單片機(jī)與時(shí)鐘芯片DS1302連接電路如圖所示。


4

為了簡(jiǎn)化實(shí)驗(yàn),電路中使用了100uF的電容代替電池,當(dāng)

單片機(jī)系統(tǒng)斷電后由電容維持DS1302的供電(3分鐘左右)。 當(dāng)作為長(zhǎng)期使用的時(shí)鐘時(shí),應(yīng)更換為3V的紐扣電池。


2 程 序 移 植
例17.1 讀取DS1302運(yùn)行過程中的年、月、日、時(shí)、分、秒數(shù)據(jù)并發(fā)送到計(jì)算機(jī)串口助手顯 示,單片機(jī)時(shí)鐘頻率22.1184MHz,波特率9600。串口助手接收區(qū)選擇“字符格式顯示”。

sbit SCK = P2^7; // 時(shí)鐘
sbit SDA = P4^5; // 數(shù)據(jù)
sbit RST = P4^6; // DS1302復(fù)位(片選)
unsigned char StartTime[7]= {14,11,30,23,50,59,7}; // 設(shè)定初始時(shí)間值
// 年、月、日、時(shí)、分、秒、星期* ,14-11-30 23:50:59 星期7

void main()

{
port_mode(); // 所有IO口設(shè)為準(zhǔn)雙向弱上拉方式。 UART_init(); // 波特率:9600/22.1184MHz Data_Swap(); // 數(shù)據(jù)交換
set_time(time); // 設(shè)定初始時(shí)間值 , 只設(shè)定1次,設(shè)定完成后應(yīng)屏蔽本行
while(1)
{
read_time(time); // 秒分時(shí)日月周年 UART_Send_PC(time);
delay_1S();
}
}



部分程序預(yù)覽(完整代碼請(qǐng)下載附件)
  1. /****************《51單片機(jī)輕松入門-基于STC15W4K系列》配套例程 *************
  2. ★★★★★★★★★★★★★★★★★★★★★★★★
  3. 《51單片機(jī)輕松入門-基于STC15W4K系列》 一書已經(jīng)由北航出版社正式出版發(fā)行。
  4.   作者親手創(chuàng)作的與教材配套的51雙核實(shí)驗(yàn)板(2個(gè)MCU)對(duì)程序下載、調(diào)試、仿真方便,不需要外部
  5.   仿真器與編程器,這種設(shè)計(jì)方式徹底解決了系統(tǒng)中多個(gè)最高優(yōu)先級(jí)誰也不能讓誰的中斷競(jìng)爭(zhēng)問題。
  6.   QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
  7.         驗(yàn)證信息:STC15單片機(jī)
  8.   郵箱:xgliyouquan@126.com
  9.   ★★★★★★★★★★★★★★★★★★★★★★★★*/

  10. #include "STC15W4K.H"
  11. #include "uart_debug.H"
  12. #include <intrins.h>
  13. sbit SCK = P2^7;                   // 時(shí)鐘        
  14. sbit SDA = P4^5;                      // 數(shù)據(jù)        
  15. sbit RST = P4^6;               // DS1302復(fù)位(片選)
  16. #define DS1302_W_ADDR 0x80           // 寫起始地址
  17. #define DS1302_R_ADDR 0x81            // 讀起始地址
  18. unsigned char StartTime[7]=        {14,11,30,23,50,59,7};  // 年月日時(shí)分秒周 14-11-30 23:50:59
  19. unsigned char time[8];  // 秒分時(shí)日月周年

  20. void Data_Swap()             // 數(shù)據(jù)交換
  21. {
  22.         time[0]=StartTime[5];         // 秒
  23.         time[1]=StartTime[4];         // 分
  24.         time[2]=StartTime[3];         // 時(shí)
  25.         time[3]=StartTime[2];         // 日
  26.         time[4]=StartTime[1];         // 月
  27.         time[5]=StartTime[6];         // 周
  28.         time[6]=StartTime[0];         // 年
  29.         time[7]=0;                                 // 最后一字節(jié)寫保護(hù)為0可寫入數(shù)據(jù)
  30. }

  31. // 寫字節(jié),低位在前,高位在后        
  32. void write_ds1302_byte(unsigned char dat)
  33. {
  34.         unsigned char i;
  35.         for (i=0;i<8;i++)
  36.         {
  37.                 SDA = dat & 0x01;  // bit型變量取值范圍是0和1,賦值非0結(jié)果為1
  38.                 SCK = 1;                   // 放入數(shù)據(jù)到時(shí)鐘上升沿時(shí)間 50nS
  39.                 dat >>= 1;                   // 時(shí)鐘上升沿后數(shù)據(jù)保持時(shí)間 70nS
  40.                 SCK = 0;                   // 時(shí)鐘低電平時(shí)間與時(shí)鐘高電平時(shí)間250nS
  41.         }
  42. }  
  43. // 清除寫保護(hù)
  44. void clear_ds1302_WP(void)
  45. {
  46.         RST = 0;           // RST引腳既是CE引腳
  47.         SCK = 0;
  48.         RST = 1;
  49.         write_ds1302_byte(0x8E);
  50.         write_ds1302_byte(0);
  51.         SDA = 0;
  52.         RST = 0;
  53. }        
  54. // 設(shè)置寫保護(hù)
  55. void set_ds1302_WP(void)
  56. {
  57.         RST = 0;           // RST引腳既是CE引腳
  58.         SCK = 0;
  59.         RST = 1;
  60.         write_ds1302_byte(0x8E);
  61.         write_ds1302_byte(0x80);
  62.         SDA = 0;
  63.         RST = 0;
  64. }

  65. // 連續(xù)寫入8個(gè)寄存器數(shù)據(jù),dat-待寫入數(shù)據(jù)指針  
  66. void write_ds1302_nbyte(unsigned char *dat)
  67. {
  68.     unsigned char i;
  69.     RST=0;
  70.         SCK=0;
  71.     RST = 1;
  72.     write_ds1302_byte(0xBE);  // 發(fā)送突發(fā)寫寄存器指令
  73.     for (i=0; i<8; i++)       // 連續(xù)寫入8字節(jié)數(shù)據(jù)
  74.     {
  75.         write_ds1302_byte(dat[i]);
  76.     }
  77.     RST = 0;
  78. }
  79. // 設(shè)定時(shí)鐘數(shù)據(jù)
  80. void set_time(unsigned char *timedata)
  81. {
  82.         unsigned char i, tmp;
  83.         for (i=0; i<7; i++)  // 轉(zhuǎn)化為壓縮BCD格式(一個(gè)字節(jié)存放2個(gè)BCD碼)
  84.         {
  85.                 tmp = timedata[i] / 10;                        // 獲取高位BCD碼
  86.                 timedata[i] = timedata[i] % 10;                // 獲取低位BCD碼
  87.                 timedata[i] = timedata[i] + tmp*16;        // 合并成壓縮BCD碼
  88.         }
  89.         clear_ds1302_WP();                                     // 清除寫保護(hù)
  90.         write_ds1302_nbyte(timedata);                    // 連續(xù)寫入8字節(jié)數(shù)據(jù)
  91.         set_ds1302_WP();                                // 寫保護(hù)
  92. }  

  93. // 讀字節(jié),低位在前,高位在后
  94. unsigned char read_ds1302_byte(void)
  95. {
  96.         unsigned char i, dat=0;        
  97.         for (i=0;i<8;i++)
  98.         {        
  99.                 dat >>= 1;
  100.                 if (SDA) dat |= 0x80;
  101.                 SCK = 1;
  102.                 SCK = 0;
  103.         }
  104.         return dat;
  105. }
  106. // 連續(xù)讀取8個(gè)寄存器的數(shù)據(jù),dat-讀取數(shù)據(jù)的接收指針  
  107. void read_time(unsigned char *dat)
  108. {
  109.     unsigned char i;  
  110.         RST=0;
  111.         SCK=0;
  112.     RST = 1;
  113.     write_ds1302_byte(0xBF);  //發(fā)送突發(fā)讀寄存器指令
  114.     for (i=0; i<8; i++)     //連續(xù)讀取8個(gè)字節(jié)
  115.     {
  116.         dat[i] = read_ds1302_byte();
  117.     }
  118.     RST = 0;
  119. }

  120. void delay_1S(void)
  121. {
  122.    unsigned char i,j,k;
  123.    for(i=85;i>0;i--)      // 注意后面沒分號(hào)
  124.    for(j=254;j>0;j--)     // 注意后面沒分號(hào)
  125.    for(k=255;k>0;k--);    // 注意后面有分號(hào)
  126. }
  127. // 單字節(jié)壓縮BCD碼轉(zhuǎn)換成ASCII碼另一常見格式示例,dat/16 + 0x30,
  128. // dat/16本質(zhì)就是右移4位,數(shù)字0--9加上0x30即得數(shù)字0--9的ASCII碼
  129. void UART_Send_PC(unsigned char *tmp)
  130. {
  131.         unsigned char str[12];           // 字符串轉(zhuǎn)換緩沖區(qū)
  132.         str[0] = '2';                    // 添加年份的高2位:20
  133.     str[1] = '0';
  134.     str[2] = (tmp[6] >> 4) + '0';    //“年”高位數(shù)字轉(zhuǎn)換為ASCII碼
  135.     str[3] = (tmp[6]&0x0F) + '0';    //“年”低位數(shù)字轉(zhuǎn)換為ASCII碼
  136.     str[4] = '-';  //添加日期分隔符
  137.     str[5] = (tmp[4] >> 4) + '0';    //“月”
  138.     str[6] = (tmp[4]&0x0F) + '0';
  139.     str[7] = '-';
  140.     str[8] = (tmp[3] >> 4) + '0';    //“日”
  141.     str[9] = (tmp[3]&0x0F) + '0';
  142.     str[10] = '\0';                                         // 字符串結(jié)束符
  143.         UART_Send_Str(str);                                 // 輸出  年、月、日
  144.         UART_Send_Str("   ");
  145.   
  146.     str[0] = (tmp[2] >> 4) + '0';    //“時(shí)”
  147.     str[1] = (tmp[2]&0x0F) + '0';
  148.     str[2] = ':';  //添加時(shí)間分隔符
  149.     str[3] = (tmp[1] >> 4) + '0';    //“分”
  150.     str[4] = (tmp[1]&0x0F) + '0';
  151.     str[5] = ':';
  152.     str[6] = (tmp[0] >> 4) + '0';    //“秒”
  153.     str[7] = (tmp[0]&0x0F) + '0';
  154.     str[8] = '\0';
  155.     UART_Send_Str(str);                   // 輸出  時(shí)、分、秒         
  156.         UART_Send_Str("   ");   
  157.         
  158.         UART_Send_Str("week = ");
  159.         str[0] = (tmp[5]&0x0F) + '0';    //“星期”
  160.     str[1] = '\0';
  161.         UART_Send_Str(str);                          // 輸出  星期  
  162.         UART_Send_Str("   ");
  163. }
  164. void port_mode()            // 端口模式
  165. {
  166.         P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
  167.         P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
  168. }
  169. void main()   
  170. {  
  171.         port_mode();            // 所有IO口設(shè)為準(zhǔn)雙向弱上拉方式。
  172.         UART_init();        // 波特率:9600/22.1184MHz
  173.         Data_Swap();        // 數(shù)據(jù)交換
  174.          set_time(time);     // 設(shè)定初始時(shí)間值 ,數(shù)組名就代表數(shù)組首地址
  175.         while(1)
  176.         {        
  177.                 read_time(time);          // 秒分時(shí)日月周年        
  178.                 UART_Send_PC(time);                  
  179.                 delay_1S();
  180.         }
  181. }
復(fù)制代碼


第17章 DS1302時(shí)鐘芯片.rar

174.04 KB, 下載次數(shù): 84, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:441232 發(fā)表于 2018-12-6 20:51 | 只看該作者
感謝 辛苦了找了很久
回復(fù)

使用道具 舉報(bào)

板凳
ID:421232 發(fā)表于 2018-12-12 19:41 | 只看該作者
謝謝分享·
回復(fù)

使用道具 舉報(bào)

地板
ID:288930 發(fā)表于 2019-1-18 13:57 | 只看該作者
謝謝分享!
回復(fù)

使用道具 舉報(bào)

5#
ID:315083 發(fā)表于 2019-5-28 17:22 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表