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

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位,对吧
assssdz 回答时间: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么?有问题想咨询下
蓝色天使211 回答时间:2018-1-23 12:38:06
感谢楼主分享!
ycaaa 回答时间:2018-1-28 17:02:13
11111111111111111111111111111
Johnson Cao 回答时间:2018-1-30 10:18:13
小镇夏天的风声 回答时间:2018-10-10 17:59:17
多谢分享 还是软件模拟好用
sincomaster 回答时间:2018-10-12 08:51:40
谢谢分享

所属标签

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