打印

stm32的i2c

[复制链接]
2198|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lonely8122|  楼主 | 2009-5-13 15:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家有没有觉得STM32的I2C有比较严重的问题?SR1和SR2的值经常莫名的变,还有连续读写也会有问题,这里说的连续读写不是指24cxx的页读写,而是说,我如果先读10个字节,然后发停止位,后面跟着又读10个字节,就会失败了。请有使用经验的人指点,谢谢,下面是我的读写24c256的程序,请大家帮忙分析:
/*****************************************************************************
*    函数名:read_24cxx
*    参数:读缓冲区:read_buff,读操作其始地址:read_address 读字节数量:num
*    返回:操作的结果
*
******************************************************************************/
INT8U read_24cxx(INT8U *read_buff , INT16U read_address, INT8U length)
{
  INT32U i, wait_timer;
  INT8U address_8bit;
  if((I2C1->SR1&0x0040)!=0) i=I2C1->DR;  //清除SR1里的RXNE位,这一位经常无故置位
  wait_timer=0xffff;
  // Send I2C1 START condition 
  I2C_GenerateSTART(I2C1, ENABLE);
  // Test on I2C1 EV5 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer))  wait_timer--;  
  if(wait_timer==0) return TIME_OUT;
  
  wait_timer=0xffff;
  // Send I2C2 slave Address for write
  I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Transmitter);
  // Test on I2C1 EV6 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(wait_timer))  wait_timer--; 
  if(wait_timer==0) return TIME_OUT;
  
  wait_timer=0xffff;
  address_8bit = (INT8U)(read_address>>8);
  I2C_SendData(I2C1, address_8bit);       //send the writing address.
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer))  wait_timer--;
  if(wait_timer==0) return TIME_OUT;
  
  wait_timer=0xffff;
  address_8bit = (INT8U)(read_address);
  I2C_SendData(I2C1, address_8bit);       //send the writing address.
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer))  wait_timer--;
  if(wait_timer==0) return TIME_OUT;

  wait_timer=0xffff;
  I2C_GenerateSTART(I2C1, ENABLE);
  // Test on I2C1 EV5 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer))  wait_timer--;  
  if(wait_timer==0) return TIME_OUT;
   // Send I2C2 slave Address for write
  
  wait_timer=0xffff;
  I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Receiver);
  // Test on I2C1 EV6 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))&&(wait_timer))  wait_timer--; 
  if(wait_timer==0) return TIME_OUT;
  
    for(i=0;i<length;i++)
  { 
    wait_timer=0xffff;
    while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))&&(wait_timer)) wait_timer--;
    if(wait_timer==0) break;
    else  
    { 
      read_buff=I2C_ReceiveData(I2C1);
    }
  }  
  
    // Send I2C1 STOP Condition 
 I2C_GenerateSTOP(I2C1, ENABLE); 

  if(wait_timer==0)  return TIME_OUT;
  else  return NO_ERROR;
}


/*****************************************************************************
*    函数名:write_24cxx
*    参数:写缓冲区:write_buff,读操作其始地址:write_address 读字节数量:num(<=64)
*    返回:操作的结果
*
******************************************************************************/
INT8U write_24cxx(INT8U * write_buff, INT16U write_address, INT8U length)
{
  INT32U i, wait_timer;
  INT8U address_8bit;
  if(length>64)  return  QUANTITY_OVERRUN;   //写入数量超过一页(64byte)
  
  EN_24C_WRITE;                   //关闭写保护
  
  I2C_EE_WaitEepromStandbyState();    //等待E2准备好
  
  wait_timer=0xffff;
  // Send I2C1 START condition
  I2C_GenerateSTART(I2C1, ENABLE);
  // Test on I2C1 EV5 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))&&(wait_timer))  wait_timer--;  
  if(wait_timer==0) 
  {
    DIS_24C_WRITE;       //恢复写保护
    return TIME_OUT;
  }
  wait_timer=0xffff;
  // Send I2C2 slave Address for write 
  I2C_Send7bitAddress(I2C1, __24C_SLAVE1_ADDRESS7, I2C_Direction_Transmitter);
  // Test on I2C1 EV6 and clear it 
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(wait_timer))  wait_timer--; 
  if(wait_timer==0) 
  {
    DIS_24C_WRITE;
    return TIME_OUT;
  }
  
  wait_timer=0xffff;
  address_8bit = (INT8U)(write_address>>8);
  I2C_SendData(I2C1, address_8bit);       //send the writing address.
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer))  wait_timer--;
  if(wait_timer==0) 
  {
    DIS_24C_WRITE;
    return TIME_OUT;
  }
  
  wait_timer=0xffff;
  address_8bit = (INT8U)(write_address);
  I2C_SendData(I2C1, address_8bit);       //send the writing address.
  while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer))  wait_timer--;
  if(wait_timer==0) 
  {
    DIS_24C_WRITE;
    return TIME_OUT;
  }
  for(i=0;i<length;i++)
  {
    wait_timer=0xffff;
    I2C_SendData(I2C1, write_buff);
    while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(wait_timer))  wait_timer--;
    if(wait_timer==0) break;
  }
  
      // Send I2C1 STOP Condition 
  I2C_GenerateSTOP(I2C1, ENABLE);
  OSTimeDly(5);           //延时等待器件内部写操作结束
  DIS_24C_WRITE;           //恢复写保护 
  if(wait_timer==0)  return TIME_OUT;
  else return NO_ERROR;
  
}
沙发
lut1lut| | 2009-5-13 17:22 | 只看该作者

置顶帖子有个I2C读写的可以供参考

那个查询方式的,很多人用过了,你可以先比较一下,找找自己的问题。

使用特权

评论回复
板凳
dragonbch| | 2009-12-29 13:35 | 只看该作者
初始化后第一次是主写,可是就是就是在EV5那个循环内出不来,咋整呢?高手指点,我都急死了。

使用特权

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

本版积分规则

16

主题

74

帖子

0

粉丝