📄 rtc-ds1302.c
字号:
#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include <time.h>#include "../include/ped.h"//#include "../include/rtc.h"//#define RTC_DATA *(unsigned char *)0xfffff439 &= 0x02; static unsigned char convert_bcd(unsigned char ch){ if (((ch & 0x0f) > 9) || (((ch>>4)&0x0f) > 9)) return 0xff; return ((ch>>4)&0x0f)*10 + (ch&0x0f);} void set_clk_high(){ *(unsigned char *)0xfffff43b |= 0x04; *(unsigned char *)0xfffff438 |= 0x04; *(unsigned char *)0xfffff439 |= 0x04; //*(unsigned char *)0xfffff43b &= 0xfb; }void set_clk_low(){ *(unsigned char *)0xfffff43b |= 0x04; *(unsigned char *)0xfffff438 |= 0x04; *(unsigned char *)0xfffff439 &= 0xfb; //*(unsigned char *)0xfffff43b &= 0xfb;}void set_rst_high(){ *(unsigned char *)0xfffff43b |= 0x01; *(unsigned char *)0xfffff438 |= 0x01; *(unsigned char *)0xfffff439 |= 0x01; //*(unsigned char *)0xfffff43b &= 0xfe; }void set_rst_low(){ *(unsigned char *)0xfffff43b |= 0x01; *(unsigned char *)0xfffff438 |= 0x01; *(unsigned char *)0xfffff439 &= 0xfe; //*(unsigned char *)0xfffff43b &= 0xfe;}void set_datout_high(){ *(unsigned char *)0xfffff413 |= 0x02; *(unsigned char *)0xfffff410 |= 0x02; *(unsigned char *)0xfffff411 |= 0x02; //*(unsigned char *)0xfffff43b &= 0xfd; }void set_datout_low(){ *(unsigned char *)0xfffff413 |= 0x02; *(unsigned char *)0xfffff410 |= 0x02; *(unsigned char *)0xfffff411 &= 0xfd; //*(unsigned char *)0xfffff43b &= 0xfd;}unsigned char DS1302_Read_Byte() { unsigned char temp,rbyte=0,A; //set PJ1 I/O function,Input *(unsigned char *)0xfffff413 |= 0x02; *(unsigned char *)0xfffff410 &= 0xfd; for(temp=8;temp > 0;temp--) { rbyte=rbyte>>1; A = *(unsigned char *)0xfffff411; if(A &= 0x02) { rbyte=rbyte | 0x80; } else { rbyte=rbyte & 0x7f; } set_clk_high(); set_clk_low(); } return(rbyte);}//20050110发现没有任何延迟都没有问题void DS1302_Write_Byte(unsigned char input){ unsigned char temp; set_clk_low(); //set_rst_low(); //set_rst_high(); //set PJ1 I/O function,Outout //*(unsigned char *)0xfffff43b |= 0x02; //*(unsigned char *)0xfffff438 |= 0x02;// Write data valade at clock rising edge //set_clk_low(); for(temp=8;temp > 0;temp--) { if(input & 0x01) { set_datout_high(); } else { set_datout_low(); } //DelayMs(5); set_clk_high(); set_clk_low(); input= input >> 1; }}//写DS1302时钟的有关数据void DS1302_Write(unsigned char add,unsigned char d){ set_clk_low(); set_rst_low(); set_rst_high(); DS1302_Write_Byte(add); DS1302_Write_Byte(d); set_rst_low(); *(unsigned char *)0xfffff43b &= 0xf8;}//读DS1302时钟的有关数据unsigned char DS1302_Read(unsigned char add){ unsigned char a; set_rst_low(); set_clk_low(); set_rst_high(); DS1302_Write_Byte(add); a=DS1302_Read_Byte(); set_rst_low(); *(unsigned char *)0xfffff43b &= 0xf8; return a;}void DS1302_START(void){ set_rst_low(); set_clk_low(); set_rst_high(); DS1302_Write_Byte(0x80); DS1302_Write_Byte(0x00); set_rst_low();}///////////////////////////////////////////////////////////////////////////////////// 原型: void DS1302_Rtime(unsigned char *a)// 功能: 用单字节方式读DS1302时钟的所有数据,内部的无限制// 包括CONTROL 位和CHG位// 输入: *a 接收数据的地址// 输出: 9位数据,包括CONTROL 和CHG///////////////////////////////////////////////////////////////////////////////////void DS1302_Rtime(unsigned char *a){//秒-0 *(a+5)=DS1302_Read(0x81);//分-1 *(a+4)=DS1302_Read(0x83); //时-2 *(a+3)=DS1302_Read(0x85); //日-3 *(a+2)=DS1302_Read(0x87); //月-4 *(a+1)=DS1302_Read(0x89); //年-6 *a=DS1302_Read(0x8d); //星期-5 // *(a+6)=DS1302_Read(0x8b); //CONTROL-7 // *(a+7)=DS1302_Read(0x8f); //充电-8 //*(a+8)=DS1302_Read(0x91); }///////////////////////////////////////////////////////////////////////////////////// 原型: void DS1302_Wtime(unsigned char *a)// 功能: 用单字节方式写DS1302时钟的所有数据,内部的无限制// 包括CONTROL 位和CHG位// 输入: *a 接收数据的地址/////////////////////////////////////////////////////////////////////////////////////set YY MM DD HH MI SE WEvoid DS1302_Wtime(unsigned char *a){//秒-0 DS1302_Write(0x80,*a);//分-1 DS1302_Write(0x82,*(a+1)); //时-2 DS1302_Write(0x84,*(a+2)); //日-3 DS1302_Write(0x86,*(a+3)); //月-4 DS1302_Write(0x88,*(a+4)); //年-6 DS1302_Write(0x8C,*(a+5)); //星期-5 DS1302_Write(0x8A,*(a+6)); //CONTROL-7 // DS1302_Write(0x8E,*(a+7)); //充电-8 // DS1302_Write(0x90,*(a+8)); }/******************************************************************** 设置系统日期和时间unsigned char SetTime(unsigned char *TimeBuf);功能: 设置系统日期和时间输入: TimeBuf:日期时间参数的指针,格式为YYMMDDhhmmss,参数为BCD码,共6个字节长返回: 0-Success 1-参数中年份非法 2-参数中月份非法 3-参数中日份非法 4-参数中小时份非法 5-参数中分钟非法 6-参数中秒钟非法 0xff-参数中有非数字项。********************************************************************/int SetTime(unsigned char *TimeBuf){ unsigned char TmpBuf[7]; unsigned char str[20]; unsigned char cDaysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31}; unsigned char wYear; unsigned char bMon, bDay; unsigned long i,dwDays; struct tm tp; time_t t; memcpy(str, TimeBuf, 7); //file://YXF 2001/06/05 //Year--up to 2100 if(((str[0]&0xf0)> 0x20)||((str[0]&0x0f)>9)) return 1; //file://Tong 2001/02/21 for(i=1; i<6; i++) { if (((str[i] & 0xf0) > 0x90) || ((str[i] & 0x0f) > 9)) return 0xff; } wYear = (str[0]>>4)*10 + (str[0]&0x0f); bMon = (str[1]>>4)*10 + (str[1]&0x0f); bDay = (str[2]>>4)*10 + (str[2]&0x0f); if(wYear >= 50) wYear += 1900; else wYear += 2000; if ((bMon <= 0) || (bMon > 12)) return 2; if ((bDay <= 0) || (bDay > cDaysInMonth[bMon-1])) { if (bMon != 2) return 3; if ( (wYear%400==0) || ((wYear%4==0)&&(wYear%100!=0)) ) { // Leap year if ((bDay > 29)||(bDay<=0)) { return 3; // large than 29 or equals to 0 } } else { return 3; // Not leap year large than 28 } } if (str[3] >= 0x24) return 4; if (str[4] >= 0x60) return 5; if (str[5] >= 0x60) return 6; dwDays = 0; for (i=1950; i<wYear; i++) { dwDays += 365; if ( (i%400==0) || ((i%4==0)&&(i%100!=0)) ) dwDays ++; } for(i=1; i<bMon; i++) dwDays += cDaysInMonth[i-1]; dwDays += bDay; if (bMon > 2) { if ( (wYear%400==0) || ((wYear%4==0)&&(wYear%100!=0)) ) dwDays ++; } if (str[5] == 0x59) str[5] = 0x58; str[6] = (unsigned char)((dwDays-1)%7); if (str[6] == 0) { str[6] = 7; } tp.tm_year = str[0]+100; tp.tm_mon = str[1]-1; tp.tm_mday = str[2]; tp.tm_hour = str[3]; tp.tm_min = str[4]; tp.tm_sec = str[5]; tp.tm_isdst = 0; t = mktime(&tp); if (t == (time_t)(-1)) return -1; if (stime(&t) == -1) return -1; TmpBuf[0]=str[5]; //second TmpBuf[1]=str[4]; //minute TmpBuf[2]=str[3]; //hour TmpBuf[3]=str[2]; //day TmpBuf[4]=str[1]; //month //TmpBuf[5]=str[6]; //week TmpBuf[5]=str[0]; //year DS1302_Wtime(TmpBuf); return 0;}void GetTime(unsigned char *str){ struct tm *tp; time_t t; int i; time(&t); tp = localtime(&t); i = tp->tm_year-100; str[0] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_mon+1; str[1] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_mday; str[2] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_hour; str[3] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_min; str[4] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_sec; str[5] = (((i/10)<<4) & 0xf0) | (i % 10); i = tp->tm_wday; if (i == 0) i = 7; str[6] = (((i/10)<<4) & 0xf0) | (i % 10);}/******************************************************************** 读取实时时钟当前日期和时间void GetRTCTime(unsigned char *str)功能: 读取实时时钟当前日期和时间输入: str:7字节时钟数据地址(秒、分、时、日、月、年)返回: None********************************************************************/void GetRTCTime(unsigned char *str){ unsigned char i;/* for(i=0; i<7; i++) { str1[i] = DS1302_Read(0x81+i+i); str[i] = (str1[i] >> 4)*10 + (str1[i] & 0x0f); }*/ DS1302_Rtime(str); //如果读出时间秒的最高位为1,说明时钟已经停止,重新设置。 while(str[0] & 0x80) { str[0] &= 0x7f; DS1302_Wtime(str); DS1302_Rtime(str); }/* for(i=0; i<7; i++) { str[i] = convert_bcd(str[i]); }*/ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -