RTC_GM1302
RTC_GM1302
/* * @Description : LVGL * @Author : wangxy * @Date : 2022-04-14 * @LastEditTime: Today * @LastEditors : wangxy * @FilePath : ESP32/rtc.c * **/ #include "ESP32_Lvgl.h" #define RTC_CLK 22 //39-GPIO22 #define RTC_SIO 21 //42-GPIO21 #define RTC_RST 25 //14-GPIO25 #define RTC_CLK_OUT pinMode(RTC_CLK,OUTPUT); #define RTC_CLK_SET digitalWrite(RTC_CLK,1); #define RTC_CLK_RESET digitalWrite(RTC_CLK,0); #define RTC_SIO_IN pinMode(RTC_SIO, INPUT); #define RTC_SIO_OUT pinMode(RTC_SIO,OUTPUT); #define RTC_SIO_SET digitalWrite(RTC_SIO,1); #define RTC_SIO_RESET digitalWrite(RTC_SIO,0); #define RTC_SIO_READ digitalRead(RTC_SIO); #define RTC_RST_OUT pinMode(RTC_RST,OUTPUT); #define RTC_RST_SET digitalWrite(RTC_RST,1); #define RTC_RST_RESET digitalWrite(RTC_RST,0); //unsigned char twdata[8]={0x58,0x59,0x23,0x31,0x12,0x06,0x04,0x80};/*定义初始化时钟数据数组,前7个为时钟数据,第8个为控制寄存器数据*/ unsigned char twdata[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80}; unsigned char trdata[7]; /*定义 1302 时钟数据数组,用来存放读出的时钟数据(BCD 码) */ unsigned char asc[14]; /*定义 ASC 码转换数组,用来存放时钟数据(BCD)转换过来的 ASC 码 */ void gm1302_rtc_init(void) { RTC_CLK_OUT RTC_SIO_OUT RTC_RST_OUT } /******************************************************************** 函 数 名:RTInputByte() 功 能:实时时钟写入一字节 说 明:往 GM1302 写入 1Byte 数据 (内部函数) 入口参数:d 写入的数据 返 回 值:无 ***********************************************************************/ void RT_write_Byte(uchar ACC) //低位先发 { RTC_SIO_OUT //Serial.printf("\nbegin_\n"); for(uchar i=8; i>0; i--) { if(ACC&0x01){ RTC_SIO_SET //Serial.printf("1 "); }else{ RTC_SIO_RESET //Serial.printf("0 "); } RTC_CLK_SET RTC_CLK_RESET ACC = ACC >> 1; } //Serial.printf("\nend_\n"); } /******************************************************************** 函 数 名:RTOutputByte() 功 能:实时时钟读取一字节 说 明:从 GM1302 读取 1Byte 数据 (内部函数) 入口参数:无 返 回 值:ACC ***********************************************************************/ uchar RT_read_Byte(void) //低位先接收 { uchar ACC; RTC_SIO_IN for(uchar i=8; i>0; i--) { ACC = ACC >>1; int p =RTC_SIO_READ if(p){ ACC =ACC|0x80; }else{ //no } RTC_CLK_SET RTC_CLK_RESET } return(ACC); } /******************************************************************** 函 数 名:W1302() 功 能:往 GM1302 写入数据 说 明:先写地址,后写命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: GM1302 地址, ucData: 要写的数据 返 回 值:无 ***********************************************************************/ void W1302(uchar ucAddr, uchar ucDa) { RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(ucAddr); /* 地址,命令 */ RT_write_Byte(ucDa); /* 写 1Byte 数据*/ RTC_CLK_SET RTC_RST_RESET } /******************************************************************** 函 数 名:R1302() 功 能:读取 GM1302 某地址的数据 说 明:先写地址,后读命令/数据 (内部函数) 调 用:RTInputByte() , RTOutputByte() 入口参数:ucAddr: GM1302 地址 返 回 值:ucData :读取的数据 ***********************************************************************/ uchar R1302(uchar ucAddr) { uchar ucData; RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(ucAddr); /* 地址,命令 */ ucData = RT_read_Byte(); /* 读 1Byte 数据 */ RTC_CLK_SET RTC_RST_RESET return(ucData); } /******************************************************************** 函 数 名:BurstW1302T() 功 能:往 GM1302 写入时钟数据(多字节方式) 说 明:先写地址,后写命令/数据 调 用:RTInputByte() 入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制 8Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 1B 返 回 值:无 ***********************************************************************/ void BurstW1302T(uchar *pWClock) { W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(0xbe); /* 0xbe:时钟多字节写命令 */ for (uchar i = 8; i>0; i--){ /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/ RT_write_Byte(*pWClock); /* 写 1Byte 数据*/ pWClock++; } RTC_CLK_SET RTC_RST_RESET } /******************************************************************** 函 数 名:BurstR1302T() 功 能:读取 GM1302 时钟数据 说 明:先写地址/命令,后读数据(时钟多字节方式) 调 用:RTInputByte() , RTOutputByte() 入口参数:pRClock: 读取时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 返 回 值:无 ***********************************************************************/ void BurstR1302T(uchar *pRClock) { RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(0xbf); /* 0xbf:时钟多字节读命令 */ for (uchar i=8; i>0; i--) { *pRClock = RT_read_Byte(); /* 读 1Byte 数据 */ pRClock++; } RTC_CLK_SET RTC_RST_RESET } /******************************************************************** 函 数 名:BurstW1302R() 功 能:往 GM1302 寄存器数写入数据(多字节方式) 说 明:先写地址,后写数据(寄存器多字节方式) 调 用:RTInputByte() 入口参数:pWReg: 寄存器数据地址 返 回 值:无 ***********************************************************************/ void BurstW1302R(uchar *pWReg) { W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/ RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(0xfe); /* 0xbe:时钟多字节写命令 */ for (uchar i=31; i>0; i--){ /* 31Byte 寄存器数据 */ RT_write_Byte(*pWReg); /* 写 1Byte 数据*/ pWReg++; } RTC_CLK_SET RTC_RST_RESET } /******************************************************************** 函 数 名:BurstR1302R() 功 能:读取 GM1302 寄存器数据 说 明:先写地址,后读命令/数据(寄存器多字节方式) 调 用:RTInputByte() , RTOutputByte() 入口参数:pRReg: 寄存器数据地址 返 回 值:无 ***********************************************************************/ void BurstR1302R(uchar *pRReg) { RTC_RST_RESET RTC_CLK_RESET RTC_RST_SET RT_write_Byte(0xff); /* 0xff:时钟多字节读命令 */ for (uchar i=31; i>0; i--){ /*31Byte 寄存器数据 */ *pRReg = RT_read_Byte(); /* 读 1Byte 数据 */ pRReg++; } RTC_CLK_SET RTC_RST_RESET } /******************************************************************** 函 数 名:Set1302() 功 能:设置初始时间,以单字节方式连续设置 GM1302 的 7 个时钟寄存器 说 明:先写地址,后写数据(单字节方式) 调 用:W1302() 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 返 回 值:无 ***********************************************************************/ void Set1302(uchar *pClock) { uchar ucAddr = 0x80; //W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ for(uchar i =7; i>0; i--) { W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ pClock++; ucAddr +=2; } W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ } /******************************************************************** 函 数 名:Get1302() 功 能:单字节方式读取 GM1302 当前时间(7 个时钟数据) 说 明: 调 用:R1302() 入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 返 回 值:无 ***********************************************************************/ void Get1302(uchar ucCurtime[]) { uchar ucAddr = 0x81; for (uchar i=0; i<7; i++) { ucCurtime[i] = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */ ucAddr += 2; } } /******************************************************************** 函 数 名:Bcd2asc( ) 功 能:将读取的 GM1302 时钟数据(压缩型 bcd 码)转换成 asc 码存储在 asc 数组中 说 明: 调 用: 入口参数: 返 回 值:无 ***********************************************************************/ void Bcd2asc(void) { uchar i,j; for (j=0,i=0; i<7; i++){ asc[j++] =(trdata[i]&0xf0)>>4|0x30 ;/*格式为: 秒 分 时 日 月 星期 年 */ asc[j++] =trdata[i]&0x0f|0x30; } Serial.printf("read time = %s\r\n",asc); } #if 0 /******************************************************************** 函 数 名:main( ) 功 能:先设置 GM1302 的时间,然后循环读取 GM1302 的时钟数据并保存, 将读取的时钟数据转换成 asc 码保存 说 明:该主函数很简单,用户可以根据需要来选择多字节方式或者单字节方式 调 用: 入口参数: 返 回 值:无 ***********************************************************************/ void main(void) { BurstW1302T(twdata); /* 多字节方式设置 GM1302 时间 */ //Set1302(twdata); /* 单字节方式设置 GM1302 时间 */ while(1) { BurstR1302T(trdata); /* 多字节方式读取 GM1302 时间*/ //Get1302(trdata); /* 单字节方式读取 GM1302 时间*/ Bcd2asc(); /* 时钟数据转换成 asc 码*/ } } #endif unsigned char hex_to_bcd(unsigned char hex) { if (hex > 99) return 0; return ((hex / 10) << 4) +hex % 10; }
Stay hungry, stay foolish
待续。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)