I2C从机接收代码的疑惑
在网上看到一个基于STM32L011的IAP代码。其中Bootloader的I2C从机部分有点疑惑。 代码如下。这段代码表示的是检测到STOPF之后,判断是从机接收STOP还是从机发送STOP。其中我用红色线条框出来的部分,这部分的目的到底是啥?
我理解是发送一个NACK表示数据传输结束。 安 发表于 2019-9-19 10:57
我理解是发送一个NACK表示数据传输结束。
但是按照协议,NACK应该由主机来发送,表示不需要从机再发数据了啊 要分情况的。再写入数据时,ACK由从机控制。再读取数据时由主机控制。 安 发表于 2019-9-19 16:06
要分情况的。再写入数据时,ACK由从机控制。再读取数据时由主机控制。
这个我清楚的。可能我没描述清楚,我把完整的I2C中断代码贴出来
void I2C1_IRQHandler(void)
{
uint32_t I2C_InterruptStatus = I2C1->ISR; /* Get interrupt status */
if((I2C_InterruptStatus & I2C_ISR_ADDR) == I2C_ISR_ADDR) /* Check address match */
{
I2C1->ICR |= I2C_ICR_ADDRCF; /* Clear address match flag*/
if((I2C1->ISR & I2C_ISR_DIR) == I2C_ISR_DIR) /* Check if transfer direction is read (slave transmitter) */
{
I2C1->CR1 |= I2C_CR1_TXIE; /* Set transmit IT /status*/
i2c_event=EVENT_OPCOD_SEND; /* Set I2Centor transmit mode*/
}
else /*Write operation, slave receive status*/
{
I2C1->CR1 |= I2C_CR1_RXIE; /* Set receive IT /status*/
i2c_event=EVENT_OPCOD_BUSY_RECEIVE; /* Set I2Centor receive mode*/
}
I2C1->CR1 |=I2C_CR1_STOPIE;//Enable STOP interrupt
}
else if((I2C_InterruptStatus & I2C_ISR_TXIS) == I2C_ISR_TXIS)
{
//add some application code in this place
}
/*check RXDR is not empty*/
else if((I2C_InterruptStatus & I2C_ISR_RXNE) == I2C_ISR_RXNE)
{
//I2C_ISR_RXNE add you code in this place Tomas Li add
Receive_Buffer= I2C1->RXDR;
i2c_event=EVENT_OPCOD_BUSY_RECEIVE;//slave is busy for receive data
}
else if((I2C_InterruptStatus & I2C_ISR_NACKF) == I2C_ISR_NACKF)
{
}
/*check Stop event happen */
if((I2C_InterruptStatus & I2C_ISR_STOPF) == I2C_ISR_STOPF)
{
I2C1->ICR |=I2C_ICR_STOPCF;//clear the STOP interrupt Flag
#if 1
switch(i2c_event){
case EVENT_OPCOD_BUSY_RECEIVE://slave receive status Stop flag
I2C_Receive_Counter=0;
i2c_event = EVENT_OPCOD_NOTYET_READ;
I2C1->CR1 &= ~(I2C_CR1_STOPIE); //Disable all interrupt.except Error interrupt
I2C1->CR2 |= I2C_CR2_NACK;//set feedback Nack in next event
I2C1->CR1 |= I2C_CR1_ADDRIE;
break;
case EVENT_OPCOD_SEND: //slave send stop
I2C1->ICR |=I2C_ICR_STOPCF | I2C_ICR_NACKCF |I2C_ICR_BERRCF;//clear the STOP interrupt Flag
I2C1->CR1 |=I2C_CR1_ADDRIE;
i2c_event = NOEVENT;
break;
default:
break;
}
#endif
}
else
{
error = ERROR_I2C; /* Report an error */
}
} 从代码上分析,当I2C总线忙时的处理机制。I2C再下个事件时产生一个NACK,用于结束处理。这里我理解时对I2C总线忙时,需要告诉主机,停止访问。 从机接收结束数据后, 产生一个NACK,告知主机接收完毕。
页:
[1]