GD32F330
目前想在GD32F330的芯片上实现一个I2C从机发送功能。现在用正点原子的STM32开发板通过按键向GD32发送读取指令,GD32作为从机返回64位信息。每次复位后,第一读取数据成功,用示波器抓取了电平变化,从机地址正常,数据段内容正常。
但是第二次按键后,只能读到从机地址以及读标志位,从机响应不了。
有人遇到过这样的问题吗。 这个是第一次传输的数据,地址正常,数据内容也没问题 第二次传输的时候,就这剩下地址了,GD32作为从机没有响应
我用的是从机接收中断模式来进行从机数据传输的。
这是我的初始化函数:
void i2c0_config(void)
{
i2c_rcu_config1();
i2c_config1();
//i2c_nvic_config();
//i2c_interrupt();
}
void i2c_rcu_config1(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_I2C0);
}
void i2c_config1(void)
{
gpio_af_set(GPIOB,GPIO_AF_1,GPIO_PIN_6);
gpio_af_set(GPIOB,GPIO_AF_1,GPIO_PIN_7);
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_config(I2C0,100000,I2C_DTCY_2);
i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,slaveaddress1);
nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
i2c_enable(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
nvic_irq_enable(I2C0_EV_IRQn, 0, 4);
nvic_irq_enable(I2C0_ER_IRQn, 0, 1);
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
i2c_interrupt_enable(I2C0, I2C_INT_EV);
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
} 这是我的接收中断函数,基本都是从官方的例程里找的。
void I2C0_EV_IRQHandler(void)
{
if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND))
{
/* clear the ADDSEND bit */
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
}
else if((i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) && (!i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)))
// if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE))
{
i2c_data_transmit(I2C0, testnum);
}
else if(i2c_interrupt_flag_get(I2C0,I2C_INT_FLAG_STPDET))
{
// i=0;
i2c_enable(I2C0);
//// i2ctrasmitable=1;
}
}
/*!
\brief this function handles I2C0 error interrupt request exception
*/
void I2C0_ER_IRQHandler(void)
{
// i2c0_error_irq_handler();
/* 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);
}
有大佬遇到过这种问题吗,太难受了 大佬们来点建议吧 问题解决了,无语了,中断在清理外停止标志位后,会关闭I2C中断,所以要再开一次中断才行。
页:
[1]