|
- /*
- 单片机型号:STC15F104E 晶振频率:11.0592Mhz 波特率:9600
- */
- #include "stc15f104e.h"
- #include "intrins.h"
- #define is_leap_year(year) ((year) %4 == 0 && (year) %100 !=0 || (year) %400 ==0) //闰年判断
- #define U8 unsigned char
- #define U16 unsigned int
- #define U32 unsigned long
- sbit DS1302_SCLK = P3 ^ 2; //时钟口
- sbit DS1302_IO = P3 ^ 3; //数据口
- sbit DS1302_RST = P3 ^ 4; //片选口
- sbit KEY=P3^5; //低电平设置指定时间
- sbit txd = P3 ^ 1;
- void delay_uart() { //11.0592Mhz 延时1/9600秒
- unsigned char a,b;
- for(b=114;b>0;b--)
- for(a=1;a>0;a--);
- }
- void delay1s(){
- unsigned char a,b,c;
- for(c=217;c>0;c--)
- for(b=171;b>0;b--)
- for(a=73;a>0;a--);
- }
- void TXD_Byte(U8 Byte) { //串口发送1字节
- U8 j = 1;
- delay_uart();
- txd = 0;
- do {
- delay_uart();
- txd = Byte & j;
- j <<= 1;
- } while (j);
- delay_uart();
- txd = 1;
- }
- void TXD_Text(U8* text) { //串口发送字符串
- for (; *text; text++) {
- TXD_Byte(*text);
- }
- }
- U8 code MonthTable[2][12] = {
- {31,28,31,30,31,30,31,31,30,31,30,31}, //平年月数表
- {31,29,31,30,31,30,31,31,30,31,30,31}, //闰年月数表
- };
- U32 code WeekText[7] = { //星期字符串数组
- 0x53554E20, //SUN 周日
- 0x4D4F4E20, //MON 周一
- 0x54554520, //TUE 周二
- 0x57454420, //WED 周三
- 0x54485520, //THU 周四
- 0x46524920, //FRI 周五
- 0x53415420, //SAT 周六
- };
- U8 dec2bcd(U8 D) { //将10进制的19转化成16进制的0x19
- return ((D / 10) << 4) + (D % 10);
- }
- U8 bcd2dec(U8 H) { //将16进制的0x19转化成10进制的19
- return (H >> 4) * 10 + (H & 15);
- }
- union ds1302_now{ //10进制 DS1302时间 (24小时制)
- struct {
- U8 sec; //秒 0~59
- U8 min; //分钟 0~59
- U8 hour; //小时 0~23
- U8 day; //日 1~31
- U8 month; //月 1~12
- U8 week; //星期 1~7 (星期日为1 星期一为2)
- U8 year; //年 0~99
- } now;
- U8 dat[7];
- };
- union time_text { //字符串时间 YYYY-MM-DD WWW HH:II:SS (24小时制)
- struct {
- U8 year[4]; //年4位 前2位固定20
- U8 sub1; //减号 固定0x2D
- U8 month[2]; //月2位
- U8 sub2; //减号 固定0x2D
- U8 day[2]; //日 2位
- U8 bla1; //空格 固定0x20
- U32 week; //星期代码 4位 SUN MON TUE WED THU FRI SAT (最后1位空格)
- U8 hour[2]; //小时2位
- U8 col1; //冒号 固定0x3A
- U8 min[2]; //分钟 2位
- U8 col2; //冒号 固定0x3A
- U8 sec[2]; //秒 2位
- U8 null; //字符串结束符(空字符) 固定0x00
- } str;
- U8 dat[24];
- };
- U8 *now2text(U8 *ds1302_now) { //DS1302时间转字符串
- union ds1302_now *now= ds1302_now;
- static union time_text text;
- if (now->now.week >= 1 && now->now.week <= 7) {
- text.str.week = WeekText[now->now.week - 1];
- }
- else {
- text.str.week = 0x45525220;
- }
- text.str.year[0] = 0x32;
- text.str.year[1] = 0x30;
- text.str.sub1 = 0x2D;
- text.str.sub2 = 0x2D;
- text.str.col1 = 0x3A;
- text.str.col2 = 0x3A;
- text.str.bla1 = 0x20;
- text.str.null = 0x00;
- text.str.year[2] = (now->now.year / 10 % 10) | 0x30;
- text.str.year[3] = (now->now.year % 10) | 0x30;
- text.str.month[0] = (now->now.month / 10 % 10) | 0x30;
- text.str.month[1] = (now->now.month % 10) | 0x30;
- text.str.day[0] = (now->now.day / 10 % 10) | 0x30;
- text.str.day[1] = (now->now.day % 10) | 0x30;
- text.str.hour[0] = (now->now.hour / 10 % 10) | 0x30;
- text.str.hour[1] = (now->now.hour % 10) | 0x30;
- text.str.min[0] = (now->now.min / 10 % 10) | 0x30;
- text.str.min[1] = (now->now.min % 10) | 0x30;
- text.str.sec[0] = (now->now.sec / 10 % 10) | 0x30;
- text.str.sec[1] = (now->now.sec % 10) | 0x30;
- return text.dat;
- }
- void DS1302_Delay() { //延时X微秒 (STC-Y3&12M)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- U8 DS1302_RXD() { //DS1302读1字节
- U8 i = 1, dat = 0;
- do {
- DS1302_SCLK = 0;
- DS1302_Delay();
- if(DS1302_IO) dat |= i;
- DS1302_SCLK = 1;
- DS1302_Delay();
- i <<= 1;
- } while (i);
- return dat;
- }
- void DS1302_TXD(U8 dat) { //DS1302写1字节
- U8 i = 1;
- do {
- DS1302_SCLK = 0;
- DS1302_Delay();
- DS1302_IO = dat & i;
- DS1302_SCLK = 1;
- DS1302_Delay();
- i <<= 1;
- } while (i);
- }
- U8 DS1302_Read(U8 addr) { //DS1302读地址
- U8 dat;
- DS1302_RST = 0;
- DS1302_Delay();
- DS1302_SCLK = 0;
- DS1302_Delay();
- DS1302_RST = 1;
- DS1302_Delay();
- DS1302_TXD(addr);
- dat = DS1302_RXD();
- DS1302_SCLK = 1;
- DS1302_RST = 0;
- return dat;
- }
- void DS1302_Write(U8 addr,U8 dat) { //DS1302写地址
- DS1302_RST = 0;
- DS1302_Delay();
- DS1302_SCLK = 0;
- DS1302_Delay();
- DS1302_RST = 1;
- DS1302_Delay();
- DS1302_TXD(addr);
- DS1302_TXD(dat);
- DS1302_SCLK = 1;
- DS1302_RST = 0;
- }
- void DS1302(U8 *p) { //DS1302读时间 (自动转换BCD码)
- U8 addr = 0x81,n = 7;
- while(n--) {
- *p++ = bcd2dec(DS1302_Read(addr));
- addr += 2;
- }
- }
- void DS1302_Set(U8 *p) { //DS1302设置时间 (自动转换BCD码)
- U8 addr = 0x80, n = 7;
- DS1302_Write(0x8e, 0x00); //关写保护
- while (n--) {
- DS1302_Write(addr, dec2bcd(*p++));
- addr += 2;
- }
- DS1302_Write(0x8e, 0x80); //开写保护
- }
- void DS1302_Init() { //DS1302初始化
- DS1302_RST = 0;
- DS1302_SCLK = 0;
- DS1302_Write(0x8e, 0x00); //允许写操作
- DS1302_Write(0x90, 0xa6); //一个二极管+4K电阻充电
- DS1302_Write(0x8e, 0x80); //写保护
- }
-
- bit DS1302_now_check(U8* ds1302_now) { //DS1302时间合法校验
- union ds1302_now* now = ds1302_now;
- if (now->now.year > 99) {
- return 0;
- }else if (now->now.month > 12) {
- return 0;
- }else if (now->now.day > MonthTable[is_leap_year(2000+now->now.year)][now->now.month-1]) {
- return 0;
- }else if (now->now.hour > 23) {
- return 0;
- }else if (now->now.min > 59) {
- return 0;
- }else if (now->now.sec > 59) {
- return 0;
- }
- return 1;
- }
- void main(){
- union ds1302_now now;
- P3 = 0xFF;
- DS1302_Init();
- if(!KEY){ //2020年7月27日星期一 16时10分0秒 (修改成当前日期时间)
- now.now.year=20;
- now.now.month=7;
- now.now.day=27;
- now.now.hour=16;
- now.now.min=10;
- now.now.sec=0;
- now.now.week=2;
- DS1302_Set(&now.dat);
- }
- while (1){
- WDT_CONTR = 0x37;
- delay1s();
- DS1302(&now.dat);
- if (DS1302_now_check(&now.dat)) {
- TXD_Text(now2text(now.dat));
- }
- else {
- TXD_Text("DS1302 Time Error!");
- }
- TXD_Text("\r\n");
- }
- }
复制代码 |
|