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

主从硬件IIC

[复制链接]
flyman 提问时间:2016-8-12 23:30 /
采用STM8S003F硬件I2C进行双机通讯,两个片子都使用内部16M,从机采用中断方式进行接收和发送数据(官方DEMO),主机是调用库函数向从机传数据。在主机里第一步就是检测总线是否忙,结果一直处于总线忙状态,从机也没有进入中断,硬件检查没接错线,是什么原因呢?   
while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY))  ;                 // 等待总线释放    主机卡在这一直总线忙,从机进不了中断


从机初始化:

void main(void)
{
  Init_Clk();
  Init_IO();
  Init_Timer();
  Init_I2C();

  enableInterrupts();

while(1)
{;
}
}
void Init_Clk(void)
{
  //  CLK_DeInit();
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
    CLK_HSICmd(ENABLE);         // 内部时钟默认8分频
//    CLK_HSECmd(ENABLE);         
}

void Init_I2C(void)
{
     I2C_DeInit();
     I2C_Init(I2C_FREQUENCY, SLAVE_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
     I2C_ITConfig( (I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
     I2C_Cmd(ENABLE);
}
中断:
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{

  if ((I2C->SR2) != 0)          // 读I2C错误,清状态位。
  {
    I2C->SR2 = 0;

    state1 = I2C_SR1;
    state2 = I2C_SR3;
    I2C_CR2 |= 0x04;

    LedStatus(1);       // Test
  }

  WORD Event = I2C_GetLastEvent();
  switch (Event)
  {
      /******* Slave transmitter ******/
      /* check on EV1 */
    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
      Tx_Idx = 0;
      break;

      /* check on EV3 */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
      /* Transmit data */
      I2C_SendData(Slave_Buffer_Rx[Tx_Idx++]);
      break;


      /******* Slave receiver **********/
      /* check on EV1*/
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:      // 清接受地址
      //  Rx_Idx = 0;
          I2C->SR1;
          I2C->SR3;
      break;

      /* Check on EV2*/
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:
      Slave_Buffer_Rx[Rx_Idx] = I2C_ReceiveData();

      break;

      /* Check on EV4 */
    case (I2C_EVENT_SLAVE_STOP_DETECTED):
            /* write to CR2 to clear STOPF flag */
            I2C->SR1;
            I2C->CR2 |= I2C_CR2_ACK;
      break;

    default:
     break;
  }

}




主机:
void main(void)
{

  Init_Clk();
  Init_IO();
  Init_Timer();
  Init_I2C();

  enableInterrupts();

  IIC_WriteByte(SLAVE_ADDRESS, DATA_ADDRESS,TestDataIIC);

  while (1)
  {
      Test();
  }

}

void Init_Clk(void)
{

    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
    CLK_HSICmd(ENABLE);         

}


void Init_I2C(void)
{
     I2C_DeInit();

     I2C_Init(I2C_FREQUENCY, SLAVE_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);

      I2C_ITConfig( (I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF), DISABLE);  //禁用中断
     I2C_Cmd(ENABLE);

}



void IIC_WriteByte(BYTE bDevice_ID, BYTE bwrite_Data_address, BYTE bData)   
{

    while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY))  ;                 // 等待总线释放    主机卡在这一直总线忙,从机进不了中断

    I2C_GenerateSTART(ENABLE);                                  // 开始信号
    while( !I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT))  ;      // 等待应答 EV5
    I2C_Send7bitAddress(bDevice_ID, I2C_DIRECTION_TX);          // 写选择芯片地址
    while( !I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))  ;  // 等待应答 EV6
    I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
    I2C_SendData(bwrite_Data_address);                          //  写芯片起始地址
    while( !I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING) )  ;// 等待应答 EV8
    I2C_SendData(bData);                                        //  写数据
    while( !I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED) ) ; // 等待应答 EV8_2

    I2C_GenerateSTOP(ENABLE);                                   // 停止信号
}

收藏 3 评论15 发布时间:2016-8-12 23:30

举报

15个回答
delei 回答时间:2019-10-13 09:50:54
也遇到了同样的问题,就想问下ST的大佬都在吃屎吗,这么不好用的,他们不知道?
无薪税绵 回答时间:2016-8-18 10:59:30
首先,要确定硬件有没有问题。
其次,不建议使用while作死循环等待,应该改成计数等待。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2 神马都是浮云

查看全部评分

Q向涵Q 回答时间:2016-8-18 09:05:37
硬件的好用么
从STM8开始 回答时间:2016-8-18 09:17:49
stm8的I2C用软件模拟比较好,硬件不怎么好用
johnson_gong 回答时间:2016-8-18 09:43:37
这个问题应该与STM32F103的硬件I2C很相似,因为硬件存在Debug,有时候就是无法跳出这个循环,你可以网上找一下,有这方面的解决方法

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2 赞一个!

查看全部评分

feixiang20 回答时间:2016-8-18 23:25:13
查一下是不是循环错误啊
flyman 回答时间:2016-9-1 23:04:06
已经发现问题了,初始问题。
GPIO_Init(GPIOB,  GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW );          //  定义B口推挽低速输出
GPIO_Init(GPIOB,  ( (GPIO_Pin_TypeDef)(SCL | SDA) ), GPIO_MODE_OUT_OD_HIZ_FAST );

第一个初始导致了第二个初始不成功
   
flyman 回答时间:2016-9-1 23:06:00
硬件IIC还是不好用,主从通讯,主机读数据比较稳定了;可主机写数据一开始跑正常 ,跑会儿就死机了,还不知道是什么原因造成的。
nocoyou 回答时间:2016-9-14 00:46:52
ST的硬件IIC有硬件BUG
sz阿呆 回答时间:2017-8-15 18:04:05
和楼主一样的IC,I2C初始化也一样,只能得到起始信号,发送Slave地址时,SCL始终为低,最总就Timeout。
12下一页

所属标签

相似问题

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