21ic问答首页 - GD32E230作为IIC从机时接收数据会卡顿是什么原因
GD32E230作为IIC从机时接收数据会卡顿是什么原因
Henry-hu2024-08-29
在配置完成IIC从机模式后,主机向从机发送9位数据,在从机收到数据后主函数的代码会跑不到,不知道在什么地方造成了阻塞,接收完毕会产生多次的STPDEF中断吗,但是IIC从机模式的故障应该也不会影响到主函数的运行才对,有没有懂的大佬帮忙分析一下谢谢,代码如下#include "gd32e230.h"
#define MSG_RECV_BYTE_SUM 9
#define MSG_SEND_BYTE_SUM 6
#define I2C0_OWN_ADDRESS7 0x44
void iic_msg_gpio_config_init(void)
{
/* enable GPIOB clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* enable I2C0 clock */
rcu_periph_clock_enable(RCU_I2C0);
/* connect PB6 to I2C0_SCL */
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);
/* connect PB7 to I2C0_SDA */
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);
/* configure GPIO pins of I2C0 */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
/* I2C clock configure */
i2c_clock_config(I2C0, 400000, I2C_DTCY_2);
/* I2C address configure */
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_OWN_ADDRESS7);
/* enable I2C0 */
i2c_enable(I2C0);
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
nvic_irq_enable(I2C0_EV_IRQn, 23);
nvic_irq_enable(I2C0_ER_IRQn, 32);
/* enable the I2C0 interrupt */
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
i2c_interrupt_enable(I2C0, I2C_INT_EV);
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
}
void i2c0_event_irq_handler(void)
{
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND))
{
// 0:接收端
// 1:发送端
tI2cSlave.uFlag.Bits.DirState = i2c_flag_get(I2C0, I2C_FLAG_TR);
if (tI2cSlave.uFlag.Bits.DirState == RESET)
{
msg_iic_recv_buf_count = 0;
for (uint8_t i = 0; i < MSG_RECV_BYTE_SUM; i++)
{
i2c_rxbuffer1[i = 0;
}
}
else
{
/* clear I2C_TDATA register */
i2c_flag_clear(I2C0, I2C_FLAG_TBE);
slave_msg_send.soft_versions = 0x00;
i2c_txbuffer[0 = slave_msg_send.soft_versions;
i2c_txbuffer[1 = slave_msg_send.KEY_state;
slave_msg_send.reserved_1 = 0x00;
slave_msg_send.reserved_2 = 0x00;
slave_msg_send.reserved_3 = 0x00;
i2c_txbuffer[2 = slave_msg_send.reserved_1;
i2c_txbuffer[3 = slave_msg_send.reserved_2;
i2c_txbuffer[4 = slave_msg_send.reserved_3;
slave_msg_send.check_sum = 0;
uint32_t cheak = 0;
cheak += i2c_txbuffer[0];
cheak += i2c_txbuffer[1];
cheak += i2c_txbuffer[2];
cheak += i2c_txbuffer[3];
cheak += i2c_txbuffer[4];
cheak = ~cheak;
cheak = cheak + 1;
i2c_txbuffer[5 = cheak;
slave_msg_send.check_sum = cheak;
msg_iic_send_buf_count = 0;
}
/* clear the ADDSEND bit */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)) // && dma_flag_get(DMA_RX_CH, DMA_FLAG_FTF)
{
if (msg_iic_recv_buf_count < MSG_RECV_BYTE_SUM)
{
i2c_rxbuffer1[msg_iic_recv_buf_count = i2c_data_receive(I2C0);
if (msg_iic_recv_buf_count == (MSG_RECV_BYTE_SUM - 1))
{
UpdateReceiveProc();
}
++msg_iic_recv_buf_count;
}
else
{
i2c_data_receive(I2C0);
}
}
else if ((i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE))) // && dma_flag_get(DMA_TX_CH, DMA_FLAG_FTF)
{
/* send a data byte */
if (msg_iic_send_buf_count < MSG_SEND_BYTE_SUM)
{
/* if reception data register is not empty, I2C0 will read a data from I2C_RDATA */
i2c_data_transmit(I2C0, i2c_txbuffer[msg_iic_send_buf_count]);
msg_iic_send_buf_count++;
}
else
{
i2c_data_transmit(I2C0, 0xff);
}
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET))
{
/* clear STPDET interrupt flag */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_STPDET);
if (tI2cSlave.uFlag.Bits.DirState == RESET)
{
tI2cSlave.uFlag.Bits.RecSuccess = SUCCESS;
msg_iic_recv_buf_count = 0x00;
}
else
{
tI2cSlave.uFlag.Bits.SendSuccess = SUCCESS;
tI2cSlave.SendSize = 0x00; // 避免没有接收到命令重新发数据
msg_iic_send_buf_count = 0x00;
}
i2c_enable(I2C0);
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
/* clear STPDET interrupt flag */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
tI2cSlave.uFlag.Bits.SendSuccess = SUCCESS;
}
}
void i2c0_error_irq_handler(void)
{
/* no acknowledge received */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
}
/* SMBus alert */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
}
/* bus timeout in SMBus mode */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
}
/* over-run or under-run when SCL stretch is disabled */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
}
/* arbitration lost */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
}
/* bus error */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
}
/* CRC value doesn't match */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
}
/* disable the I2C0 interrupt */
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
i2c_interrupt_disable(I2C0, I2C_INT_EV);
}
void I2C0_EV_IRQHandler(void)
{
i2c0_event_irq_handler();
}
void I2C0_ER_IRQHandler(void)
{
i2c0_error_irq_handler();
}
#define MSG_RECV_BYTE_SUM 9
#define MSG_SEND_BYTE_SUM 6
#define I2C0_OWN_ADDRESS7 0x44
void iic_msg_gpio_config_init(void)
{
/* enable GPIOB clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* enable I2C0 clock */
rcu_periph_clock_enable(RCU_I2C0);
/* connect PB6 to I2C0_SCL */
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);
/* connect PB7 to I2C0_SDA */
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);
/* configure GPIO pins of I2C0 */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
/* I2C clock configure */
i2c_clock_config(I2C0, 400000, I2C_DTCY_2);
/* I2C address configure */
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_OWN_ADDRESS7);
/* enable I2C0 */
i2c_enable(I2C0);
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
nvic_irq_enable(I2C0_EV_IRQn, 23);
nvic_irq_enable(I2C0_ER_IRQn, 32);
/* enable the I2C0 interrupt */
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
i2c_interrupt_enable(I2C0, I2C_INT_EV);
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
}
void i2c0_event_irq_handler(void)
{
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND))
{
// 0:接收端
// 1:发送端
tI2cSlave.uFlag.Bits.DirState = i2c_flag_get(I2C0, I2C_FLAG_TR);
if (tI2cSlave.uFlag.Bits.DirState == RESET)
{
msg_iic_recv_buf_count = 0;
for (uint8_t i = 0; i < MSG_RECV_BYTE_SUM; i++)
{
i2c_rxbuffer1[i = 0;
}
}
else
{
/* clear I2C_TDATA register */
i2c_flag_clear(I2C0, I2C_FLAG_TBE);
slave_msg_send.soft_versions = 0x00;
i2c_txbuffer[0 = slave_msg_send.soft_versions;
i2c_txbuffer[1 = slave_msg_send.KEY_state;
slave_msg_send.reserved_1 = 0x00;
slave_msg_send.reserved_2 = 0x00;
slave_msg_send.reserved_3 = 0x00;
i2c_txbuffer[2 = slave_msg_send.reserved_1;
i2c_txbuffer[3 = slave_msg_send.reserved_2;
i2c_txbuffer[4 = slave_msg_send.reserved_3;
slave_msg_send.check_sum = 0;
uint32_t cheak = 0;
cheak += i2c_txbuffer[0];
cheak += i2c_txbuffer[1];
cheak += i2c_txbuffer[2];
cheak += i2c_txbuffer[3];
cheak += i2c_txbuffer[4];
cheak = ~cheak;
cheak = cheak + 1;
i2c_txbuffer[5 = cheak;
slave_msg_send.check_sum = cheak;
msg_iic_send_buf_count = 0;
}
/* clear the ADDSEND bit */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)) // && dma_flag_get(DMA_RX_CH, DMA_FLAG_FTF)
{
if (msg_iic_recv_buf_count < MSG_RECV_BYTE_SUM)
{
i2c_rxbuffer1[msg_iic_recv_buf_count = i2c_data_receive(I2C0);
if (msg_iic_recv_buf_count == (MSG_RECV_BYTE_SUM - 1))
{
UpdateReceiveProc();
}
++msg_iic_recv_buf_count;
}
else
{
i2c_data_receive(I2C0);
}
}
else if ((i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE))) // && dma_flag_get(DMA_TX_CH, DMA_FLAG_FTF)
{
/* send a data byte */
if (msg_iic_send_buf_count < MSG_SEND_BYTE_SUM)
{
/* if reception data register is not empty, I2C0 will read a data from I2C_RDATA */
i2c_data_transmit(I2C0, i2c_txbuffer[msg_iic_send_buf_count]);
msg_iic_send_buf_count++;
}
else
{
i2c_data_transmit(I2C0, 0xff);
}
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET))
{
/* clear STPDET interrupt flag */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_STPDET);
if (tI2cSlave.uFlag.Bits.DirState == RESET)
{
tI2cSlave.uFlag.Bits.RecSuccess = SUCCESS;
msg_iic_recv_buf_count = 0x00;
}
else
{
tI2cSlave.uFlag.Bits.SendSuccess = SUCCESS;
tI2cSlave.SendSize = 0x00; // 避免没有接收到命令重新发数据
msg_iic_send_buf_count = 0x00;
}
i2c_enable(I2C0);
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
/* clear STPDET interrupt flag */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
tI2cSlave.uFlag.Bits.SendSuccess = SUCCESS;
}
}
void i2c0_error_irq_handler(void)
{
/* no acknowledge received */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
}
/* SMBus alert */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
}
/* bus timeout in SMBus mode */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
}
/* over-run or under-run when SCL stretch is disabled */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
}
/* arbitration lost */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
}
/* bus error */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
}
/* CRC value doesn't match */
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
}
/* disable the I2C0 interrupt */
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
i2c_interrupt_disable(I2C0, I2C_INT_EV);
}
void I2C0_EV_IRQHandler(void)
{
i2c0_event_irq_handler();
}
void I2C0_ER_IRQHandler(void)
{
i2c0_error_irq_handler();
}
赞0
评论
2024-09-30
赞0
评论
2024-09-30
赞0
评论
2024-09-25
赞0
评论
2024-09-25
赞0
评论
2024-09-25
赞0
评论
2024-09-25
赞0
评论
2024-09-25
赞0
评论
2024-09-25
赞0
评论
2024-09-25
您需要登录后才可以回复 登录 | 注册