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

【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, 下载次数: 195)
收藏 5 评论20 发布时间:2015-11-8 20:18

举报

20个回答
DAHAIGE-355079 回答时间: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
楼主好牛,两个板子都有了。而且还有逻辑分析仪
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就是个鸡肋。
alvin_ 回答时间:2015-11-9 08:41:14
逻辑分析仪自己买的吗大神总是一鸣惊人啊
黄小狼 回答时间:2015-11-9 08:51:37
前来学习观战中。。。
123下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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