STM32
直播中

陈敏

7年用户 1321经验值
私信 关注
[问答]

stm8l051 I2C从机发送,为什么主机一直收到的是0xff?

void main(void)
{
  /* Infinite loop */
  CLK_LSICmd(ENABLE);//使能LSI
CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_LSI);//RTC时钟源LSI,1分频=38K
  while (CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == RESET);//等待LSI就绪
  CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);

  I2C_DeInit(I2C1);
  I2C_Init(I2C1, 4000, 0x51,I2C_Mode_I2C, I2C_DutyCycle_2,I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
  /* Enable Error Interrupt*/
  I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);

  USART_DeInit(USART1);
  CLK_PeripheralClockConfig (CLK_Peripheral_USART1,ENABLE);//开启USART时钟
  USART_Init(USART1,9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,(USART_Mode_TypeDef)USART_Mode_Tx|USART_Mode_Rx);//设置USART参数9600,8N1,接收/发送
  USART_Cmd (USART1,ENABLE);
  enableInterrupts();//使能中断

  while (1)
  {
  }
}
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler,29)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
  u8 temp = 0;
    if (I2C1->SR1 0x02)//地址已经匹配(读SR1,SR3清除该位)
    {
      I2C_GetITStatus(I2C1,I2C_IT_ADDR);
        temp = I2C1->SR3 0x07;
        USART1_SendStr("匹配地址n");
    }
    else if ((I2C1->SR1 0x84)  (I2C1->SR3 0x04))//数据字节传送完
    {
      I2C_GetITStatus(I2C1,I2C_IT_BTF);
        temp = 0xA0;    //假设这里发送0xA5
        I2C1->DR = temp;
        I2C_GenerateSTOP(I2C1,ENABLE);
        USART1_SendStr("数据发完 等待发送n");
    }
    else if ((I2C1->SR1 0x40)  (0 == (I2C1->SR3 0x04)))//接收时数据寄存器
    {
        temp = I2C1->DR;    //读取数据寄存器
        USART_SendData8(USART1,temp);
        USART1_SendStr("数据发完 等待读取n");
    }
    else if (I2C1->SR1 0x10)//检测到停止位
    {
        I2C1->CR2 = I2C1->CR2;//清除停止位
        I2C_GenerateSTOP(I2C1,ENABLE);
        USART1_SendStr("检测到停止位n");
    }
    //错误处理
    if (I2C1->SR2 0x01)//总线错误
    {
        I2C1->SR2  = ~0x01;//清零
        USART1_SendStr("总线错误n");
    }
    else if(I2C1->SR2 0x02)//仲裁失败
    {
        I2C1->SR2  = ~0x02;//清零
        USART1_SendStr("仲裁失败n");
    }
    else if(I2C1->SR2 0x04)//应答失败
    {
        I2C1->SR2  = ~0x04;//清零
        USART1_SendStr("应答失败n");
    }
    else if(I2C1->SR2 0x08)//上溢、下溢
    {
        I2C1->SR2  = ~0x08;//清零
        USART1_SendStr("上溢下溢n");
    }

    USART1_SendStr("中断结束n");
    return;



}




回帖(1)

手托初梦

2024-5-6 16:54:11
从你提供的代码来看,你正在尝试使用STM8L051微控制器作为I2C从机,但是主机一直收到的是0xff。这个问题可能有以下几个原因:

1. I2C总线冲突:请确保I2C总线上没有其他设备与你的STM8L051从机发生冲突。检查其他设备的地址和引脚连接。

2. I2C初始化参数错误:检查I2C初始化函数中的参数是否正确。例如,你正在使用4000作为I2C时钟频率,但是STM8L051的最大I2C时钟频率为1MHz。请确保你的时钟频率在允许的范围内。

3. I2C通信模式错误:你正在使用I2C_Mode_I2C作为通信模式,这是正确的。但是,请确保主机也使用相同的通信模式。

4. I2C从机地址错误:你正在使用0x51作为从机地址,确保这个地址没有与其他设备冲突,并且主机正在使用正确的地址进行通信。

5. 从机响应错误:请检查你的从机是否正确地响应了主机的读取请求。在I2C通信中,从机需要向主机发送数据。确保你的从机代码中包含了发送数据的部分。

6. 硬件连接问题:检查I2C1的SDA和SCL引脚是否正确连接到主机的相应引脚上,并且没有短路或断路。

7. 主机问题:确保主机的I2C配置和通信正确。主机需要正确地发送读取请求,并且正确地解析从机发送的数据。

为了解决这个问题,你可以尝试以下步骤:

1. 检查I2C总线是否有冲突,并确保所有设备的地址不冲突。
2. 检查I2C初始化参数,确保时钟频率和从机地址正确。
3. 确保从机代码中包含了发送数据的部分,并正确响应主机的读取请求。
4. 检查硬件连接,确保I2C1的SDA和SCL引脚正确连接。
5. 检查主机的I2C配置和通信,确保正确发送读取请求并解析从机数据。

希望这些建议能帮助你解决问题。如果问题仍然存在,请提供更多的代码和信息,以便进一步分析。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分