打印
[STM8]

stm8硬件I2C 主机/从机 发送/接收 完全解决测试验证通过

[复制链接]
3054|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
capturesthe|  楼主 | 2016-11-27 19:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。主机主函数:
I2C_MASTERMODE_Init(STANDARDSPEED);
  I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);
  rim();
  delay_ms(6000);
// while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
// I2C_GenerateSTART(ENABLE);
  while(1)
  {
    //I2C_Write(0x40,0x50,0x64);
   //I2C_EEPROM_WriteOneByte(0x42,Cnt);
   //I2C_Write(0x40,Cnt,0x58);
   // Cnt++;
    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
    I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);
    I2C_AcknowledgeConfig(I2C_ACK_CURR);
    I2C_TXCnt=0;
    I2C_RXCnt=0;
    I2C_GenerateSTART(ENABLE);
    delay_ms(3000);
  }

   主机中断部分:
    unsigned char Nuse;
  unsigned char Event;                                 
  Event=I2C->SR1;                                               //数据无错位  
  Nuse=I2C->SR3;
  if(I2C_TX)                                                   //主发送
  {
    switch(Event)
    {
      case 0X01:                                                  //起始条件已经发送
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);   //发送从机地址
          break;
      case 0x80:                         //发送区空  
          I2C->DR=I2C_TXBuffer[I2C_TXCnt++];
          if(I2C_TXCnt>=14)
          {
            I2C_TXCnt=0;
            I2C_ITConfig(I2C_IT_BUF, DISABLE);
          }
          break;
      case 0X82:                             // 地址发送结束   
         // Nuse=I2C->SR3;
          I2C_TXCnt=0;
          I2C->DR=I2C_TXBuffer[I2C_TXCnt++];
          break;
      case 0x84:
          I2C_GenerateSTOP(ENABLE);
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
         
          break;
      default:
          break;   
    }
  }
  else                                                        //主接收
  {
    switch(Event)
    {
      case 0X01:                                                  //起始条件已经发送
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);   //发送从机地址
          break;
      case 0x40:                                          //接收区满
          I2C_RXBuffer[I2C_RXCnt++]=I2C->DR;   
          if(I2C_RXCnt==13)
          {           
            I2C_AcknowledgeConfig(I2C_ACK_NONE);
            I2C_GenerateSTOP(ENABLE);
          }
          if(I2C_RXCnt>=14)
          {
            I2C_RXCnt=0;
          }
          break;
      case 0X42:                             // 地址发送结束   
         // Nuse=I2C->SR3;
          I2C_RXCnt=0;
          Nuse=I2C->DR;
          break;
      case 0x44:
          //I2C_GenerateSTOP(ENABLE);
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
      default:
          break;   
    }
  }


沙发
capturesthe|  楼主 | 2016-11-27 19:33 | 只看该作者
从机中断:
unsigned char Add;
  unsigned char Nuse;
  static unsigned char RX_Cnt=0;
  
  if(I2C->SR2&0X0F)           //I2C 出现错误
  {
    I2C->SR2&=0xf0;
    //I2C->CR2|=1<<7;
    //I2C->CR2&=~(1<<7);
    RX_Cnt=0;
    I2C_Tx_Idx=0;
  }
  
   if(I2C->SR1&0X02)      //地址匹配
  {
    (void)(I2C->SR3);  //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR
     // I2C->DR = 0X00;
    I2C_Tx_Idx=0;
    I2C_Rx_Idx=0;
    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
  }
  if(I2C->SR1&0X10)         //停止条件
  {
    Nuse = I2C->CR2;
    nop();
    I2C->CR2 = Nuse;
  }
  if(I2C->SR1&0X04)
  {
    Nuse=I2C->DR;
   // I2C->DR=Nuse;
  }
   if(I2C->SR1 & 0x40)
   {
      Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR;
      if(I2C_Rx_Idx>=14)
      {
        I2C_Rx_Idx=0;
      }   
   }
  if(I2C->SR1 & 0x80)
  {
    //将发送的数据放入DR寄存器,清除TX
    //   I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
     //  if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
   
    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
    if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
  }


使用特权

评论回复
板凳
734774645| | 2016-11-27 21:04 | 只看该作者
正需要这个,以前都用IO来搞,学习一下楼主的方法。

使用特权

评论回复
地板
hclin| | 2017-1-18 20:11 | 只看该作者
有完整的源码可供编译、测试吗?

使用特权

评论回复
5
hudi008| | 2017-1-18 23:06 | 只看该作者
hclin 发表于 2017-1-18 20:11
有完整的源码可供编译、测试吗?

这个iic不是有代码吗

使用特权

评论回复
6
18814303937| | 2019-3-7 16:53 | 只看该作者
你好,iic中断的产生条件是怎么样的?是不是做从机时,当时候有iic信号过来,就会产生中断?

使用特权

评论回复
评论
18814303937 2019-3-11 10:23 回复TA
当addr =1的时候 有开中断的话,是会产生一个中断的 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

136

帖子

1

粉丝