打印

调试STM32 I2C过程中碰到的问题

[复制链接]
5358|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wugb|  楼主 | 2007-11-5 08:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好:
    有没有人用过STM32 I2C作为Master。
1.我发现在一些操作后,比较发送一组数据后,经常地RNE位会自动变为1,导致后续的状态判断不对。贴一段代码:
  /* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

  /* Send RTC address for read */
  I2C_Send7bitAddress(I2C1, COMPANION_ADDRESS, I2C_Direction_Transmitter);

  /* Test on EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  
  /* Send the RTC internal address 0 */    
  I2C_SendData(I2C1, 0x00);  

  /* Test on EV8 and clear it */
  while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send the Read Time Command */    
  I2C_SendData(I2C1, RTC_READ_TIME);  

  /* Test on EV8 and clear it */
  while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send STOP condition */
  //I2C_GenerateSTOP(I2C1, ENABLE);


    
  /* Send START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
  
  /* 这里RNE位为1, 检查通不过 **********************/
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

呵呵,不知道有没有各位有没有碰到过!

2.它的接收控制不太好用,如果在接收处理流程中加中断,就不能正常操作I2C了,好奇怪的设计!

沙发
ST_ARM| | 2007-11-5 10:30 | 只看该作者

I2C的使用

1、/* 这里RNE位为1, 检查通不过 **********************/
  /* Test on EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

A:RNE位为1, 与检查I2C_EVENT_MASTER_MODE_SELECT通不过没有关系。此时RxNE肯定是1,你再检查一下。


2、它的接收控制不太好用,如果在接收处理流程中加中断,就不能正常操作I2C了,好奇怪的设计

A:“接收控制不太好用”,请问你是主模式下接收,还是从模式下接收?

使用特权

评论回复
板凳
wugb|  楼主 | 2007-11-5 16:38 | 只看该作者

I2C

1.请注意看
#define  I2C_EVENT_MASTER_MODE_SELECT  ((u32)0x00030001)  /* BUSY, MSL and SB flag */
#define I2C_FLAG_Mask           ((u32)0x00FFFFFF)

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, u32 I2C_EVENT)
{
  u32 LastEvent = 0;
  u32 Flag1 = 0, Flag2 = 0;
  ErrorStatus status = ERROR;

  /* Check the parameters */
  assert(IS_I2C_EVENT(I2C_EVENT));

  Flag1 = I2Cx->SR1;
  Flag2 = I2Cx->SR2;
  Flag2 = Flag2 << 16;

  /* Get the last event value from I2C status register */
  LastEvent = (Flag1 | Flag2) & I2C_FLAG_Mask;

  /* Check whether the last event is equal to I2C_EVENT */
  if (LastEvent == I2C_EVENT )
  {
    /* SUCCESS: last event is equal to I2C_EVENT */
    status = SUCCESS;
  }
  else
  {
    /* ERROR: last event is different from I2C_EVENT */
    status = ERROR;
  }

  /* Return status */
  return status;
}

RxNE为1时,SR.6为1,无论如何LastEvent.6为1,它是不可能等于I2C_EVENT_MASTER_MODE_SELECT(它的第6位为0)

2.在Master模式下接收,好像不能单步调试

使用特权

评论回复
地板
luckiest| | 2007-11-15 14:09 | 只看该作者

我I2C也有问题

我用STM32读铁电,仿照官方读M24C04的,稍有改动。
写没有问题,随机读取,第一遍OK,之后读写都不行了。。。调试器发现死在EV5的while()里。和楼主的情况相似,不过一直没搞清具体原因。
库函数里如下定义
/* EV5 */
#define  I2C_EVENT_MASTER_MODE_SELECT  ((u32)0x00030001)  /* BUSY, MSL and SB flag */
但是参考手册里写了这一句:
EV5: SB=1, cleared by reading SR1 register followed by writing DR register with Address.
是不是说只要写地址前读了SR1,就自动清了?

使用特权

评论回复
5
luckiest| | 2007-11-15 19:57 | 只看该作者

这下OK了~

我把Clear EV5那句改成了
while((((u32)(I2C1->SR2) << 16) | (u32)(I2C1->SR1) & 0x00FFFFBF) != I2C_EVENT_MASTER_MODE_SELECT); 
实际上就是把I2C_CheckEvent()里的Mask改了。现在程序OK了~~
谢谢楼主,要不是看到你这帖我都要写模拟I2C了~

我不太明白你所说的Master模式单步调试。这样单步调试,不影响I2C时序么?

使用特权

评论回复
6
mojingxian| | 2007-11-22 16:10 | 只看该作者

Re:谢谢楼主,要不是看到你这帖我都要写模拟I2C了~

我早用软件I2C了,之前一直没有调通,也是同样的问题,在check EV5死掉了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

8

帖子

1

粉丝