Files
HBshuiwuConcentrator/APP/rtc_ext.c
2025-12-15 16:07:49 +08:00

507 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "rtc_ext.h"
#include "bl24c512.h"
#include "include.h"
extern void dl_start();
extern void rp_start();
extern bool is_report_time();
extern bool is_dl_time();
extern void hb_timeproc();
st_rtc_ext ERtctime;
void RTC_EXT_da_mode(bool in_mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SDA_PIN;
if (in_mode)
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
else
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
}
GPIO_Init(RTC_SDA_PIN_PORT, &GPIO_InitStructure );
}
/*************************************************************
函数功能I2C总线复位。
函数名称I2C_Reset。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_Reset(void)
{
RTC_EXT_da_mode(SDA_MODE_IN);
while(1)
{
RTC_SCL_LOW();
delayedus(1);
RTC_SCL_HIGH();
if( RTC_GET_SDA() ==1 )
{
break;
}
delayedus(1);
}
RTC_EXT_da_mode(SDA_MODE_OUT);
}
void RTC_EXT_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RTC_SDA_PIN_CLK | RTC_SCL_PIN_CLK , ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(RTC_SDA_PIN_PORT , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(RTC_SCL_PIN_PORT , &GPIO_InitStructure );
RTC_EXT_Reset();
}
/*************************************************************
函数功能:产生起始位。
函数名称I2C_GenerateSTART。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_GenerateSTART(void)
{
RTC_SDA_HIGH();//eeprom_da(1);
RTC_SCL_HIGH();//eeprom_clk(1);
delayedus(2);
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SCL_LOW();//eeprom_clk(0);
delayedus(2);
}
/*************************************************************
函数功能:产生停始位。
函数名称I2C_GenerateSTOP。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_I2C_GenerateSTOP(void)
{
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SCL_HIGH();//eeprom_clk(1);
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能:检测应答。
函数名称I2C_check_ack。
函数返回:返回值是应答状态。
函数参数:无参数。
**************************************************************/
unsigned char RTC_EXT_check_ack(void)
{
unsigned char ack=0;
RTC_EXT_da_mode(SDA_MODE_IN);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
if(RTC_GET_SDA() ==1)
{
ack=0;
}
else
{
ack=1;
}
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_EXT_da_mode(SDA_MODE_OUT);
return ack;
}
/*************************************************************
函数功能:发送一个应答位。
函数名称I2c_send_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_ack(void)
{
RTC_SDA_LOW();//eeprom_da(0);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
RTC_SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能发送一个NO应答。
函数名称I2c_send_no_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_no_ack(void)
{
RTC_SDA_HIGH();//eeprom_da(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
}
/*************************************************************
函数功能I2C发送一个字节。
函数名称I2c_send_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_byte(unsigned char data )
{
unsigned char i;
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
for(i=0;i<8;i++)
{
if((data&0x80)==0x80)
{
RTC_SDA_HIGH();//eeprom_da(1);
}
else
{
RTC_SDA_LOW(); //eeprom_da(0);
}
RTC_SCL_HIGH(); //eeprom_clk(1);//clk 1
//delayedus(1);
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
//delayedus(1);
data<<=1;
}
delayedus(90);
}
/*************************************************************
函数功能I2C接收一个字节。
函数名称I2c_receive_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
unsigned char RTC_EXT_receive_byte(void)
{
unsigned char i;
unsigned char rda=0;
RTC_EXT_da_mode(SDA_MODE_IN);
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
//delayedus(1);
for(i=0;i<8;i++)
{
rda<<=1;
RTC_SCL_HIGH(); //eeprom_clk(1);//clk 1
//delayedus(1);
if(RTC_GET_SDA() ==1 )
{
rda|=0x01;
}
else
{
rda&=0xFE;
}
RTC_SCL_LOW(); //eeprom_clk(0);//clk
//delayedus(1);
}
RTC_EXT_da_mode(SDA_MODE_OUT);
return rda;
}
/*************************************************************
函数功能RTC8025T读reg
函数名称RTC_read_reg。
函数返回:
函数参数:
**************************************************************/
bool RTC_read_reg(u8 reg, u8 *dat)
{
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_WRIT_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(reg);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_READ_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
*dat = RTC_EXT_receive_byte();
RTC_EXT_send_no_ack();
delayedus(1);
RTC_EXT_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能RTC8025T写reg
函数名称RTC_write_reg。
函数返回:
函数参数:
**************************************************************/
bool RTC_write_reg(u8 reg, u8 dat)
{
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_WRIT_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(reg);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(dat);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能EEPROM任意地址读一字节。
函数名称RTC_test
函数返回:
函数参数:
**************************************************************/
void RTC_test(void)
{
u8 dat_year;
u8 dat_mon;
u8 dat_day;
RTC_EXT_init();
RTC_read_reg(RTC_REG_MONTH, &dat_mon);
RTC_read_reg(RTC_REG_YEAR, &dat_year);
RTC_read_reg(RTC_REG_DAY , &dat_day);
RTC_write_reg(RTC_REG_YEAR, 16);
RTC_write_reg(RTC_REG_MONTH, 6);
RTC_write_reg(RTC_REG_DAY, 14);
RTC_read_reg(RTC_REG_YEAR, &dat_year);
RTC_read_reg(RTC_REG_MONTH, &dat_mon);
RTC_read_reg(RTC_REG_DAY , &dat_day);
printf("%d/%d/%d\r\n", dat_year, dat_mon, dat_day);
}
void set_rtc_time(st_rtc_ext rtc_dat)
{
RTC_EXT_init();
RTC_write_reg(RTC_REG_SEC, rtc_dat.sec);
RTC_write_reg(RTC_REG_MIN, rtc_dat.min);
RTC_write_reg(RTC_REG_HOUR, rtc_dat.hour);
RTC_write_reg(RTC_REG_WEEK, rtc_dat.week);
RTC_write_reg(RTC_REG_DAY, rtc_dat.day);
RTC_write_reg(RTC_REG_MONTH, rtc_dat.month);
RTC_write_reg(RTC_REG_YEAR, rtc_dat.year);
}
void read_rtc_time(st_rtc_ext * rtc_dat)
{
RTC_EXT_init();
st_rtc_ext TempTime1,TempTime2;
/*
RTC_read_reg(RTC_REG_SEC, &rtc_dat->sec);
RTC_read_reg(RTC_REG_MIN, &rtc_dat->min);
RTC_read_reg(RTC_REG_HOUR, &rtc_dat->hour);
RTC_read_reg(RTC_REG_WEEK, &rtc_dat->week);
RTC_read_reg(RTC_REG_DAY, &rtc_dat->day);
RTC_read_reg(RTC_REG_MONTH, &rtc_dat->month);
RTC_read_reg(RTC_REG_YEAR, &rtc_dat->year);
*/
for(u8 n=0 ;n<3; n++)
{
RTC_read_reg(RTC_REG_SEC, &TempTime1.sec);
RTC_read_reg(RTC_REG_MIN, &TempTime1.min);
RTC_read_reg(RTC_REG_HOUR, &TempTime1.hour);
RTC_read_reg(RTC_REG_WEEK, &TempTime1.week);
RTC_read_reg(RTC_REG_DAY, &TempTime1.day);
RTC_read_reg(RTC_REG_MONTH, &TempTime1.month);
RTC_read_reg(RTC_REG_YEAR, &TempTime1.year);
RTC_read_reg(RTC_REG_SEC, &TempTime2.sec);
RTC_read_reg(RTC_REG_MIN, &TempTime2.min);
RTC_read_reg(RTC_REG_HOUR, &TempTime2.hour);
RTC_read_reg(RTC_REG_WEEK, &TempTime2.week);
RTC_read_reg(RTC_REG_DAY, &TempTime2.day);
RTC_read_reg(RTC_REG_MONTH, &TempTime2.month);
RTC_read_reg(RTC_REG_YEAR, &TempTime2.year);
if((TempTime1.sec == TempTime2.sec) &&
(TempTime1.min == TempTime2.min) &&
(TempTime1.hour == TempTime2.hour) &&
(TempTime1.week == TempTime2.week) &&
(TempTime1.day == TempTime2.day) &&
(TempTime1.month == TempTime2.month) &&
(TempTime1.year == TempTime2.year)
)
{
rtc_dat->sec = TempTime1.sec;
rtc_dat->min = TempTime1.min;
rtc_dat->hour = TempTime1.hour;
rtc_dat->week = TempTime1.week;
rtc_dat->day = TempTime1.day;
rtc_dat->month = TempTime1.month;
rtc_dat->year = TempTime1.year;
return;
}
}
RTC_read_reg(RTC_REG_SEC, &rtc_dat->sec);
RTC_read_reg(RTC_REG_MIN, &rtc_dat->min);
RTC_read_reg(RTC_REG_HOUR, &rtc_dat->hour);
RTC_read_reg(RTC_REG_WEEK, &rtc_dat->week);
RTC_read_reg(RTC_REG_DAY, &rtc_dat->day);
RTC_read_reg(RTC_REG_MONTH, &rtc_dat->month);
RTC_read_reg(RTC_REG_YEAR, &rtc_dat->year);
}
void read_rtc_stime(sTime *time_dat)
{
RTC_EXT_init();
RTC_read_reg(RTC_REG_SEC, &time_dat->second);
RTC_read_reg(RTC_REG_MIN, &time_dat->minute);
RTC_read_reg(RTC_REG_HOUR, &time_dat->hour);
RTC_read_reg(RTC_REG_DAY, &time_dat->day);
RTC_read_reg(RTC_REG_MONTH, &time_dat->month);
RTC_read_reg(RTC_REG_YEAR, &time_dat->year);
}
u8* GetCurrentTime( void )
{
return (u8*)&ERtctime;
}
void GetExternClockTime(st_rtc_ext * rtc_dat)
{
MemCpy((u8*)rtc_dat,(u8*)&ERtctime,sizeof(st_rtc_ext));
}
bool CheckTimeDate( st_rtc_ext * rtc_dat )
{
if(rtc_dat->year < 0x17) return FALSE;
if((rtc_dat->month > 0x12) || (rtc_dat->month == 0x00) )return FALSE;
if((rtc_dat->day > 0x31) || (rtc_dat->day == 0x00) ) return FALSE;
if(rtc_dat->hour > 0x24) return FALSE;
if(rtc_dat->min > 0x60) return FALSE;
if(rtc_dat->sec > 0x60) return FALSE;
if(rtc_dat->week > 0x06) return FALSE;
return TRUE;
}
static bool is_reset = false;
static u32 reset_count = 0;
void ExtRTC_Process_Task(void *ptr)
{
RTC_EXT_init();
read_rtc_time(&ERtctime);
// if( ( CheckBCDFormat( (u8*)&ERtctime, sizeof(&ERtctime) ) == FALSE ) || (CheckTimeDate(&ERtctime) == FALSE) )
// {
// ERtctime.year = 0x17;
// ERtctime.month = 0x07;
// ERtctime.day = 0x01;
// ERtctime.hour = 0x10;
// ERtctime.min = 0x23;
// ERtctime.sec = 0x45;
// ERtctime.week = 0x06;
//
// set_rtc_time(ERtctime);
// }
for (;;)
{
read_rtc_time(&ERtctime);
vTaskDelay( 2000 / portTICK_RATE_MS );
hb_timeproc();
if(ERtctime.hour==0x09 && ERtctime.min == 0x30)
{
is_reset = true;
}
if(is_reset)
{
reset_count ++ ;
if(reset_count>60)
{
SysReset();
}
}
}
}