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

【NUCLEO-L476RG开发】硬件I2C 精华  

[复制链接]
netlhx 发布时间:2015-11-8 20:18
本帖最后由 netlhx 于 2015-11-8 20:35 编辑

NUCLEO-L476RG到手一段时间了,今天来测试一下硬件I2C的操作,听说很多BUG,试一试看如何。

准备用I2C来访问AT24C02 EEPROM,将数据写入到EEPROM中,然后再读取出来,验证读写操作的正确性。

硬件平台如下


NUCLEO-L476RG

nucleo-l476.png

前段时间FSL的KL02Z套装,上面的MINIDOCK扩展板上恰好有AT24C02,所以借过来用一下,FSL不要生气啊

minidock.png

标准的ARDUINO接口,放到哪都行。合体照。

test.png

硬件连接及原理图

MINI DOCI上的AT24C02连接

QQ截图20151108162714.png

ARDUINO接口:SCL及SDA

QQ截图20151108162724.png

NUCLEO-L476RG上对应的接口

nucleo-l476rg-review-16.jpg


写程序之前,要了解硬件的基本特性,首先是STM32L476RG上I2C接口支持的特性;其次是AT24C02的特性。

STM32L476RG的I2C功能框图如下

QQ截图20151108154725.png

值得一提的是,L4的I2C有自己独立的内核时钟,可以在SYSCLK、PCLK及HSI中任选一种做为I2C的内核时钟。另外L4的I2C支持三种不同的通信速率:100KHZ, 400KHZ,1MHZ。由于AT24C02只支持最高400KHZ,所以这里就选择400KHZ做为内核时钟。

创建I2C测试工程,建立过程略。几点要注意的地方。

首先,本例程中使用的是I2C1,对应的SCL及SDA引脚为PB8及PB9,时钟配置后SYSCLK为80MHZ。

I2C硬件配置参数如图

QQ截图20151108172523.png

速度有三种可选:标准,快速,快速加。另外针对不同的特定应用,可以选择设置上升和下降沿的时间,以纳秒为单位,范围为0-120纳秒之间。注意这个TIMING参数,是灰色的,CUBEMX自动计算并设置该值,不像以前的F0和F3系列,需要一个专门的工具来设置TIMING的值,够麻烦的。

下面是使用HAL库与EEPROM通信的主要代码。


  1. /* USER CODE BEGIN PV */
  2. /* Private variables ---------------------------------------------------------*/
  3. #define EEPROM_ADDRESS        0xA0
  4. #define EEPROM_PAGESIZE        0x11
  5. #define EEPROM_TIMEOUT        1000

  6. extern I2C_HandleTypeDef hi2c1;

  7. char msg[] = "This is a test!\r\n";

  8. char buf[40];

  9. int16_t Remaining_Bytes;
  10. uint16_t Memory_Address;

  11. uint16_t len;

  12. ......

  13. //write msg to eeprom
  14. Remaining_Bytes = strlen(msg);
  15. Memory_Address = 0;
  16.         
  17. while(Remaining_Bytes > 0)
  18. {
  19.       if(HAL_I2C_Mem_Write_DMA(&hi2c1, EEPROM_ADDRESS, Memory_Address, I2C_MEMADD_SIZE_8BIT, (uint8_t *)(msg + Memory_Address), EEPROM_PAGESIZE) != HAL_OK)
  20.       {
  21.               Error_Handler();
  22.                         
  23.        }
  24.                
  25.        while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  26.        {
  27.        }
  28.                
  29.        while (HAL_I2C_IsDeviceReady(&hi2c1, EEPROM_ADDRESS, 10, 300) == HAL_TIMEOUT);
  30.                
  31.        while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  32.         {
  33.         }
  34.                
  35.          Remaining_Bytes -= EEPROM_PAGESIZE;
  36.                
  37.          Memory_Address += EEPROM_PAGESIZE;
  38.         }
  39.         
  40. //read msg to buff

  41.   if(HAL_I2C_Mem_Read_DMA(&hi2c1 , EEPROM_ADDRESS, 0, I2C_MEMADD_SIZE_8BIT, (uint8_t*)buf, strlen(msg))!= HAL_OK)
  42.   {
  43.     /* Reading process Error */
  44.     Error_Handler();        
  45.   }
  46.   
  47.   /* Wait for the end of the transfer */  
  48.   while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
  49.   {
  50.   }
  51.         
复制代码

根据STD库中用户的反馈,I2C出错的原因主要由几方面造成,一是ST设计的I2C接口,通信过程中一些状态变量及标志位的设置非常严格,如果程序逻辑考虑不周全,会导致I2C停止工作,需要软复位后才能继续;另一方面,I2C接口在处理单个,双字节及多字节传输过程中要分开考虑,进一步将问题复杂化了;还有就是结合具体的I2C设备,不同的时序要求,进一步复杂化了通信过程。

