51單片機輕松入門—基于STC15W4K系列(C語言版)
李友全 編著 詳見:http://www.zg4o1577.cn/bbs/dpj-37954-1.html
第17章 DS1302時鐘芯片 1 電路圖 2 程序移植
0.png (56.07 KB, 下載次數: 116)
下載附件
2016-3-28 22:51 上傳
1.png (164.05 KB, 下載次數: 141)
下載附件
2016-3-28 22:51 上傳
使用單片機的定時器可以實現時鐘功能, 但程序較為復雜,單片機斷電后重新上電 時間需要重新設置,為了降低程序的復雜程度,解決斷電后重新上電的時間設置 問題,我們需要使用專用的時鐘芯片DS1302 1 電 路 圖 配套實驗板1號單片機與時鐘芯片DS1302連接電路如圖所示。
2.png (172.39 KB, 下載次數: 124)
下載附件
2016-3-28 22:51 上傳
4
為了簡化實驗,電路中使用了100uF的電容代替電池,當 單片機系統斷電后由電容維持DS1302的供電(3分鐘左右)。 當作為長期使用的時鐘時,應更換為3V的紐扣電池。
3.png (44.89 KB, 下載次數: 114)
下載附件
2016-3-28 22:51 上傳
例17.1 讀取DS1302運行過程中的年、月、日、時、分、秒數據并發送到計算機串口助手顯 示,單片機時鐘頻率22.1184MHz,波特率9600。串口助手接收區選擇“字符格式顯示”。
sbit SCK = P2^7; // 時鐘 sbit SDA = P4^5; // 數據 sbit RST = P4^6; // DS1302復位(片選) unsigned char StartTime[7]= {14,11,30,23,50,59,7}; // 設定初始時間值 // 年、月、日、時、分、秒、星期* ,14-11-30 23:50:59 星期7 void main() { port_mode(); // 所有IO口設為準雙向弱上拉方式。 UART_init(); // 波特率:9600/22.1184MHz Data_Swap(); // 數據交換 set_time(time); // 設定初始時間值 , 只設定1次,設定完成后應屏蔽本行 while(1) { read_time(time); // 秒分時日月周年 UART_Send_PC(time); delay_1S(); } }
0.png (183.88 KB, 下載次數: 120)
下載附件
2016-3-28 22:52 上傳
部分程序預覽(完整代碼請下載附件)
- /****************《51單片機輕松入門-基于STC15W4K系列》配套例程 *************
- ★★★★★★★★★★★★★★★★★★★★★★★★
- 《51單片機輕松入門-基于STC15W4K系列》 一書已經由北航出版社正式出版發行。
- 作者親手創作的與教材配套的51雙核實驗板(2個MCU)對程序下載、調試、仿真方便,不需要外部
- 仿真器與編程器,這種設計方式徹底解決了系統中多個最高優先級誰也不能讓誰的中斷競爭問題。
- QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
- 驗證信息:STC15單片機
- 郵箱:xgliyouquan@126.com
- ★★★★★★★★★★★★★★★★★★★★★★★★*/
- #include "STC15W4K.H"
- #include "uart_debug.H"
- #include <intrins.h>
- sbit SCK = P2^7; // 時鐘
- sbit SDA = P4^5; // 數據
- sbit RST = P4^6; // DS1302復位(片選)
- #define DS1302_W_ADDR 0x80 // 寫起始地址
- #define DS1302_R_ADDR 0x81 // 讀起始地址
- unsigned char StartTime[7]= {14,11,30,23,50,59,7}; // 年月日時分秒周 14-11-30 23:50:59
- unsigned char time[8]; // 秒分時日月周年
- void Data_Swap() // 數據交換
- {
- time[0]=StartTime[5]; // 秒
- time[1]=StartTime[4]; // 分
- time[2]=StartTime[3]; // 時
- time[3]=StartTime[2]; // 日
- time[4]=StartTime[1]; // 月
- time[5]=StartTime[6]; // 周
- time[6]=StartTime[0]; // 年
- time[7]=0; // 最后一字節寫保護為0可寫入數據
- }
- // 寫字節,低位在前,高位在后
- void write_ds1302_byte(unsigned char dat)
- {
- unsigned char i;
- for (i=0;i<8;i++)
- {
- SDA = dat & 0x01; // bit型變量取值范圍是0和1,賦值非0結果為1
- SCK = 1; // 放入數據到時鐘上升沿時間 50nS
- dat >>= 1; // 時鐘上升沿后數據保持時間 70nS
- SCK = 0; // 時鐘低電平時間與時鐘高電平時間250nS
- }
- }
- // 清除寫保護
- void clear_ds1302_WP(void)
- {
- RST = 0; // RST引腳既是CE引腳
- SCK = 0;
- RST = 1;
- write_ds1302_byte(0x8E);
- write_ds1302_byte(0);
- SDA = 0;
- RST = 0;
- }
- // 設置寫保護
- void set_ds1302_WP(void)
- {
- RST = 0; // RST引腳既是CE引腳
- SCK = 0;
- RST = 1;
- write_ds1302_byte(0x8E);
- write_ds1302_byte(0x80);
- SDA = 0;
- RST = 0;
- }
- // 連續寫入8個寄存器數據,dat-待寫入數據指針
- void write_ds1302_nbyte(unsigned char *dat)
- {
- unsigned char i;
- RST=0;
- SCK=0;
- RST = 1;
- write_ds1302_byte(0xBE); // 發送突發寫寄存器指令
- for (i=0; i<8; i++) // 連續寫入8字節數據
- {
- write_ds1302_byte(dat[i]);
- }
- RST = 0;
- }
- // 設定時鐘數據
- void set_time(unsigned char *timedata)
- {
- unsigned char i, tmp;
- for (i=0; i<7; i++) // 轉化為壓縮BCD格式(一個字節存放2個BCD碼)
- {
- tmp = timedata[i] / 10; // 獲取高位BCD碼
- timedata[i] = timedata[i] % 10; // 獲取低位BCD碼
- timedata[i] = timedata[i] + tmp*16; // 合并成壓縮BCD碼
- }
- clear_ds1302_WP(); // 清除寫保護
- write_ds1302_nbyte(timedata); // 連續寫入8字節數據
- set_ds1302_WP(); // 寫保護
- }
- // 讀字節,低位在前,高位在后
- unsigned char read_ds1302_byte(void)
- {
- unsigned char i, dat=0;
- for (i=0;i<8;i++)
- {
- dat >>= 1;
- if (SDA) dat |= 0x80;
- SCK = 1;
- SCK = 0;
- }
- return dat;
- }
- // 連續讀取8個寄存器的數據,dat-讀取數據的接收指針
- void read_time(unsigned char *dat)
- {
- unsigned char i;
- RST=0;
- SCK=0;
- RST = 1;
- write_ds1302_byte(0xBF); //發送突發讀寄存器指令
- for (i=0; i<8; i++) //連續讀取8個字節
- {
- dat[i] = read_ds1302_byte();
- }
- RST = 0;
- }
-
- void delay_1S(void)
- {
- unsigned char i,j,k;
- for(i=85;i>0;i--) // 注意后面沒分號
- for(j=254;j>0;j--) // 注意后面沒分號
- for(k=255;k>0;k--); // 注意后面有分號
- }
- // 單字節壓縮BCD碼轉換成ASCII碼另一常見格式示例,dat/16 + 0x30,
- // dat/16本質就是右移4位,數字0--9加上0x30即得數字0--9的ASCII碼
- void UART_Send_PC(unsigned char *tmp)
- {
- unsigned char str[12]; // 字符串轉換緩沖區
- str[0] = '2'; // 添加年份的高2位:20
- str[1] = '0';
- str[2] = (tmp[6] >> 4) + '0'; //“年”高位數字轉換為ASCII碼
- str[3] = (tmp[6]&0x0F) + '0'; //“年”低位數字轉換為ASCII碼
- str[4] = '-'; //添加日期分隔符
- str[5] = (tmp[4] >> 4) + '0'; //“月”
- str[6] = (tmp[4]&0x0F) + '0';
- str[7] = '-';
- str[8] = (tmp[3] >> 4) + '0'; //“日”
- str[9] = (tmp[3]&0x0F) + '0';
- str[10] = '\0'; // 字符串結束符
- UART_Send_Str(str); // 輸出 年、月、日
- UART_Send_Str(" ");
-
- str[0] = (tmp[2] >> 4) + '0'; //“時”
- str[1] = (tmp[2]&0x0F) + '0';
- str[2] = ':'; //添加時間分隔符
- str[3] = (tmp[1] >> 4) + '0'; //“分”
- str[4] = (tmp[1]&0x0F) + '0';
- str[5] = ':';
- str[6] = (tmp[0] >> 4) + '0'; //“秒”
- str[7] = (tmp[0]&0x0F) + '0';
- str[8] = '\0';
- UART_Send_Str(str); // 輸出 時、分、秒
- UART_Send_Str(" ");
-
- UART_Send_Str("week = ");
- str[0] = (tmp[5]&0x0F) + '0'; //“星期”
- str[1] = '\0';
- UART_Send_Str(str); // 輸出 星期
- UART_Send_Str(" ");
- }
- void port_mode() // 端口模式
- {
- P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
- P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
- }
- void main()
- {
- port_mode(); // 所有IO口設為準雙向弱上拉方式。
- UART_init(); // 波特率:9600/22.1184MHz
- Data_Swap(); // 數據交換
- set_time(time); // 設定初始時間值 ,數組名就代表數組首地址
- while(1)
- {
- read_time(time); // 秒分時日月周年
- UART_Send_PC(time);
- delay_1S();
- }
- }
復制代碼
|