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

使用HAL库硬件I2C时如何设置器件地址?

[复制链接]
hujjj 提问时间:2019-9-18 15:32 /
阅读主题, 点击返回1楼
收藏 评论16 发布时间:2019-9-18 15:32
16个回答
回答时间:2019-9-19 15:37:31
可以选择地址的。第一次先写入硬件地址和读取地址。第二次直接读取数据长度即可。MEM这个函数我没有仔细的研究,我使用的函数操作过程有I2C开始、停止操作。
hujjj 回答时间:2019-9-19 17:25:57
安 发表于 2019-9-19 15:37
可以选择地址的。第一次先写入硬件地址和读取地址。第二次直接读取数据长度即可。MEM这个函数我没有仔细的 ...

我再测试看看。
hujjj 回答时间:2019-9-20 10:08:09
    经过测试,使用HAL_I2C_Mem_Write()和HAL_I2C_Mem_Read()函数对DS1307进行读写操作没有问题,而使用HAL_I2C_Transmit()和HAL_I2C_Master_Receive()函数对DS1307进行读写操作却不成功,似乎操作的数据地址不正确。我在测试时按照每分钟读取一次,分别使用不同的函数对同一DS1307器件读取日历数据,用HAL_I2C_Mem_Read()函数能读出正确的日期和时间,而用HAL_I2C_Master_Receive()函数读出的内容却是错误的,应该是读入了其他地址的数据。
    这是用HAL_I2C_Mem_Read()函数读取的日历数据(年份和时间):
I2C_ReadDS1307_0.jpg



    这是月日和时间:

I2C_ReadDS1307_1.jpg



    这是用HAL_I2C_Master_Receive()函数读出年份和时间:

I2C_ReadDS1307_2.jpg



    这是月日和时间:

I2C_ReadDS1307_3.jpg



    我按照版主的提示在读写操作前先写入要读写的地址,然后再进行读写操作,结果仍是不行,看来对用HAL_I2C_Master_Receive()和用HAL_I2C_Master_Transmit()这两个函数还尚未理解和掌握。下面是我测试时的代码:

  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.    
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,0,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.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,0,1,10000);//发送起始地址
  28.        
  29.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
  30.     {
  31.         return 1;
  32.     }
  33.     if(size == 1){               //检查DS1307是否需要初始化
  34.                 if(DS_Buff[0]>127){
  35.             year = 2019;
  36.                     month = 9;
  37.                     day = 18;
  38.                     week = 3;
  39.                     hour = 9;
  40.                     minute = 1;
  41.                
  42.             DS1307_DataToBuff();
  43.                         DS1307_I2C_Transmit(8);
  44.                 }
  45.         }
  46.         else{
  47.             DS1307_BuffToData();
  48.     }
  49.         return 0;       
  50. }
复制代码



回答时间:2019-9-20 10:20:58
我用到的时I2C1,楼主用的和我一样吗?楼主看一下你用的RTC的硬件地址是多少,是否和我的一致。1307读取出来的是BCD码,需要进行数据转换的。I2C操作入口时指针类型,需要注意一下。
hujjj 回答时间:2019-9-20 11:09:22
我的DS1307器件地址是0xD0,数据格式是BCD码,数组是定义为uint8_t,目前用HAL_I2C_Mem..函数能够正常读写,而且对AT24C32也能正常读写。但用HAL_I2C_Master..函数则读写出错,很可能是没有操控好读写的地址。
回答时间:2019-9-20 11:23:02
我怀疑时你写入的第一个数内容不对,你入口写0。你按照我给你的代码试试。入口用一个变量或者数组。
hujjj 回答时间:2019-9-20 12:25:12
安 发表于 2019-9-20 11:23
我怀疑时你写入的第一个数内容不对,你入口写0。你按照我给你的代码试试。入口用一个变量或者数组。 ...

    确实是这个问题,我改成变量之后就顺利地读出了正确数据,看来这个参数不能用常量。下面是修改后能正确运行的代码:
  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. }
复制代码


    终于实现了两种方法读取数据,再次表示感谢!
12

所属标签

相似问题

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