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

查看: 5607|回复: 13

[STM32L476] 【NUCLEO-L476RG开发】STM32L4首秀之开发笔记,I2C总线解锁

[复制链接]

11

主题

1139

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-7-10
发表于 2015-11-20 23:47:09 | 显示全部楼层 |阅读模式
最近正在使用一个加速度传感器做设计,正好赶上论坛搞活动,有幸抢到一块STM32L4的板子,今天写一篇开发笔记,分享一下开发心得。如果处理器正在与I2C总线的器件通讯时,处理器异常复位(例如在线调试reset),那么I2C从器件未跑完要求的输出时序,从而异常锁死IC2总线的SDA,此时问题表现为总线一直为busy,只能断电复位才可正常工作。
解决思路为,让从器件跑完他该有的时序,自然释放SDA,那么每次复位初始化时,不能直接初始化处理器的I2C外设,而是要先查询SDA是否处于锁死状态,不多说,先上图。
先秀一下开发板哈,我看大家对此很热衷
a1.jpg
下面是连接,使用I2C1的PB6,PB7
a2.jpg
现在都进入懒人模式了,有了STM32CUBE还是很方便的,首先要PB6,PB7进入GPIO OC模式,下图为GPIO模式截图
1.jpg
2.jpg
查询I2C总线是否占用,如果占用则解锁,解锁后进入I2C初始化函数(代码在最后)。下图为I2C cube 截图
3.jpg
4.jpg


下面通过代码简述流程
//首先初始化PB6,PB7为集电极开路的输出状态,注意此时不能初始化I2C外设//
//因为一旦初始化了I2C外设,PB6,PB7就不跟你玩了,直接被I2C接管了//
////以下是MX_GPIO_Init()的内容////////////////////////////////////////////////
  GPIO_InitTypeDef GPIO_InitStruct;
  /* GPIO Ports Clock Enable */
  __GPIOB_CLK_ENABLE();
  /*Configure GPIO pins : PB6 PB7 */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_PB6);
  HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_PB7);
////////////////////////初始化完GPIO模式/////////////////////////////////////////////////////
HAL_GPIO_WritePin(GPIOB,GPIO_Pin_6,GPIO_PIN_SET);        //置PB6为集电极开路状态,外部上拉电阻高电平//
HAL_GPIO_WritePin(GPIOB,GPIO_Pin_7,GPIO_PIN_SET);        //置PB7为集电极开路状态,外部上拉电阻高电平//
unsigned char timeout=0;                                //防止解锁失败导致程序锁死的循环变量//
//下面这个循环不断在SCL送出时钟,直到I2C从器件退出输出状态,即释放I2C SDA总线//
while(HAL_GPIO_ReadPin(GPIOB,GPIO_Pin_7)== GPIO_PIN_RESET)        
{
        HAL_GPIO_WritePin(GPIOB,GPIO_Pin_6,GPIO_PIN_SET);        //SCL输出时钟//
        delay_us(100);
        HAL_GPIO_WritePin(GPIOB,GPIO_Pin_6,GPIO_PIN_RESET);
        delay_us(100);
        timeout++;
        if(timeout==0)
        {
            //失败//
             break;
         }        
}        
/////////////////////////////////////////////////////////////////////////////
///////////////////I2C从器件释放总线后,正式进入I2C外设初始化函数////////////
MX_I2C1_Init();
//可以访问I2C器件了//
.
.
.
.
////////////////////////////////////////////////////////////////////////////////


////////下面函数为cube生成的I2C1初始化代码,根据需要自己改/////////
void MX_I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00000000;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
  HAL_I2C_Init(&hi2c1);
    /**Configure Analogue filter
    */
  HAL_I2CEx_AnalogFilter_Config(&hi2c1, I2C_ANALOGFILTER_ENABLED);
}



小结:I2C总线被从器件锁死的原因比较多,这只是我在开发中遇到的一种情况,希望对朋友们有用。



















评分

参与人数 1ST金币 +30 收起 理由
沐紫 + 30

查看全部评分

<
回复

使用道具 举报

1

主题

629

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-3-7
发表于 2015-11-21 09:02:27 | 显示全部楼层
谢谢分享               
回复 支持 反对

使用道具 举报

7

主题

311

回帖

0

蝴蝶豆

高级会员

最后登录
2016-3-23
发表于 2015-11-21 10:19:18 | 显示全部楼层
楼主能不能分享个工程文件呀?另外,我有点疑问是,既然断电重新上电即可,还这么费事干嘛呢?重新烧写程序?这不比断电更麻烦吗?还是我没理解呢?
回复 支持 反对

使用道具 举报

11

主题

1139

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-7-10
 楼主| 发表于 2015-11-21 10:46:44 | 显示全部楼层
jiaswang 发表于 2015-11-21 10:19
楼主能不能分享个工程文件呀?另外,我有点疑问是,既然断电重新上电即可,还这么费事干嘛呢?重新烧写程序 ...

因为仿真时,电路板的电源是atlink供给的,不想总是插拔,再者,实际产品中通常有处理器复位按键,你不希望按了一下复位键后,设备失控了吧。
回复 支持 反对

使用道具 举报

47

主题

3404

回帖

30

蝴蝶豆

版主

最后登录
2020-12-7
发表于 2015-11-21 10:48:23 | 显示全部楼层
这个不错,i2c被意外锁死,。。就会出现。无法使用的情况。。
STMCU-Logo.png
回复 支持 反对

使用道具 举报

7

主题

311

回帖

0

蝴蝶豆

高级会员

最后登录
2016-3-23
发表于 2015-11-21 13:36:01 | 显示全部楼层
peter001 发表于 2015-11-21 10:46
因为仿真时,电路板的电源是atlink供给的,不想总是插拔,再者,实际产品中通常有处理器复位按键,你不希 ...

原来如此……工程文件能分享下吗?
回复 支持 反对

使用道具 举报

41

主题

2476

回帖

282

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2015-11-22 22:28:41 | 显示全部楼层
顶一下            
回复 支持 反对

使用道具 举报

89

主题

127

回帖

0

蝴蝶豆

高级会员

最后登录
2016-7-26
发表于 2015-11-23 09:20:05 | 显示全部楼层
锁死是啥意思。。。不好意思。。。我刚学的。。
回复 支持 反对

使用道具 举报

1

主题

7

回帖

0

蝴蝶豆

初级会员

最后登录
2018-8-10
发表于 2015-12-2 09:24:39 | 显示全部楼层
STM32F1经常跑死在I2C也是这个原因吗?
回复 支持 反对

使用道具 举报

11

主题

1139

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-7-10
 楼主| 发表于 2015-12-2 17:39:30 | 显示全部楼层
ghostxdy 发表于 2015-12-2 09:24
STM32F1经常跑死在I2C也是这个原因吗?

不完全是,很多时候是时序问题
回复 支持 反对

使用道具 举报

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