你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32使用HAL库驱动SD2405时钟芯片(模拟IIC)

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
头文件
  1. #ifndef SD2405_H__
  2. #define SD2405_H__

  3. #include "main.h"
  4. #include "delay.h"


  5. #define IIC_SCL PBout(13)
  6. #define IIC_SDA PBout(14)
  7. #define READ_SDA PBin(14)

  8. /// SD2405寄存器地址定义 ///
  9. #define SD2405_ADDR_YEAR   6
  10. #define SD2405_ADDR_MONTH  5
  11. #define SD2405_ADDR_DAY    4
  12. #define SD2405_ADDR_WEEK   3
  13. #define SD2405_ADDR_HOUR   2
  14. #define SD2405_ADDR_MINUTE 1
  15. #define SD2405_ADDR_SECOND 0

  16. #define SD2405_ADDR_CTR1 0X0F
  17. #define SD2405_ADDR_CTR2 0X10
  18. #define SD2405_ADDR_CTR3 0X11


  19. #define UChar2BCD(chr)  ((((chr) / 10) << 4) | ((chr) % 10))
  20. #define BCD2UChar(bcd) ((((bcd) >> 4) * 10) + ((bcd) & 0X0F))


  21. #pragma pack(1)
  22. typedef struct
  23. {
  24.         uint16_t year;
  25.         uint8_t month;
  26.         uint8_t day;
  27.         uint8_t hour;
  28.         uint8_t minute;
  29.         uint8_t second;
  30.         uint8_t week;
  31. }SD2405_DateTypedef;
  32. #pragma pack()

  33. void SD2405_Init(void);
  34. void SD2405_Write_Time(SD2405_DateTypedef* date);
  35. SD2405_DateTypedef* SD2405_Read_Time(void);

  36. #endif
复制代码

