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

HAL库的I2C模块函数库改造

[复制链接]
shiyongzhu 发布时间:2015-8-14 14:10
本帖最后由 shiyongzhu 于 2015-8-14 14:55 编辑

STHAL库的I2C模块函数库中提供了大量的函数,方便了用户的使用。近期由于需要使用下I2C接口,对HAL库中的函数以及相关的例程进行了一下研究,发现当mcu处于从机的时候,其提供的函数只能满足从机处于接收或者发送状态之一(本人观点,欢迎指正),当主机既需要对从机既需要读又需要写时,特别的不方便。为此本人对HAL库中的I2C进行了一下改造,使其处于从机时收发皆可。
主要的思想是开启地址匹配中断,主机对从机进行读或写时进入该中断后,在中断中读取状态寄存器ISR,看主机是读还是写,然后分别进入相关的子程序即可。 捕获.JPG
具体实现以stm32f072为例,初始化,注意开启中断:
  1. void MX_I2C1_Init(void)
  2. {

  3.   hi2c1.Instance = I2C1;
  4. //  hi2c1.Init.Timing = 0x00700000;                                                                                                        //1MHz,100ns,100ns,slave
  5.         hi2c1.Init.Timing = 0x00900000;                                                                                                                //400kHz,10ns,10ns,slave
  6.   hi2c1.Init.OwnAddress1 = ADDRESS;                                                                                                //µçµ÷µØÖ·
  7.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;                // µØÖ·Îª7λ
  8.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
  9.   hi2c1.Init.OwnAddress2 = 0;
  10.   hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  11.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
  12.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
  13.   HAL_I2C_Init(&hi2c1);

  14.     /**Configure Analogue filter
  15.     */
  16.   HAL_I2CEx_AnalogFilter_Config(&hi2c1, I2C_ANALOGFILTER_ENABLED);
  17.        
  18.         HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);                //i2c1
  19.   HAL_NVIC_EnableIRQ(I2C1_IRQn);
  20. }
复制代码

然后写I2C中断服务函数void I2C1_IRQHandler(),具体程序如下
  1. void I2C1_IRQHandler(void)
  2. {
  3.   if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
  4.     HAL_I2C_ER_IRQHandler(&hi2c1);
  5.   } else {
  6.     HAL_I2C_EV_IRQHandler(&hi2c1);
  7.   }
  8. }
复制代码

具体干活的程序如下,本处对原有的函数库进行了改造
  1. void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
  2. {
  3. if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) && (__HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ADDRI) == SET))
  4.   {
  5.                 HAL_I2C_SlaveRxTxCallback(hi2c);
  6.   }
  7.        
  8. }
复制代码

HAL_I2C_SlaveRxTxCallback(hi2c)为自己写的函数,具体如下
  1. void HAL_I2C_SlaveRxTxCallback(I2C_HandleTypeDef *hi2c)               
  2. {
  3.         if(hi2c->Instance==I2C1)
  4.         {
  5.                  /* Slave mode selected */
  6.     if (hi2c->State == HAL_I2C_STATE_READY)
  7.     {
  8.       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); // ÇåÖжÏ
  9.                         if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DIR))                // ÊÕ·¢·½Ïò
  10.                         {
  11. HAL_I2C_Slave_Transmit_DMA_NEW(hi2c,(uint8_t*)i2c1_tx_buffer, sizeof(i2c1_tx_buffer));
  12.                         }
  13.                         else
  14.                         {
  15. HAL_I2C_Slave_Receive_DMA_NEW(hi2c,(uint8_t*)i2c1_rx_buffer, sizeof(i2c1_rx_buffer));
  16.                         }
  17.     }
  18.         }

  19. }
复制代码

上面函数中的函数:
HAL_I2C_Slave_Transmit_DMA_NEW(hi2c,(uint8_t*)i2c1_tx_buffer,sizeof(i2c1_tx_buffer))
HAL_I2C_Slave_Receive_DMA_NEW(hi2c,(uint8_t*)i2c1_rx_buffer,sizeof(i2c1_rx_buffer));
HAL_I2C_Slave_Transmit_DMAHAL_I2C_Slave_Receive_DMA_NEW的改造,删除了原有函数中的地址匹配和方向判断的内容。

使用时,只要开启地址匹配中断一切就OK了
  1. __HAL_I2C_ENABLE_IT(&hi2c1,I2C_IT_ADDRI);
复制代码



收藏 5 评论17 发布时间:2015-8-14 14:10

举报

17个回答
沐紫 回答时间:2015-8-14 14:47:11
谢谢楼主

楼主在编辑帖子的时候,右上角有个添加代码文字按钮,用来放代码特别好用 QQ截图20150814144826.jpg
shiyongzhu 回答时间:2015-8-14 14:55:51
沐紫 发表于 2015-8-14 14:47
谢谢楼主

楼主在编辑帖子的时候,右上角有个添加代码文字按钮,用来放代码特别好用 ...

谢谢沐紫,用了下效果好很多!
苏柚 回答时间:2015-8-14 16:39:27
看来楼主也是大牛啊
Paderboy 回答时间:2015-8-14 17:53:04
多谢楼主,学习了。。
党国特派员 回答时间:2015-8-16 14:07:36
多谢楼主,学习了。。
wambob 回答时间:2015-8-17 19:52:34
学习下的经验楼主
数码小叶 回答时间:2015-8-18 16:39:03
多谢楼主,学习了。。
微雪电子 回答时间:2017-2-8 10:44:53
楼主有工程源码吗、可否发给我看下,最新一直在弄i2c 从模式。
草民星空 回答时间:2017-2-10 13:49:22
学习学习
12下一页

所属标签

STM32团队

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


最新内容

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