恩成 发表于 2023-4-6 11:09

GD32F330

目前想在GD32F330的芯片上实现一个I2C从机发送功能。现在用正点原子的STM32开发板通过按键向GD32发送读取指令,GD32作为从机返回64位信息。
每次复位后,第一读取数据成功,用示波器抓取了电平变化,从机地址正常,数据段内容正常。
但是第二次按键后,只能读到从机地址以及读标志位,从机响应不了。
有人遇到过这样的问题吗。

恩成 发表于 2023-4-6 11:35

这个是第一次传输的数据,地址正常,数据内容也没问题

恩成 发表于 2023-4-6 11:36

第二次传输的时候,就这剩下地址了,GD32作为从机没有响应

恩成 发表于 2023-4-6 11:38

我用的是从机接收中断模式来进行从机数据传输的。
这是我的初始化函数:
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);
       
}

恩成 发表于 2023-4-6 11:39

这是我的接收中断函数,基本都是从官方的例程里找的。
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);
}

恩成 发表于 2023-4-6 11:40

有大佬遇到过这种问题吗,太难受了

恩成 发表于 2023-4-6 17:20

大佬们来点建议吧

恩成 发表于 2023-4-7 15:07

问题解决了,无语了,中断在清理外停止标志位后,会关闭I2C中断,所以要再开一次中断才行。
页: [1]
查看完整版本: GD32F330