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

主从硬件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 神马都是浮云

查看全部评分

廖向涵 回答时间: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
tony2simmy 回答时间:2017-8-15 18:04:05
和楼主一样的IC,I2C初始化也一样,只能得到起始信号,发送Slave地址时,SCL始终为低,最总就Timeout。
a试纸 回答时间:2019-4-10 09:47:16
楼主解决了吗,我遇到同样的问题
cjwdlp 回答时间:2019-7-12 12:34:29
flyman 发表于 2016-9-1 23:04
已经发现问题了,初始问题。
GPIO_Init(GPIOB,  GPIO_PIN_ALL, GPIO_MODE_OUT_PP_LOW_SLOW );          // ...

那初始IO 该设置成什么模式? 复用开漏输出么?
Delei 回答时间:2019-10-13 10:06:32
我用的时候,从模式挺稳定的,但是主模式总会莫名其妙的卡死!
Delei 回答时间:2019-10-13 10:07:14
cjwdlp 发表于 2019-7-12 12:34
那初始IO 该设置成什么模式? 复用开漏输出么?

    GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_OD_HIZ_FAST);
    GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_FAST);
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版