#define RX8025_ADDR_READ 0x65
#define RX8025_ADDR_WRITE 0x64
// 设备寄存器地址
#define RX8025_ADDR_SECONDS 0x00
#define RX8025_ADDR_WEEK 0x30
#define RX8025_ADDR_DATES 0x40
#define RX8025_ADDR_MONTH 0x50
#define RX8025_ADDR_MINUTES 0x80
#define RX8025_ADDR_CONTROL1 0xE0
#define RX8025_ADDR_CONTROL2 0xF0
uint8_t RX8025_BCD2DEC(uint8_t val){ uint8_t i; i = val&0x0f; //按位与,i得到低四位数。 val >>= 4; //右移四位,将高四位移到低四位的位置,得到高四位码值。 val &= 0x0f; //防止移位时高位补进1,只保留高四位码值 val *= 10; //高位码值乘以10 i += val; //然后与第四位码值相加。 return i; //将得到的十进制数返回} /** * @brief RX8025_DEC2BCD 十进制转BCD码 * @param val BCD码 * @return */uint8_t RX8025_DEC2BCD(uint8_t val){ uint8_t i; i = val/10; //取得十位 val %= 10; //取得个位 i <<= 4; //左移4位 i += val; return i;} void Rx8025_WriteCTFG(void){ uint8_t temp; temp = RX8025_ReadReg(REG_CONTROL2); temp &= 0xFB; //Write CTFG; RX8025_WriteReg(REG_CONTROL2,temp);} /***************************************************** Function Name :* Description : 初始化RX8025* Input :* Return : 返回非0值代表初始化通过* Note :*****************************************************/uint8_t RX8025_Init(void){ uint8_t temp,temp1; RX8025GpioInit(); temp = RX8025_ReadReg(REG_CONTROL1); /******* RX8025上电默认选择12小时制 **********/#if USING_T12_T24==1 //24小时制 RX8025_WriteReg(REG_CONTROL1,temp|REGBIT_12_24);#elif USING_T12_T24==0 //12小时制 RX8025_WriteReg(REG_CONTROL1,temp&(~REGBIT_12_24));#endif /* INTA管脚输出模式 */ temp = RX8025_ReadReg(REG_CONTROL1); temp &= 0xF8; //清空低3位 //temp |= 0x00;//INTA管脚不输出 //temp |= 0x01;//INTA管脚输出固定低电平 //temp |= 0x02;//INTA管脚输出占空比50%、2HZ的脉冲 temp |= 0x03;//INTA管脚输出占空比50%、1HZ的脉冲 //temp |= 0x04;//INTA管脚输出电平模式,1秒1次 //temp |= 0x05;//INTA管脚输出电平模式,1分钟1次 //temp |= 0x06;//INTA管脚输出电平模式,1小时1次 //temp |= 0x07;//INTA管脚输出电平模式,1月1次 RX8025_WriteReg(REG_CONTROL1,temp); temp1 = RX8025_ReadReg(REG_CONTROL1); if(temp == temp1) //读写是否正常 temp1 = 0; else temp1 = 1; /* 低电压检测功能 */ /* 振动停止检测功能 */ temp = RX8025_ReadReg(REG_CONTROL1); RX8025_WriteReg(REG_CONTROL1,temp|REGBIT_XST); //启动低电压检测 /* 电源复位检测功能 */ temp = RX8025_ReadReg(REG_CONTROL1); RX8025_WriteReg(REG_CONTROL1,temp&(~REGBIT_PON)); //清除标志位,为下次做准备 /* INTB管脚输出 */ temp = RX8025_ReadReg(REG_CONTROL2); RX8025_WriteReg(REG_CONTROL2,temp&(~REGBIT_WAFG)); //关闭ALARM_W引起的INTB管脚的输出 temp = RX8025_ReadReg(REG_CONTROL2); RX8025_WriteReg(REG_CONTROL2,temp&(~REGBIT_DAFG)); //关闭ALARM_D引起的INTB管脚的输出 /* 日历计数器 */ temp = RX8025_ReadReg(REG_MONTH); RX8025_WriteReg(REG_MONTH,temp&(~0x80)); //规定:先写零再使用 return temp1;} /* 读取RTC method=0时采用阻塞方式读,method=1时采用状态机+非阻塞方式*/void ReadRTCBlock(struct tm *rtc){ Rx8025RTC.tm_sec = RX8025_BCD2DEC(RX8025_ReadReg(0)&0x7f); Rx8025RTC.tm_min = RX8025_BCD2DEC(RX8025_ReadReg(1)&0x7f); Rx8025RTC.tm_hour = RX8025_BCD2DEC(RX8025_ReadReg(2)&0x7f); //----星期 Rx8025RTC.tm_wday= RX8025_BCD2DEC(RX8025_ReadReg(3)&0x07); //----一个月中的日期 Rx8025RTC.tm_mday = RX8025_BCD2DEC(RX8025_ReadReg(4)&0x3f); Rx8025RTC.tm_mon = RX8025_BCD2DEC(RX8025_ReadReg(5)&0x1f); Rx8025RTC.tm_year = RX8025_BCD2DEC(RX8025_ReadReg(6)&0xff); Rx8025RTC.tm_year += 2000; (*rtc).tm_sec = Rx8025RTC.tm_sec; (*rtc).tm_min = Rx8025RTC.tm_min; (*rtc).tm_hour = Rx8025RTC.tm_hour; //----星期 (*rtc).tm_wday= Rx8025RTC.tm_wday; //----一个月中的日期 (*rtc).tm_mday = Rx8025RTC.tm_mday; (*rtc).tm_mon = Rx8025RTC.tm_mon; (*rtc).tm_year = Rx8025RTC.tm_year;} void ReadRTCNoBlock(struct tm *rtc){ (*rtc).tm_sec = Rx8025RTC.tm_sec; (*rtc).tm_min = Rx8025RTC.tm_min; (*rtc).tm_hour = Rx8025RTC.tm_hour; //----星期 (*rtc).tm_wday= Rx8025RTC.tm_wday; //----一个月中的日期 (*rtc).tm_mday = Rx8025RTC.tm_mday; (*rtc).tm_mon = Rx8025RTC.tm_mon; (*rtc).tm_year = Rx8025RTC.tm_year;} /***************************************************** Function Name :* Description :* Input :* Return :* Note : 采用阻塞方式写,耗时75ms*****************************************************/uint8_t WriteRTCBlock(struct tm rtc){ Rx8025RTC.tm_sec = rtc.tm_sec; Rx8025RTC.tm_min = rtc.tm_min; Rx8025RTC.tm_hour = rtc.tm_hour; //----星期 Rx8025RTC.tm_wday = rtc.tm_wday; //----一个月中的日期 Rx8025RTC.tm_mday = rtc.tm_mday; Rx8025RTC.tm_mon = rtc.tm_mon; Rx8025RTC.tm_year = rtc.tm_year; /* 每次写入耗时0.97ms */ RX8025_WriteReg(0,RX8025_DEC2BCD(Rx8025RTC.tm_sec)); RX8025_WriteReg(1,RX8025_DEC2BCD(Rx8025RTC.tm_min)); RX8025_WriteReg(2,RX8025_DEC2BCD(Rx8025RTC.tm_hour)); RX8025_WriteReg(3,RX8025_DEC2BCD(Rx8025RTC.tm_wday)); RX8025_WriteReg(4,RX8025_DEC2BCD(Rx8025RTC.tm_mday)); RX8025_WriteReg(5,RX8025_DEC2BCD(Rx8025RTC.tm_mon)); RX8025_WriteReg(6,RX8025_DEC2BCD(Rx8025RTC.tm_year-2000)); return 1; } /**************************************功能描述: 发送读取时间命令参数说明:返回说明:调用方式: 1s调用一次全局变量:读写时间:注意事项:日期 :**************************************/void Rx8025ReadRTCTask(void){ rx8025_status = READ_RTC;} /**************************************功能描述: 周期性轮询任务参数说明:返回说明:调用方式: 100ms调用一次全局变量:读写时间:注意事项:日期 :**************************************/void Rx8025Task(void){ static uint8_t step=0; switch(rx8025_status) { case IDLE_RTC: break; case READ_RTC: switch(step) { case 0: Rx8025RTC.tm_sec = RX8025_BCD2DEC(RX8025_ReadReg(0)&0x7f); step++; break; case 1: Rx8025RTC.tm_min = RX8025_BCD2DEC(RX8025_ReadReg(1)&0x7f); step++; break; case 2: Rx8025RTC.tm_hour = RX8025_BCD2DEC(RX8025_ReadReg(2)&0x7f); step++; break; case 3: Rx8025RTC.tm_wday= RX8025_BCD2DEC(RX8025_ReadReg(3)&0x07); step++; break; case 4: Rx8025RTC.tm_mday = RX8025_BCD2DEC(RX8025_ReadReg(4)&0x3f); step++; break; case 5: Rx8025RTC.tm_mon = RX8025_BCD2DEC(RX8025_ReadReg(5)&0x1f); step++; break; case 6: Rx8025RTC.tm_year = RX8025_BCD2DEC(RX8025_ReadReg(6)&0xff); Rx8025RTC.tm_year += 2000; step = 0; rx8025_status = IDLE_RTC; break; } break; default: break; }}
转载于:https://www.cnblogs.com/zym0805/p/7193462.html