头文件
- #ifndef SD2405_H__
- #define SD2405_H__
- #include "main.h"
- #include "delay.h"
- #define IIC_SCL PBout(13)
- #define IIC_SDA PBout(14)
- #define READ_SDA PBin(14)
- /// SD2405寄存器地址定义 ///
- #define SD2405_ADDR_YEAR 6
- #define SD2405_ADDR_MONTH 5
- #define SD2405_ADDR_DAY 4
- #define SD2405_ADDR_WEEK 3
- #define SD2405_ADDR_HOUR 2
- #define SD2405_ADDR_MINUTE 1
- #define SD2405_ADDR_SECOND 0
- #define SD2405_ADDR_CTR1 0X0F
- #define SD2405_ADDR_CTR2 0X10
- #define SD2405_ADDR_CTR3 0X11
- #define UChar2BCD(chr) ((((chr) / 10) << 4) | ((chr) % 10))
- #define BCD2UChar(bcd) ((((bcd) >> 4) * 10) + ((bcd) & 0X0F))
- #pragma pack(1)
- typedef struct
- {
- uint16_t year;
- uint8_t month;
- uint8_t day;
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- uint8_t week;
- }SD2405_DateTypedef;
- #pragma pack()
- void SD2405_Init(void);
- void SD2405_Write_Time(SD2405_DateTypedef* date);
- SD2405_DateTypedef* SD2405_Read_Time(void);
- #endif
复制代码
源文件
- #include "sd2405.h"
- #include <string.h>
- void IIC_Init(void)
- {
- /* 此处添加你的IIC引脚初始化IO的代码,我是直接使用STM32CubeMX生成的 */
- IIC_SCL = 1;
- IIC_SDA = 1;
- }
- /// 设置IIC的SDA引脚为输出
- void SDA_SET_OUT(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- GPIO_InitStruct.Pin = IIC_SCL_Pin | IIC_SDA_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- }
- /// 设置IIC的SDA引脚为输入
- void SDA_SET_IN(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- GPIO_InitStruct.Pin = IIC_SDA_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- }
- void IIC_Start(void)
- {
- SDA_SET_OUT();
- IIC_SDA = 1;
- IIC_SCL = 1;
- delay_us(5);
- IIC_SDA = 0; //START:when CLK is high,DATA change form high to low
- delay_us(6);
- IIC_SCL = 0;
- }
- void IIC_Stop(void)
- {
- SDA_SET_OUT();
- IIC_SCL = 0;
- IIC_SDA = 0; //STOP:when CLK is high DATA change form low to high
- IIC_SCL = 1;
- delay_us(6);
- IIC_SDA = 1;
- delay_us(6);
- }
- uint8_t IIC_Wait_Ack(void)
- {
- uint8_t tempTime = 0;
- IIC_SDA = 1;
- delay_us(1);
- SDA_SET_IN();
- IIC_SCL = 1;
- delay_us(1);
- while (READ_SDA)
- {
- tempTime++;
- if (tempTime > 250)
- {
- IIC_Stop();
- return 1;
- }
- }
- IIC_SCL = 0;
- return 0;
- }
- void IIC_Ack(void)
- {
- IIC_SCL = 0;
- SDA_SET_OUT();
- IIC_SDA = 0;
- delay_us(2);
- IIC_SCL = 1;
- delay_us(5);
- IIC_SCL = 0;
- }
- void IIC_NAck(void)
- {
- IIC_SCL = 0;
- SDA_SET_OUT();
- IIC_SDA = 1;
- delay_us(2);
- IIC_SCL = 1;
- delay_us(5);
- IIC_SCL = 0;
- }
- void IIC_Send_Byte(uint8_t txd)
- {
- uint8_t t;
- SDA_SET_OUT();
- IIC_SCL = 0;
- for (t = 0; t < 8; t++)
- {
- if ((txd & 0x80) > 0) //0x80 1000 0000
- IIC_SDA = 1;
- else
- IIC_SDA = 0;
- txd <<= 1;
- delay_us(2);
- IIC_SCL = 1;
- delay_us(2);
- IIC_SCL = 0;
- delay_us(2);
- }
- }
- uint8_t IIC_Read_Byte(uint8_t ack)
- {
- uint8_t i, receive = 0;
- SDA_SET_IN();
- for (i = 0; i < 8; i++ )
- {
- IIC_SCL = 0;
- delay_us(2);
- IIC_SCL = 1;
- receive <<= 1;
- if (READ_SDA)receive++;
- delay_us(1);
- }
- if (!ack)
- IIC_NAck();
- else
- IIC_Ack();
- return receive;
- }
- void SD2405_Init(void)
- {
- IIC_Init();
- }
- void SD2405_WriteOneByte(uint8_t WriteAddr, uint8_t Data)
- {
- IIC_Start();
- IIC_Send_Byte(0x64);
- IIC_Wait_Ack();
- IIC_Send_Byte(WriteAddr);
- IIC_Wait_Ack();
- IIC_Send_Byte(Data);
- IIC_Wait_Ack();
- IIC_Stop();
- delay_ms(10);
- }
- uint8_t SD2405_ReadOneByte(uint8_t ReadAddr)
- {
- uint8_t temp;
- IIC_Start();
- IIC_Send_Byte(0x64);
- IIC_Wait_Ack();
- IIC_Send_Byte(ReadAddr);
- IIC_Wait_Ack();
- IIC_Start();
- IIC_Send_Byte(0x65);
- IIC_Wait_Ack();
- temp = IIC_Read_Byte(0);
- IIC_Stop();
- return temp;
- }
- /// 使能写
- void Write_On(void)
- {
- SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x84);
- SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x80);
- }
- /// 禁止写
- void Write_Off(void)
- {
- SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x00);
- SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x52);
- }
- /// 写入时间
- void SD2405_Write_Time(SD2405_DateTypedef* date)
- {
- Write_On();
- SD2405_WriteOneByte(SD2405_ADDR_YEAR, UChar2BCD(date->year - 2000));
- SD2405_WriteOneByte(SD2405_ADDR_MONTH, UChar2BCD(date->month));
- SD2405_WriteOneByte(SD2405_ADDR_DAY, UChar2BCD(date->day));
- SD2405_WriteOneByte(SD2405_ADDR_HOUR, UChar2BCD(date->hour) | 0X80); /* 24小时制 */
- SD2405_WriteOneByte(SD2405_ADDR_MINUTE, UChar2BCD(date->minute));
- SD2405_WriteOneByte(SD2405_ADDR_SECOND, UChar2BCD(date->second));
- SD2405_WriteOneByte(SD2405_ADDR_WEEK, UChar2BCD(date->week));
- Write_Off();
- }
- /// 读取时间
- SD2405_DateTypedef* SD2405_Read_Time(void)
- {
- static SD2405_DateTypedef time;
- memset(&time, 0X00, sizeof(SD2405_DateTypedef));
- time.year = SD2405_ReadOneByte(SD2405_ADDR_YEAR);
- time.month = SD2405_ReadOneByte(SD2405_ADDR_MONTH);
- time.day = SD2405_ReadOneByte(SD2405_ADDR_DAY);
- time.hour = SD2405_ReadOneByte(SD2405_ADDR_HOUR);
- time.minute = SD2405_ReadOneByte(SD2405_ADDR_MINUTE);
- time.second = SD2405_ReadOneByte(SD2405_ADDR_SECOND);
- time.week = SD2405_ReadOneByte(SD2405_ADDR_WEEK);
- time.year = BCD2UChar(time.year) + 2000;
- time.month = BCD2UChar(time.month);
- time.day = BCD2UChar(time.day);
- time.hour = BCD2UChar(time.hour & 0X7F);
- time.second = BCD2UChar(time.second);
- time.minute = BCD2UChar(time.minute);
- time.week = BCD2UChar(time.week);
- return &time;
- }
复制代码
|