STM32硬件I2C应答响应
I2C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。在stm32中,当使用硬件I2C时,应答位由硬件自动产生。
当stm32作为主发送器时,从机每接收到一个字节由硬件自动产生一个接收应答信号返回给stm32。
当stm32作为主接收器时,stm32从从机读取数据,每读取一个字节由stm32发送一个发送应答给从机,表示当前字节读取完成;当从机接收到应答的时候,从机把数据放到数据线(SDA)继续让主机读取;当从机收到非应答(NA)时,从机停止发送数据。
在实际的使用中,stm32的应答响应初始化后由硬件自动产生,只需要stm32作为接收器时在读取结束的时候配置非应答(NA)即可。
STM32模拟I2C应答响应
在stm32实际使用过程中,硬件I2C由于st公司设计不合理,会出现各种各样的问题。此时由软件的模拟I2C由此诞生。
在模拟I2C中应答位不会由硬件自动产生,需要自行根据时序配置应答位。
应答的本质是什么?
应答其实就是一个数据位,在I2c协议中规定当发送或者接收一个字节后,下一个数据位即为应答位,当这个位为0时,即表示收到了应答,为1时,即表示为没有接收到应答。
模拟产生I2C时应答又分为两种
发送应答:
主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。
void MyI2C_W_SCL(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
Delay_us(10);
}
//这是一个发送应答程序
void MyI2C_SendAck(uint8_t AckBit)
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1); //时钟线拉高 读取应答位数据
MyI2C_W_SCL(0); //时钟线拉低 准备开始下一个时序
}
接收应答:
主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答。
void MyI2C_W_SCL(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
Delay_us(10);
}
//接收应答是我发送一个数据 从机给我返回一个值 告诉我收到了
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckBit;
MyI2C_W_SDA(1); //在接收应答前 主机要释放SDA的控制权
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}