123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 |
- #include "hal_pca8565.h"
- #include "hc32_ll_gpio.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #define IIC_ERR 0
- #define IIC_OK 1
-
- #define READ_SDA2 GPIO_ReadInputPins(GPIO_PORT_B,GPIO_PIN_12)
- #define IIC_SDA2(n) (n?GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_12):GPIO_ResetPins(GPIO_PORT_B, GPIO_PIN_12))
- #define IIC_SCL2(n) (n?GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_13):GPIO_ResetPins(GPIO_PORT_B, GPIO_PIN_13))
- #define pca8565_speed 5
- //需要示波器调1us的时间
- static void delay_us(uint16_t time)
- {
- uint16_t i;
- for(i=time;i>0;i--)
- {
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
- }
- }
- void iicx_init(void)
- {
- stc_gpio_init_t pstcGpioInit1;
- GPIO_StructInit(&pstcGpioInit1);
-
- pstcGpioInit1.u16PinDir = PIN_DIR_OUT;
- pstcGpioInit1.u16PinState = PIN_STAT_RST;
- GPIO_Init(GPIO_PORT_B, GPIO_PIN_12,&pstcGpioInit1);
- GPIO_Init(GPIO_PORT_B, GPIO_PIN_13,&pstcGpioInit1);
-
- GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_12);
- GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_13);
- }
-
-
- static void SDA_IN2(void)
- {
- stc_gpio_init_t pstcGpioInit3;//iic的引脚
- pstcGpioInit3.u16PinDir = PIN_DIR_IN;
- GPIO_Init(GPIO_PORT_B, GPIO_PIN_12,&pstcGpioInit3);
- }
- static void SDA_OUT2(void)
- {
- stc_gpio_init_t pstcGpioInit3;
- pstcGpioInit3.u16PinDir = PIN_DIR_OUT;
- pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS;
- GPIO_Init(GPIO_PORT_B, GPIO_PIN_12,&pstcGpioInit3);
- }
-
-
- static void iic_start(void)
- {
- SDA_OUT2();
-
- IIC_SDA2(1);
- IIC_SCL2(1);
- delay_us(pca8565_speed);
-
- IIC_SDA2(0);
- delay_us(pca8565_speed);
- IIC_SCL2(0);
- }
- static void iic_stop(void)
- {
- SDA_OUT2();
-
- IIC_SCL2(0);
- IIC_SDA2(0);
- delay_us(pca8565_speed);
-
- IIC_SCL2(1);
- IIC_SDA2(1);
- delay_us(pca8565_speed);
- }
- static void iic_ack(void)
- {
- SDA_OUT2();
-
- IIC_SCL2(0);
- IIC_SDA2(0);
- delay_us(pca8565_speed);
-
- IIC_SCL2(1);
- delay_us(pca8565_speed);
- IIC_SCL2(0);
- }
- static void iic_nack(void)
- {
- SDA_OUT2();
-
- IIC_SCL2(0);
- IIC_SDA2(1);
- delay_us(pca8565_speed);
-
- IIC_SCL2(1);
- delay_us(pca8565_speed);
- IIC_SCL2(0);
- }
-
- static uint8_t iic_wait_ack(void)
- {
- uint16_t t =200;
- SDA_OUT2();
-
- IIC_SDA2(1);delay_us(1);
- IIC_SCL2(1);delay_us(1);
- SDA_IN2();
- while(READ_SDA2)
- {
- t--;
-
- if(t==0)
- {
- iic_stop();
- return 1;
- }
- delay_us(1);
- }
- IIC_SCL2(0);
-
- return 0;
- }
- static void iic_send_byte(uint8_t byte)
- {
- uint8_t bit_cnt;
- SDA_OUT2();
- IIC_SCL2(0);
-
- for(bit_cnt=0;bit_cnt<8;bit_cnt++)
- {
- if(byte&0x80)
- IIC_SDA2(1);
- else
- IIC_SDA2(0);
-
- byte<<=1;
- delay_us(pca8565_speed);
- IIC_SCL2(1);
- delay_us(pca8565_speed);
- IIC_SCL2(0);
- }
- }
-
- static uint8_t iic_recive_byte(unsigned char ack)
- {
- uint8_t retc = 0;
- uint8_t bit_cnt;
- SDA_IN2();
- for(bit_cnt=0;bit_cnt<8;bit_cnt++)
- {
- IIC_SCL2(0);
- delay_us(pca8565_speed);
- IIC_SCL2(1);
-
- retc=retc<<1;
- if(READ_SDA2)
- retc++;
-
- delay_us(pca8565_speed);
- }
- return(retc);
- }
- /*
- ************************************************************
- * 函数名称: Pcf8563_IIC_WriteByte
- *
- * 函数功能: 软件IIC读取一个字节
- *
- * 入口参数: slaveAddr:从机地址
- * regAddr:寄存器地址
- * val:需要读取的数据缓存
- *
- * 返回参数: 1-成功 0-失败
- *
- * 说明:
- ************************************************************
- */
- void Pcf8563_IIC_ReadByte ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Val )
- {
- // //起始信号
- // iic_start();
- // //发送设备地址(写)
- // if(!iic_send_byte ( SlaveAddr )) //等待应答
- // return IIC_ERR;
- // //发送寄存器地址
- // if(!iic_send_byte ( RegAddr )) //等待应答
- // return IIC_ERR;
- // iic_start(); //重启信号
- // //发送设备地址(读)
- // if(!iic_send_byte ( SlaveAddr + 1 )) //等待应答
- // return IIC_ERR;
- // *Val = iic_recive_byte (0); //产生一个非应答信号,代表读取接收
- // iic_stop(); //停止信号
- // return IIC_OK;
-
- iic_start();
- iic_send_byte(SlaveAddr);
- iic_wait_ack();
- iic_send_byte(RegAddr);
- iic_wait_ack();
- iic_start();
- iic_send_byte(SlaveAddr|0x01);
- iic_wait_ack();
- *Val = iic_recive_byte(0);
- iic_stop();
- }
- /*
- ************************************************************
- * 函数名称: Pcf8563_IIC_WriteByte
- *
- * 函数功能: 软件IIC写一个字节
- *
- * 入口参数: slaveAddr:从机地址
- * regAddr:寄存器地址
- * val:需要读取的数据缓存
- *
- * 返回参数: 1-成功 0-失败
- *
- * 说明:
- ************************************************************
- */
- void Pcf8563_IIC_WriteByte ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Val )
- {
- // iic_start(); //起始信号
- // //发送设备地址(写)
- // if (!iic_send_byte ( SlaveAddr )) //等待应答
- // return IIC_ERR;
- // //发送寄存器地址
- // if (!iic_send_byte ( RegAddr ) ) //等待应答
- // return IIC_ERR;
- // if (!iic_send_byte ( *Val ) )
- // return IIC_ERR;
- //
- // iic_stop(); //停止信号
- // return IIC_OK;
-
- iic_start();
- iic_send_byte(SlaveAddr);
- iic_wait_ack();
- iic_send_byte(RegAddr);
- iic_wait_ack();
- iic_send_byte(*Val);
- iic_wait_ack();
- iic_stop();
- }
- /*
- ************************************************************
- * 函数名称: Pcf8563_IIC_WriteBytes
- *
- * 函数功能: 软件IIC写多个数据
- *
- * 入口参数: slaveAddr:从机地址
- * regAddr:寄存器地址
- * buf:需要写入的数据缓存
- * num:数据长度
- *
- * 返回参数: 1-成功 0-失败
- *
- * 说明:
- ************************************************************
- */
- _Bool Pcf8563_IIC_WriteBytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
- {
- iic_start(); //起始信号
- //发送设备地址(写)
- iic_send_byte ( SlaveAddr ); //等待应答
- iic_wait_ack();
- //发送寄存器地址
- iic_send_byte ( RegAddr ) ; //等待应答
- iic_wait_ack();
- while ( Num-- ) //循环写入数据
- {
- //发送数据
- iic_send_byte ( *Buf ); //等待应答
- iic_wait_ack();
- Buf++; //数据指针偏移到下一个
- delay_us(10);
- }
- iic_stop(); //停止信号
- return IIC_OK;
- }
- /*
- ************************************************************
- * 函数名称: Pcf8563_IIC_ReadBytes
- *
- * 函数功能: 软件IIC读多个数据
- *
- * 入口参数: slaveAddr:从机地址
- * regAddr:寄存器地址
- * buf:需要写入的数据缓存
- * num:数据长度
- *
- * 返回参数: 1-成功 0-失败
- *
- * 说明:
- ************************************************************
- */
- _Bool Pcf8563_IIC_ReadBytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
- {
- iic_start(); //起始信号
- //发送设备地址(写)
- iic_send_byte ( SlaveAddr ); //等待应答
- iic_wait_ack();
- //发送寄存器地址
- iic_send_byte ( RegAddr ); //等待应答
- iic_wait_ack();
- iic_start(); //重启信号
- //发送设备地址(读)
- iic_send_byte ( SlaveAddr + 1 ); //等待应答
- iic_wait_ack();
- while ( Num-- )
- {
- //偏移到下一个数据存储地址
- if ( Num == 0 )
- {
- *Buf = iic_recive_byte ( 0 ); //最后一个数据需要回NOACK
- }
- else
- {
- *Buf = iic_recive_byte ( 1 ); //回应ACK
- }
- Buf++;
- }
- iic_stop();
- return IIC_OK;
- }
- //常量定义
- const char week_day[7][10]={"SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"};
- const int8_t months[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
- //变量定义
- rtc_time_st rtc_time;
- /*
- ************************************************************
- * 函数名称: Pcf8563_Rtc_Init
- *
- * 函数功能: 外置RTC初始化
- *
- * 入口参数: 无
- *
- * 返回参数: 无
- *
- * 说明: STATUS1:正常模式、POR disabled
- * STATUS2:INT is active when TF is active
- * read: alarm flag inactive
- * write: alarm flag is cleared
- * read: timer flag inactive
- * write: timer flag is cleared
- * alarm interrupt disabled
- * timer interrupt disabled
- * CLKOUT:CLKOUT output is activated
- * frequency output at pin CLKOUT is 1.024 kHz(为何设置为该值)
- ************************************************************
- */
- void rtc_init(void)
- {
- iicx_init();
- }
- void Pcf8563_Rtc_Init(void)
- {
- DDL_DelayMS(20);
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,PCF8563_ADDR_CONTROL_STATUS1,0x00); //默认
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,PCF8563_ADDR_CONTROL_STATUS2,0x00); //默认
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,PCF8563_ADDR_CLKOUT,0x80); //使能CLK输出,1024Hz
- }
- /*
- ************************************************************
- * 函数名称: Get_Pcf8563_Rtc_Time
- *
- * 函数功能: 获取外置RTC时间
- *
- * 入口参数: rtc_time
- *
- * 返回参数: 无
- *
- * 说明: 读时间 年、月、日、时、分、日期 week为指针指向week_day数组
- ************************************************************
- */
- void Get_Pcf8563_Rtc_Time(rtc_time_st *rtc_time)
- {
- uint8_t time_buf[7]={0};
-
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x02,&time_buf[0]);//秒
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x03,&time_buf[1]);//分
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x04,&time_buf[2]);//时
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x05,&time_buf[3]);//日
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x06,&time_buf[4]);//星期
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x07,&time_buf[5]);//月
- Pcf8563_IIC_ReadByte(PCF8563_SLAVE_ADDRESS,0x08,&time_buf[6]);//年
-
- //将时间从BCD编码变成十进制
- rtc_time->sec=BCDToDec(time_buf[0] & 0X7F); //秒
- rtc_time->min=BCDToDec(time_buf[1] & 0X7F); //分
- rtc_time->hour=BCDToDec(time_buf[2] & 0X3F); //时
- rtc_time->date=BCDToDec(time_buf[3] & 0X3F); //日
- // rtc_time->week=(time_buf[4] & 0X07); //星期(值0为星期7 1为星期1)
- rtc_time->week=week_day[(time_buf[4] & 0X07)]; //星期(字符串指针)
- rtc_time->mon=BCDToDec(time_buf[5] & 0X1F); //月
- rtc_time->year=2000 + (uint16_t)BCDToDec(time_buf[6]); //年
-
- // for(int i = 0;i < 7; i++)
- // printf("%x ",time_buf[i]);
- }
- /*
- ************************************************************
- * 函数名称: LogRtcTime
- *
- * 函数功能: LogRtcTime
- *
- * 入口参数: rtc_time
- *
- * 返回参数: 无
- *
- * 说明: 读时间 年、月、日、时、分、日期 week为指针指向week_day数组
- ************************************************************
- */
- void LogRtcTime(rtc_time_st *rtc_time)
- {
- printf("data:%4d-%02d-%02d %02d:%02d:%02d week:%s\r\n",rtc_time->year,rtc_time->mon,rtc_time->date,rtc_time->hour,rtc_time->min,rtc_time->sec,rtc_time->week);
- }
- /*
- ************************************************************
- * 函数名称: Set_Pcf8563_Rtc_Time
- *
- * 函数功能: 获取外置RTC时间
- *
- * 入口参数: year mon date hour min sec
- *
- * 返回参数: 无
- *
- * 说明: 设置RTC时间 week为0-7 0为星期7 1为星期1
- ************************************************************
- */
- void Set_Pcf8563_Rtc_Time(uint16_t year,uint8_t mon,uint8_t date,uint8_t hour,uint8_t min,uint8_t sec,uint8_t week)
- {
- //将时间从十进制变成BCD编码
- uint8_t time_buf[7]={0};
-
- time_buf[6] = DecToBCD((uint8_t)(year-2000));
- time_buf[5] = DecToBCD(mon);
- time_buf[4] = week;
- time_buf[3] = DecToBCD(date);
- time_buf[2] = DecToBCD(hour);
- time_buf[1] = DecToBCD(min);
- time_buf[0] = DecToBCD(sec);
- // for(int i = 0;i < 7; i++)
- // printf("%x ",time_buf[i]);
- // printf("\n");
- Pcf8563_IIC_WriteBytes(PCF8563_SLAVE_ADDRESS,PCF8563_ADDR_SEC,time_buf,7);
- }
- /*
- ************************************************************
- * 函数名称: DecToBCD
- *
- * 函数功能: DecToBCD
- *
- * 入口参数: unsigned char
- *
- * 返回参数: unsigned char
- *
- * 说明: 十进制转BCD编码
- ************************************************************
- */
- unsigned char DecToBCD(unsigned char _dec)
- {
- unsigned char temp = 0;
- while (_dec >= 10)
- {
- temp++;
- _dec -= 10;
- }
- return ((unsigned char)(temp << 4) | _dec);
- }
- /*
- ************************************************************
- * 函数名称: BCDToDec
- *
- * 函数功能: BCDToDec
- *
- * 入口参数: unsigned char
- *
- * 返回参数: unsigned char
- *
- * 说明: BCD编码转十进制
- ************************************************************
- */
- unsigned char BCDToDec(unsigned char _BCD)
- {
- unsigned char temp = 0;
- temp = ((unsigned char)(_BCD & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
- return (temp + (_BCD & (unsigned char)0x0F));
- }
- /*
- ************************************************************
- * 函数名称: Days_Count
- *
- * 函数功能: 计算日期之间的天数
- *
- * 入口参数: rtc_time_st 起始和结束日期
- *
- * 返回参数: 天数
- *
- * 说明:
- ************************************************************
- */
- int Days_Count(rtc_time_st *start,rtc_time_st *stop)
- {
- int day_start=0;
- int day_stop=0;
- uint8_t i=0;
- if(start->year==stop->year) //同一年
- {
- if(ISLOOP(start->year)) //闰年
- {
- if(start->mon<=2) //计算开始的天数
- {
- if(start->mon==1)
- day_start=0;
- else
- {
- day_start=day_start+months[0];
- }
-
- }
- else
- {
- for(i=1;i<start->mon;i++)
- day_start=day_start+months[i-1]+1;
- }
-
- if(stop->mon<=2) //计算结束的的天数
- {
- if(stop->mon==1)
- day_stop=0;
- else
- {
- day_stop=day_stop+months[0];
- }
-
- }
- else
- {
- for(i=1;i<stop->mon;i++)
- day_stop=day_stop+months[i-1]+1;
- }
- }
- else //平年
- {
- if(start->mon==1) //计算开始的天数
- day_start=0;
- else
- {
- for(i=1;i<start->mon;i++)
- day_start=day_start+months[i-1];
- }
-
- if(stop->mon==1) //计算结束的的天数
- day_stop=0;
- else
- {
- for(i=1;i<stop->mon;i++)
- day_stop=day_stop+months[i-1];
- }
- }
- return day_stop-day_start;
- }
- else //不同年(此时一定12月和1月)
- {
- return 31-start->date+stop->date;
- }
- }
- /*************************************RTC定时唤醒**********************************************/
- void P8563_alarm(unsigned char min)
- {
- min = DecToBCD(min);
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,0x9,min); /*分钟报警*/
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,0x01,0x12); /*报警有效*/ //使能报警器和定时器发出中断请求
- }
-
- void clear_alarm(void)
- {
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,0x01,0x02);//清中断标志
- }
- /******************关闭闹钟中断***************************/
- void close_alarm(void)
- {
- Pcf8563_IIC_WriteByte(PCF8563_SLAVE_ADDRESS,0x01,0x00);//禁止中断
- }
-
- #include "string.h"
- #include "FreeRTOS.h"
- #include "FreeRTOSConfig.h"
- #include "task.h"
- void pca8565_task(void *argv)
- {
- Pcf8563_Rtc_Init();
- Set_Pcf8563_Rtc_Time(2023,5,19,15,11,33,5);//33 22 16 17 3 5 23
- while(1)
- {
- Get_Pcf8563_Rtc_Time(&rtc_time);
- LogRtcTime(&rtc_time);
-
- vTaskDelay(1000);
- }
- }
|