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

查看: 5600|回复: 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管理
行使您的权利
官方最新发布
13245底部标题123相同标题
12底部标题123相同标题
33333底部标题123相同序号
3435底部标题-无链接
关注我们
st-img 微信公众号
st-img 手机版