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;
}
}
- void Delayus(u16 us)
- {
- u16 i;
- for(i=0;i<us;i++)
- __nop();
- }
- void IIC_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //ÍÆÍìÊä³ö
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- // GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 Êä³ö¸ß
- }
- void IIC_Start(void)
- {
- SDA_OUT();
- SCL_1
- SDA_1
- Delayus(10);
- SDA_0
- Delayus(10);
- SCL_0
- Delayus(10);
- }
- void IIC_Stop(void)
- {
- u8 i;
- SDA_OUT();//sdaÏßÊä³ö
- SDA_0
- Delayus(10);
- SCL_1
- Delayus(10);
- SDA_1
- for(i=0;i<5;i++)
- {
- Delayus(10);
- }
- }
- u8 IIC_Wait_Ack(void)
- {
- u8 ucErrTime=0;
- SDA_IN(); //SDAÉèÖÃΪÊäÈë
- Delayus(10);
- Delayus(10);
- while(READ_SDA)
- {
- ucErrTime++;
- if(ucErrTime>250)
- {
- IIC_Stop();
- return 1;
- }
- }
- SCL_0//ʱÖÓÊä³ö0
- return 0;
- }
- void IIC_Ack(void)
- {
- SDA_OUT();
- SDA_0;
- Delayus(10);
- SCL_1
- Delayus(10);
- SCL_0
- Delayus(10);
- }
- void IIC_NAck(void)
- {
- SDA_OUT();
- SDA_1;
- Delayus(10);
- SCL_1
- Delayus(10);
- SCL_0
- Delayus(10);
- }
- void IIC_Send_Byte(u8 txd)
- {
- u8 i;
- SDA_OUT();
- for(i=0;i<8;i++)
- {
- if(txd & 0x80) SDA_1
- else SDA_0
- txd <<= 1;
- Delayus(10);
- SCL_1
- Delayus(10);
- SCL_0
- }
- Delayus(10);
- SCL_1
- Delayus(10);
- SCL_0
- }
- u8 IIC_Read_Byte(unsigned char ack)
- {
- u8 i,receive=0;
- SDA_IN();//SDAÉèÖÃΪÊäÈë
- for(i=0;i<8;i++)
- {
- SCL_1
- Delayus(10);
- receive <<=1;
- if(READ_SDA) receive |= 0x01;
- SCL_0
- Delayus(10);
- }
- SDA_OUT();
- return receive;
- }
- void R8025AC_Read(u8 sadd, u8 *buf, u8 len)
- {
- u8 i;
- IIC_Start();
- IIC_Send_Byte(0x64);
- IIC_Send_Byte(sadd<<4|0x01);
- IIC_Start();
- IIC_Send_Byte(0x65);
- for(i=0;i<len-1;i++)
- {
- buf[i] = IIC_Read_Byte(1);
- IIC_Ack();
- }
- buf[i] = IIC_Read_Byte(0);
- IIC_NAck();
- IIC_Stop();
- }
- void R8025AC_Write(u8 sadd,u8 *buf,u8 len)
- {
- u8 i;
- IIC_Start();
- IIC_Send_Byte(0X64);
- IIC_Send_Byte(sadd<<4);
- for(i=0;i<len;i++)
- {
- IIC_Send_Byte(buf[i]);
- }
- IIC_Stop();
- }