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

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

[复制链接]
c_lass 发布时间:2016-10-23 11:42
基于stm8调试硬件I2C经验分享


网上都说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;   
    }
  }
   从机中断:
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;
  }





评分

参与人数 1 ST金币 +10 收起 理由
zero99 + 10

查看全部评分

收藏 7 评论14 发布时间:2016-10-23 11:42

举报

14个回答
zero99 回答时间:2016-11-3 09:58:07
多谢分享,不过楼主发错板块了,下次注意
peter001 回答时间:2016-11-5 20:34:55
多谢分享,I2C有些难调
拥抱时光 回答时间:2016-11-11 11:30:37
想问下楼主,I2C_TX是怎么处理的,多久去接收
拥抱时光 回答时间:2016-11-11 11:43:08
应该是I2C_SR3的TRA位,对吧
asssdz-382474 回答时间:2016-11-11 12:20:03
wdshuang09 回答时间:2016-11-16 12:16:04
        
fengurl 回答时间:2017-6-6 18:10:54
楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗?
c_lass 回答时间:2017-6-22 15:14:34
STM8S103 SLAVE地址是自己在舒适化设置的
秦皇岛老王 回答时间:2017-7-1 14:55:08
版主有QQ么?有问题想咨询下
12下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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