这些问题在HAL库中都得到了很好的解决,为此,HAL库中设计了几种不同类型的API函数供调用。一类是通用的接收和发送函数,这类API函数将I2C接口视为类似于“流对象”,通信时从流对象中接收或发送数据;另一类则是类似于EEPROM之类的特殊存储对象,从这些存储对象中接收或发送数据时,都需要提供一个地址,以便准确定位。使用EEPROM来实验时,我们使用的是第二类API函数。两个主要的API函数原型及参数如下。

  1. /**
  2.   * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
  3.   * @param  hi2c : Pointer to a I2C_HandleTypeDef structure that contains
  4.   *                the configuration information for the specified I2C.
  5.   * @param  DevAddress: Target device address
  6.   * @param  pData: Pointer to data buffer
  7.   * @param  Size: Amount of data to be sent
  8.   * @retval HAL status
  9.   */
  10. HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
复制代码
  1. /**
  2.   * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
  3.   * @param  hi2c : Pointer to a I2C_HandleTypeDef structure that contains
  4.   *                the configuration information for the specified I2C.
  5.   * @param  DevAddress: Target device address
  6.   * @param  MemAddress: Internal memory address
  7.   * @param  MemAddSize: Size of internal memory address
  8.   * @param  pData: Pointer to data buffer
  9.   * @param  Size: Amount of data to be read
  10.   * @retval HAL status
  11.   */
  12. HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
复制代码

关于这两个函数的更详细的调用方法及说明,请参考API文档。

注意在具体操作EEPROM的时候,还要注意,EEPROM分字节读写及页面读写两种类型,对HAL API的调用还要进行适当的修改。

由于ST HAL API做了大量的后台工作,上面的代码看起来过于简单了。但实际上API函数在后台做了大量的工作,这不正是我们期待的么!

最后来看看运行结果。

UART打印的写入及读取取结果

QQ截图20151108200641.png

逻辑分析仪LA

无标题.png

I2C通信全程,LA分析结果

QQ截图20151108200233.png

开始通信,顺序依次是开始信号,地址,EEPROM写入地址,第一个数据字节

QQ截图20151108200331.png

字符0x0D, 0x0A, 结束信号。

QQ截图20151108200410.png

接收开始,顺序依次是开始信号,地址,EEPROM读取地址,第一个数据字节

QQ截图20151108200439.png

读取结束

QQ截图20151108200502.png



附工程

eeprom.zip (3.17 MB, 下载次数: 201)
收藏 5 评论20 发布时间:2015-11-8 20:18

举报

20个回答
lulongqin 回答时间:2016-5-8 23:06:50
楼主,您好,我利用您的代码测试失败,串口只发送了“Write to EEPROM:和This is a test!”,经测试,程序在运行        这部分是发生错误:        if(HAL_I2C_Mem_Write_DMA(&hi2c1, EEPROM_ADDRESS, Memory_Address, I2C_MEMADD_SIZE_8BIT, (uint8_t *)(msg + Memory_Address), EEPROM_PAGESIZE) != HAL_OK)
                {
                        Error_Handler();
        };程序直接进入Error_Handler()函数,请问是什么原因呢?我检查了很多地方,还是不行,求指教,非常感谢!(测试环境stm32l476rg+at24c02,后来用了at24c16测试还是失败)
Inc_brza 回答时间:2015-11-9 00:43:23
对比过硬件IIC和模拟IIC,硬件的IIC直接被模拟IIC给打爆!
1、移植,直接秒杀不用多说
2、效率,IIC的硬件通讯过程中用了太多的访问标志位,实际效率不会增加,一样是让CPU在耗,
              所以,效率反而没有模拟IIC高,因为GPIO的反转速率轻松满足IIC的通信速率,所以
              模拟IIC照样更胜1筹。
3、复杂性,ST的通病,反而模拟IIC更加把协议变得很直观。
纵上所述,感觉这个硬件IIC就是个鸡肋。
埃斯提爱慕 回答时间:2015-11-9 21:27:00
提示: 作者被禁止或删除 内容自动屏蔽
陈金华 回答时间:2015-11-8 20:26:37
沙发                     
netlhx 回答时间:2015-11-8 20:28:17
地板
qianfan 回答时间:2015-11-8 20:42:46
这个逻辑分析仪是啥牌子的?多少M?那个打标线不错。。。
Paderboy 回答时间:2015-11-8 20:57:26
多谢分享啊。。。。
2958155267 回答时间:2015-11-8 21:06:47
Hal库把底层都写好了,所以硬件i2c还是较简单的
kingsings 回答时间:2015-11-8 22:56:32
楼主好牛,两个板子都有了。而且还有逻辑分析仪
alvin_ 回答时间:2015-11-9 08:41:14
逻辑分析仪自己买的吗大神总是一鸣惊人啊
黄小狼 回答时间:2015-11-9 08:51:37
前来学习观战中。。。
奋斗逼 回答时间:2015-11-9 09:01:57
强大
戏如人生 回答时间:2015-11-9 09:05:51
逻辑分析仪都用上了啊??多少钱啊
watershade 回答时间:2015-11-9 15:24:45
楼主的逻辑分析仪花了多少钱?便宜的话推荐一下吧
aabird 回答时间:2015-11-9 16:52:41
这个厉害,虽然IIC很多人都觉得不好用
netlhx 回答时间:2015-11-9 18:40:19
QianFan 发表于 2015-11-8 20:42
这个逻辑分析仪是啥牌子的?多少M?那个打标线不错。。。

梦源的牌子吧,100M
12下一页

所属标签

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