打印
[应用相关]

STM32使用HAL库驱动SD2405时钟芯片(模拟IIC)

[复制链接]
850|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wakayi|  楼主 | 2021-7-4 16:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
头文件
#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


使用特权

评论回复
沙发
wakayi|  楼主 | 2021-7-4 16:59 | 只看该作者
源文件
#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);
}



使用特权

评论回复
板凳
wakayi|  楼主 | 2021-7-4 17:00 | 只看该作者
/// 设置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);
}


使用特权

评论回复
地板
wakayi|  楼主 | 2021-7-4 17:00 | 只看该作者
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;
}



使用特权

评论回复
5
wakayi|  楼主 | 2021-7-4 17:00 | 只看该作者
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);
}


使用特权

评论回复
6
wakayi|  楼主 | 2021-7-4 17:00 | 只看该作者
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;
}


使用特权

评论回复
7
wakayi|  楼主 | 2021-7-4 17:00 | 只看该作者
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;
}



使用特权

评论回复
8
wakayi|  楼主 | 2021-7-4 17:01 | 只看该作者
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;
}




使用特权

评论回复
9
wakayi|  楼主 | 2021-7-4 17:01 | 只看该作者
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);
        }
}

使用特权

评论回复
10
wakayi|  楼主 | 2021-7-4 17:01 | 只看该作者
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;
}


使用特权

评论回复
11
wakayi|  楼主 | 2021-7-4 17:01 | 只看该作者
void SD2405_Init(void)

{
        IIC_Init();


}

使用特权

评论回复
12
wakayi|  楼主 | 2021-7-4 17:02 | 只看该作者
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);
}


使用特权

评论回复
13
wakayi|  楼主 | 2021-7-4 17:02 | 只看该作者
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;
}


使用特权

评论回复
14
wakayi|  楼主 | 2021-7-4 17:02 | 只看该作者
/// 使能写
void Write_On(void)
{
        SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x84);
        SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x80);
}




使用特权

评论回复
15
wakayi|  楼主 | 2021-7-4 17:02 | 只看该作者
/// 禁止写
void Write_Off(void)
{
        SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x00);
        SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x52);
}



使用特权

评论回复
16
wakayi|  楼主 | 2021-7-4 17:02 | 只看该作者
/// 写入时间
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();
}

使用特权

评论回复
17
wakayi|  楼主 | 2021-7-4 17:03 | 只看该作者
/// 读取时间
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;
}


使用特权

评论回复
18
kiwis66| | 2021-7-5 08:51 | 只看该作者
不是有RTC么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

4083

帖子

1

粉丝