搜索
查看: 1412|回复: 4

[原创] 【STM32G4 NUCLEO G431RB】+ I2C通讯终于完成

[复制链接]

该用户从未签到

26

主题

1127

帖子

59

蝴蝶豆

论坛元老

最后登录
2021-7-29
发表于 2019-9-20 21:19:02 | 显示全部楼层 |阅读模式
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:
I2C_Bus_Ok.jpg

    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
  1. /******************************************************************************************
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)
  3. * 功能说明: 写数据到DS1307
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误
  6. ******************************************************************************************/
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
  8. {
  9.     uint8_t addr = 0;
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
  12.        
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
  14.     {
  15.         return 1;
  16.     }
  17.         return 0;
  18. }

  19. /******************************************************************************************
  20. * 函数名称: DS1307_I2C_Receive(uint8_t size)
  21. * 功能说明: 从DS1307读出数据
  22. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)
  23. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
  24. ******************************************************************************************/
  25. uint8_t DS1307_I2C_Receive(uint8_t size)
  26. {
  27.         uint8_t addr = 0;
  28.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
  29.        
  30.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
  31.     {
  32.         return 1;
  33.     }
  34.     if(size == 1){               //检查DS1307是否需要初始化
  35.                 if(DS_Buff[0]>127){
  36.             year = 2019;
  37.                     month = 9;
  38.                     day = 18;
  39.                     week = 3;
  40.                     hour = 9;
  41.                     minute = 1;
  42.                
  43.             DS1307_DataToBuff();
  44.                         DS1307_I2C_Transmit(8);
  45.                 }
  46.         }
  47.         else{
  48.             DS1307_BuffToData();
  49.     }
  50.         return 0;       
  51. }
  52.                  
  53. /******************************************************************************************
  54. * 函数名称: DS1307_I2C_Read()
  55. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
  56. * 输    入: 无
  57. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误
  58. ******************************************************************************************/
  59. void DS1307_I2C_Read(void)
  60. {

  61.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
  62. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
  63.     {
  64.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  65.         {
  66.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");
  67.         }
  68.     }

  69.         DS1307_BuffToData();
  70.        
  71. }

  72. /******************************************************************************************
  73. * 函数名称: DS1307_I2C_Write()
  74. * 功能说明: 将当前的日历数据写入DS1307
  75. * 输    入: 无
  76. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误
  77. ******************************************************************************************/
  78. void DS1307_I2C_Write(void)
  79. {
  80.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中
  81.        
  82.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
  83. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
  84.     {
  85.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  86.         {
  87.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
  88. //                        return 2;
  89.         }
  90.     }
  91. //        return 0;
  92. }

  93. /******************************************************************************************
  94. * 函数名称: DS1307_Chick()
  95. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
  96. * 输    入: 无
  97. * 输    出: 无
  98. ******************************************************************************************/
  99. void DS1307_Check(void)
  100. {

  101. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");
  102.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
  103.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)
  104.     {
  105.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  106.                 {
  107.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
  108.                 }
  109.         }
  110.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
  111.         if(DS_Buff[0]> 127){
  112.         year = 2019;
  113.                 month = 9;
  114.                 day = 18;
  115.                 week = 3;
  116.                 hour = 9;
  117.                 minute = 1;
  118.                
  119.         DS1307_DataToBuff();

  120.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
  121. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
  122.         {
  123.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  124.             {
  125.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");
  126.             }
  127.         }
  128.         }
  129. }

  130. /******************************************************************************************
  131. * 函数名称: DS1307_DataToBuff()
  132. * 功能说明: 将时间日期变量数据转换到数组Buff中
  133. * 输    入: 无
  134. * 输    出: 无
  135. ******************************************************************************************/
  136. void DS1307_DataToBuff(void)
  137. {
  138.     uint8_t temp;
  139.         DS_Buff[0] = 0;                  //秒
  140.     temp = ((minute/10)<<4|(minute%10));
  141.     DS_Buff[1] = temp;               //分
  142.     temp = ((hour/10)<<4|(hour%10));
  143.     DS_Buff[2] = temp;               //时

  144.     DS_Buff[3] = week;               //星期

  145.     temp = ((day/10)<<4|(day%10));
  146.     DS_Buff[4] = temp;               //日
  147.     temp = ((month/10)<<4|(month%10));
  148.     DS_Buff[5] = temp;               //月
  149.     temp = ((year%100)/10<<4|(year%10));
  150.     DS_Buff[6] = temp;               //年
  151.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
  152. }


  153. /******************************************************************************************
  154. * 函数名称: DS1307_BuffToData()
  155. * 功能说明: 将数组Buff数据转换到时间日期变量中
  156. * 输    入: 无
  157. * 输    出: 无
  158. ******************************************************************************************/
  159. void DS1307_BuffToData(void)
  160. {
  161.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
  162.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
  163.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
  164.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
  165.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
  166.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
  167.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
  168. }

  169. /******************************************************************************************
  170. * 函数名称: AT24C32_I2C_Read()
  171. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)
  172. * 输    入: adrr(起始地址),size(读取的字节长度)
  173. * 输    出: 无
  174. ******************************************************************************************/
  175. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)
  176. {

  177.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
  178.     {
  179.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  180.         {
  181.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");
  182.         }
  183.     }

  184. }

  185. /******************************************************************************************
  186. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
  187. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
  188. * 输    入: adrr(起始地址),size(写入的字节长度)
  189. * 输    出: 无
  190. ******************************************************************************************/
  191. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
  192. {
  193.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
  194.     {
  195.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
  196.         {
  197.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
  198.         }
  199.     }

  200. }
复制代码





回复

使用道具 举报

该用户从未签到

3

主题

140

帖子

0

蝴蝶豆

高级会员

最后登录
2021-4-21
发表于 2019-9-22 22:01:27 | 显示全部楼层
DS1307和DS1302区别大吗?
回复 支持 反对

使用道具 举报

该用户从未签到

26

主题

1127

帖子

59

蝴蝶豆

论坛元老

最后登录
2021-7-29
 楼主| 发表于 2019-9-23 12:10:18 | 显示全部楼层
有区别,DS1307要依靠器件地址来选定,也就是说可以挂在标准的I2C总线上使用,而DS1302则不需要器件地址,直接发送要操作的内存(寄存器)地址就行,按我的理解就是在这个总线上只能一个器件。
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

8

帖子

0

蝴蝶豆

新手上路

最后登录
2021-1-15
发表于 2019-9-23 13:50:32 | 显示全部楼层
顶一下~~!
回复

使用道具 举报

该用户从未签到

0

主题

6

帖子

0

蝴蝶豆

新手上路

最后登录
2019-11-17
发表于 2019-11-16 12:08:07 | 显示全部楼层
您好,能给我发一下G4的pack吗?官网下载老是提示错误,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-25 13:18 , Processed in 0.163134 second(s), 36 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表