#include "RTC_BL5372.h"
#include "rx.h"
#include "DataStore.h"
#include "ddl.h"
h_alarm_set alarm_value;
h_rtc_init_time current_time;
h_rtc_read_time current_read_time;
void RTC_SDA_IN(void)
{
stc_gpio_cfg_t stcGpioCfg;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
stcGpioCfg.enDir = GpioDirIn; //端口方向配置->输入
stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置->高驱动能力
stcGpioCfg.enPu = GpioPuEnable; //端口上下拉配置->无
stcGpioCfg.enPd = GpioPdDisable;
stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB
Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);
}
void RTC_SDA_OUT(void)
{
stc_gpio_cfg_t stcGpioCfg;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
stcGpioCfg.enDir = GpioDirOut; //端口方向配置->输入
stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置->高驱动能力
stcGpioCfg.enPu = GpioPuEnable; //端口上下拉配置->无
stcGpioCfg.enPd = GpioPdDisable;
stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB
Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);
}
//初始化IIC
void RTC_IIC_Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟
stcGpioCfg.enDir = GpioDirOut; //端口方向配置->输入
stcGpioCfg.enDrv = GpioDrvL; //驱动能力配置->高驱动能力
stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置->无
stcGpioCfg.enPd = GpioPdDisable;
stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB
Gpio_Init(RTC_IIC_PORT, RTC_IIC_SCL, &stcGpioCfg);
Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
}
//产生IIC起始信号
void RTC_IIC_Start(void)
{
RTC_SDA_OUT(); // sda线输出
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Ddl_Delay1us(4);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA); // START:when CLK is high,DATA change form high to low
Ddl_Delay1us(4);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void RTC_IIC_Stop(void)
{
RTC_SDA_OUT(); // sda线输出
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA); // STOP:when CLK is high DATA change form low to high
Ddl_Delay1us(4);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA); //发送I2C总线结束信号
Ddl_Delay1us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 RTC_IIC_Wait_Ack(void)
{
u8 ucErrTime = 0;
RTC_SDA_IN(); // SDA设置为输入
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
Ddl_Delay1us(2);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Ddl_Delay1us(2);
while (RTC_READ_SDA == TRUE)
{
ucErrTime++;
if (ucErrTime > 250)
{
RTC_IIC_Stop();
return 1;
}
}
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //时钟输出0
return 0;
}
//产生ACK应答
void RTC_IIC_Ack(void)
{
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
RTC_SDA_OUT();
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA);
Ddl_Delay1us(2);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Ddl_Delay1us(2);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
}
//不产生ACK应答
void RTC_IIC_NAck(void)
{
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
RTC_SDA_OUT();
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
Ddl_Delay1us(2);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
Ddl_Delay1us(2);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
}
// IIC发送一个字节
//返回从机有无应答
// 1,有应答
// 0,无应答
void RTC_IIC_Send_Byte(u8 txd)
{
u8 t;
RTC_SDA_OUT();
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //拉低时钟开始数据传输
for (t = 0; t < 8; t++)
{
// RTC_IIC_SDA=(txd&0x80)>>7;
if ((txd & 0x80) >> 7)
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
else
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA);
txd <<= 1;
// Ddl_Delay1us(2); //对TEA5767这三个延时都是必须的
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
// Ddl_Delay1us(2);
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
// Ddl_Delay1us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 RTC_IIC_Read_Byte(unsigned char ack)
{
unsigned char i, receive = 0;
RTC_SDA_IN(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
delay10us(1);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
receive <<= 1;
if (RTC_READ_SDA == TRUE)
receive++;
Ddl_Delay1us(1);
}
if (!ack)
RTC_IIC_NAck(); //发送nACK
else
RTC_IIC_Ack(); //发送ACK
return receive;
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 RTC_IIC_Read_Byte_Fast_Ack(unsigned char ack)
{
unsigned char i, receive = 0;
RTC_SDA_IN(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
receive <<= 1;
if (RTC_READ_SDA == TRUE)
receive++;
}
if (!ack)
RTC_IIC_NAck(); //发送nACK
else
RTC_IIC_Ack(); //发送ACK
return receive;
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 RTC_IIC_Read_Byte_Fast_No_Ack()
{
unsigned char i, receive = 0;
RTC_SDA_IN(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
receive <<= 1;
if (RTC_READ_SDA == TRUE)
receive++;
}
return receive;
}
//初始化IIC接口
void RTC_Init(void)
{
RTC_IIC_Init();
}
//在AT24CXX指定地址读出一个数据
// ReadAddr:开始读数的地址
//返回值 :读到的数据
u8 RTC_ReadOneByte(u16 ReadAddr)
{
u8 temp = 0;
RTC_IIC_Start();
RTC_IIC_Send_Byte(IIC_WRITE_ARR); //发送写命令
RTC_IIC_Wait_Ack();
RTC_IIC_Send_Byte(((ReadAddr<<4)|0)); //发送高地址
RTC_IIC_Wait_Ack();
RTC_IIC_Start();
RTC_IIC_Send_Byte(IIC_READ_ARR); //进入接收模式
RTC_IIC_Wait_Ack();
temp = RTC_IIC_Read_Byte(0);
// IIC_NAck();
RTC_IIC_Stop(); //产生一个停止条件
delay1ms(1);
Wdt_Feed();
return temp;
}
//在AT24CXX指定地址写入一个数据
// WriteAddr :写入数据的目的地址
// DataToWrite:要写入的数据
void RTC_WriteOneByte(u16 WriteAddr, u8 DataToWrite)
{
RTC_IIC_Start();
RTC_IIC_Send_Byte(IIC_WRITE_ARR); //发送写命令
RTC_IIC_Wait_Ack();
RTC_IIC_Send_Byte(((WriteAddr<<4)|0)); //发送高地址
RTC_IIC_Wait_Ack();
RTC_IIC_Send_Byte(DataToWrite); //发送字节
RTC_IIC_Wait_Ack();
RTC_IIC_Stop(); //产生一个停止条件
delay1ms(10);
}
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
// WriteAddr :开始写入的地址
// DataToWrite:数据数组首地址
// Len :要写入数据的长度2,4
void RTC_WriteLenByte(u16 WriteAddr, unsigned char *pBuffer, u8 Len)
{
while(Len--)
{
RTC_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
// ReadAddr :开始读出的地址
//返回值 :数据
// Len :要读出数据的长度2,4
void RTC_ReadLenByte(unsigned char ReadAddr,unsigned char *pBuffer,unsigned char NumToRead)
{
while(NumToRead)
{
*pBuffer++=RTC_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)65535来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 RTC_Check(void)
{
u8 temp;
temp = RTC_ReadOneByte(65535); //避免每次开机都写AT24CXX
if (temp == 0x55)
return 0;
else //排除第一次初始化的情况
{
RTC_WriteOneByte(65535, 0x55);
temp = RTC_ReadOneByte(65535);
if (temp == 0x55)
return 0;
}
return 1;
}
//在AT24CXX里面的指定地址开始读出指定个数的数据
// ReadAddr :开始读出的地址 对24c02为0~255
// pBuffer :数据数组首地址
// NumToRead:要读出数据的个数
void RTC_Read(u16 ReadAddr, u8 *pBuffer, u16 NumToRead)
{
while (NumToRead)
{
*pBuffer++ = RTC_ReadOneByte(ReadAddr++);
// printf("%c\n",*pBuffer);//显示读到的字符串
NumToRead--;
Wdt_Feed();
}
}
//在AT24CXX里面的指定地址开始写入指定个数的数据
// WriteAddr :开始写入的地址 对24c02为0~255
// pBuffer :数据数组首地址
// NumToWrite:要写入数据的个数
void RTC_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
{
while (NumToWrite--)
{
RTC_WriteOneByte(WriteAddr, *pBuffer);
WriteAddr++;
pBuffer++;
Wdt_Feed();
}
}
//用来设置当前的时间
void BL5372_init(h_rtc_init_time time)
{
unsigned char BL5372buf[16];
unsigned char temp;
unsigned char index=0;
///RTC_IIC_Init
BL5372buf[index++]=time.Set_Second;second
BL5372buf[index++]=time.Set_Minute;minute
BL5372buf[index++]=time.Set_Hour;hour
BL5372buf[index++]=time.Set_Week;week
BL5372buf[index++]=time.Set_Day;day
BL5372buf[index++]=time.Set_Month;month
BL5372buf[index++]=time.Set_Year;///year
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=0x00;
BL5372buf[index++]=RTC_CRL_G1_USUAL;
BL5372buf[index++]=RTC_CRL_G2_USUAL;
do{
RTC_WriteLenByte(0x00,BL5372buf,16);
temp=RTC_ReadOneByte(RTC_CRL_G2_ARR);
}while((temp&0x10)==0x10);
}
//读当前时间
void Read_Nowtime(h_rtc_read_time *read_time)
{
read_time->Second=RTC_ReadOneByte(RTC_SECOND_ARR);
read_time->Minute=RTC_ReadOneByte(RTC_MINUTE_ARR);
read_time->Hour=RTC_ReadOneByte(RTC_HOUR_ARR);
read_time->Week=RTC_ReadOneByte(RTC_WEEK_ARR);
read_time->Day=RTC_ReadOneByte(RTC_DAY_ARR);
read_time->Month=RTC_ReadOneByte(RTC_MONTH_ARR);
read_time->Year=RTC_ReadOneByte(RTC_YEAR_ARR);
read_time->Control_1=RTC_ReadOneByte(RTC_CRL_G1_ARR);
read_time->Control_2=RTC_ReadOneByte(RTC_CRL_G2_ARR);
}
//自定义时间闹钟
void RTC_SetAlarm(h_alarm_set value)
{
RTC_WriteOneByte(ALARM_CLOCK_MINUTE_ARR,value.Minute);
RTC_WriteOneByte(ALARM_CLOCK_HOUR_ARR,value.Hour);
RTC_WriteOneByte(ALARM_CLOCK_WEEK_ARR,value.Week);
RTC_WriteOneByte(RTC_CRL_G1_ARR,RTC_CRL_G1_ALARM);
RTC_WriteOneByte(RTC_CRL_G2_ARR,RTC_CRL_G2_ALARM);
}
//定时间隔输出
void RTC_Fixed_interval_timer(interval_timer Mode)
{
RTC_WriteOneByte(RTC_CRL_G1_ARR,Mode);
RTC_WriteOneByte(RTC_CRL_G2_ARR,RTC_CRL_G2_USUAL);
}