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

使用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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版