1、头文件
#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
2、源文件
#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;
}
STM32使用HAL库驱动SD2405时钟芯片(模拟IIC)
今天的文章时钟芯片有哪些_时钟芯片有哪些分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64296.html