源文件
  1. #include "sd2405.h"
  2. #include <string.h>

  3. void IIC_Init(void)
  4. {
  5. /* 此处添加你的IIC引脚初始化IO的代码,我是直接使用STM32CubeMX生成的 */
  6.         IIC_SCL = 1;
  7.         IIC_SDA = 1;
  8. }

  9. /// 设置IIC的SDA引脚为输出
  10. void SDA_SET_OUT(void)
  11. {
  12.         GPIO_InitTypeDef GPIO_InitStruct = {0};
  13.         GPIO_InitStruct.Pin = IIC_SCL_Pin | IIC_SDA_Pin;
  14.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  15.         GPIO_InitStruct.Pull = GPIO_NOPULL;
  16.         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  17.         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  18. }

  19. /// 设置IIC的SDA引脚为输入
  20. void SDA_SET_IN(void)
  21. {
  22.         GPIO_InitTypeDef GPIO_InitStruct = {0};
  23.         GPIO_InitStruct.Pin = IIC_SDA_Pin;
  24.         GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  25.         GPIO_InitStruct.Pull = GPIO_NOPULL;
  26.         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  27. }

  28. void IIC_Start(void)
  29. {
  30.         SDA_SET_OUT();
  31.         IIC_SDA = 1;
  32.         IIC_SCL = 1;
  33.         delay_us(5);
  34.         IIC_SDA = 0; //START:when CLK is high,DATA change form high to low
  35.         delay_us(6);
  36.         IIC_SCL = 0;
  37. }

  38. void IIC_Stop(void)
  39. {
  40.         SDA_SET_OUT();
  41.         IIC_SCL = 0;
  42.         IIC_SDA = 0; //STOP:when CLK is high DATA change form low to high
  43.         IIC_SCL = 1;
  44.         delay_us(6);
  45.         IIC_SDA = 1;
  46.         delay_us(6);
  47. }

  48. uint8_t IIC_Wait_Ack(void)
  49. {
  50.         uint8_t tempTime = 0;
  51.         IIC_SDA = 1;
  52.         delay_us(1);
  53.         SDA_SET_IN();
  54.         IIC_SCL = 1;
  55.         delay_us(1);
  56.         while (READ_SDA)
  57.         {
  58.                 tempTime++;
  59.                 if (tempTime > 250)
  60.                 {
  61.                         IIC_Stop();
  62.                         return 1;
  63.                 }
  64.         }
  65.         IIC_SCL = 0;
  66.         return 0;
  67. }

  68. void IIC_Ack(void)
  69. {
  70.         IIC_SCL = 0;
  71.         SDA_SET_OUT();
  72.         IIC_SDA = 0;
  73.         delay_us(2);
  74.         IIC_SCL = 1;
  75.         delay_us(5);
  76.         IIC_SCL = 0;
  77. }

  78. void IIC_NAck(void)
  79. {
  80.         IIC_SCL = 0;
  81.         SDA_SET_OUT();
  82.         IIC_SDA = 1;
  83.         delay_us(2);
  84.         IIC_SCL = 1;
  85.         delay_us(5);
  86.         IIC_SCL = 0;
  87. }

  88. void IIC_Send_Byte(uint8_t txd)
  89. {
  90.         uint8_t t;
  91.         SDA_SET_OUT();
  92.         IIC_SCL = 0;
  93.         for (t = 0; t < 8; t++)
  94.         {
  95.                 if ((txd & 0x80) > 0) //0x80  1000 0000
  96.                         IIC_SDA = 1;
  97.                 else
  98.                         IIC_SDA = 0;
  99.                 txd <<= 1;
  100.                 delay_us(2);
  101.                 IIC_SCL = 1;
  102.                 delay_us(2);
  103.                 IIC_SCL = 0;
  104.                 delay_us(2);
  105.         }
  106. }

  107. uint8_t IIC_Read_Byte(uint8_t ack)
  108. {
  109.         uint8_t i, receive = 0;
  110.         SDA_SET_IN();
  111.         for (i = 0; i < 8; i++ )
  112.         {
  113.                 IIC_SCL = 0;
  114.                 delay_us(2);
  115.                 IIC_SCL = 1;
  116.                 receive <<= 1;
  117.                 if (READ_SDA)receive++;
  118.                 delay_us(1);
  119.         }
  120.         if (!ack)
  121.                 IIC_NAck();
  122.         else
  123.                 IIC_Ack();
  124.         return receive;
  125. }

  126. void SD2405_Init(void)
  127. {
  128.         IIC_Init();
  129. }

  130. void SD2405_WriteOneByte(uint8_t WriteAddr, uint8_t Data)
  131. {
  132.         IIC_Start();
  133.         IIC_Send_Byte(0x64);
  134.         IIC_Wait_Ack();
  135.         IIC_Send_Byte(WriteAddr);
  136.         IIC_Wait_Ack();
  137.         IIC_Send_Byte(Data);
  138.         IIC_Wait_Ack();
  139.         IIC_Stop();
  140.         delay_ms(10);
  141. }

  142. uint8_t SD2405_ReadOneByte(uint8_t ReadAddr)
  143. {
  144.         uint8_t temp;
  145.         IIC_Start();
  146.         IIC_Send_Byte(0x64);
  147.         IIC_Wait_Ack();
  148.         IIC_Send_Byte(ReadAddr);
  149.         IIC_Wait_Ack();
  150.         IIC_Start();
  151.         IIC_Send_Byte(0x65);
  152.         IIC_Wait_Ack();
  153.         temp = IIC_Read_Byte(0);
  154.         IIC_Stop();
  155.         return temp;
  156. }

  157. /// 使能写
  158. void Write_On(void)
  159. {
  160.         SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x84);
  161.         SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x80);
  162. }

  163. /// 禁止写
  164. void Write_Off(void)
  165. {
  166.         SD2405_WriteOneByte(SD2405_ADDR_CTR1, 0x00);
  167.         SD2405_WriteOneByte(SD2405_ADDR_CTR2, 0x52);
  168. }

  169. /// 写入时间
  170. void SD2405_Write_Time(SD2405_DateTypedef* date)
  171. {
  172.         Write_On();
  173.         SD2405_WriteOneByte(SD2405_ADDR_YEAR,   UChar2BCD(date->year - 2000));
  174.         SD2405_WriteOneByte(SD2405_ADDR_MONTH,  UChar2BCD(date->month));
  175.         SD2405_WriteOneByte(SD2405_ADDR_DAY,    UChar2BCD(date->day));
  176.         SD2405_WriteOneByte(SD2405_ADDR_HOUR,   UChar2BCD(date->hour) | 0X80);  /* 24小时制 */
  177.         SD2405_WriteOneByte(SD2405_ADDR_MINUTE, UChar2BCD(date->minute));
  178.         SD2405_WriteOneByte(SD2405_ADDR_SECOND, UChar2BCD(date->second));
  179.         SD2405_WriteOneByte(SD2405_ADDR_WEEK,   UChar2BCD(date->week));
  180.         Write_Off();
  181. }

  182. /// 读取时间
  183. SD2405_DateTypedef* SD2405_Read_Time(void)
  184. {
  185.         static SD2405_DateTypedef time;
  186.         memset(&time, 0X00, sizeof(SD2405_DateTypedef));
  187.         time.year   = SD2405_ReadOneByte(SD2405_ADDR_YEAR);
  188.         time.month  = SD2405_ReadOneByte(SD2405_ADDR_MONTH);
  189.         time.day    = SD2405_ReadOneByte(SD2405_ADDR_DAY);
  190.         time.hour   = SD2405_ReadOneByte(SD2405_ADDR_HOUR);
  191.         time.minute = SD2405_ReadOneByte(SD2405_ADDR_MINUTE);
  192.         time.second = SD2405_ReadOneByte(SD2405_ADDR_SECOND);
  193.         time.week   = SD2405_ReadOneByte(SD2405_ADDR_WEEK);
  194.         time.year   = BCD2UChar(time.year) + 2000;
  195.         time.month  = BCD2UChar(time.month);
  196.         time.day    = BCD2UChar(time.day);
  197.         time.hour   = BCD2UChar(time.hour & 0X7F);
  198.         time.second = BCD2UChar(time.second);
  199.         time.minute = BCD2UChar(time.minute);
  200.         time.week   = BCD2UChar(time.week);
  201.         return &time;
  202. }

复制代码



收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版