诗歌三千剑 2023-05-25 16:36 采纳率: 20%
浏览 45
已结题

GD32E320 I2C问题

问题遇到的现象和发生背景

MCU: GD32E230G8

如图所示,两个I2C,却只有一个是正常的。
我用的代码呢,在GD32F310上成功过。
可是现在只有一个正常。难道我只能用一个I2C了吗?


****
其实这个代码也是从官方的一个例子该来的。

###### 用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
###### 代码如下:
```c

#include "gd32e23x.h"
#include "systick.h"
#include "stdint.h"

#define I2C_10BIT_ADDRESS      0
#define I2C0_OWN_ADDRESS7      0x72
#define I2C0_SLAVE_ADDRESS7    0x53
#define I2C0_SLAVE_ADDRESS10   0x0322
#define I2C0_SPEED              100000
#define I2C1_SPEED              100000
#define TIMEOUT 50
void i2c_init(void);

void i2c_rcu_config(void);
void i2c_gpio_config(void);
void i2c_config(void);

unsigned char i2c1_buffer_read(uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte);

unsigned char  i2c1_buffer_write(uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte);

unsigned char i2c0_buffer_read(uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte);

unsigned char  i2c0_buffer_write(uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte);

unsigned char i2c_buffer_read(uint32_t I2Cx, uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte);

unsigned char i2c_buffer_write(uint32_t I2Cx, uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    SystemInit();
    i2c_init();
    unsigned char data = 0;
    unsigned char buf[2] = {0x40,0x08};
    while(1)
    {
        i2c0_buffer_write(0x20, 0x00, buf, 2);
        i2c0_buffer_read(0xA6, 0x00, &data, 1);
        i2c1_buffer_read(0x90, 0x21, &data, 1);
        i2c1_buffer_write(0x90, 0x21, buf, 2);
    }
}

void i2c_init(void)
{
    i2c_gpio_config();
    i2c_rcu_config();
    i2c_config();
}

void i2c_rcu_config(void)
{
    rcu_periph_clock_enable(RCU_I2C1);
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_I2C0);
    rcu_periph_clock_enable(RCU_GPIOB);
}
void i2c_gpio_config(void)
{
    /* connect PB6 to I2C0_SCL */
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_0);
    /* connect PB7 to I2C0_SDA */
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_1);
    /* configure GPIO pins of I2Cx */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_0);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_0);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_1);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
    
    /* connect PB6 to I2C1_SCL */
    gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);
    /* connect PB7 to I2C1_SDA */
    gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);
    /* configure GPIO pins of I2C1 */
    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);
}


void i2c_config(void)
{
    i2c_deinit(I2C1);
    i2c_clock_config(I2C1,I2C1_SPEED,I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C1,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0xA2);
    i2c_smbus_type_config(I2C1,I2C_SMBUS_DEVICE);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1,I2C_ACK_ENABLE);
    i2c_flag_clear(I2C1,I2C_FLAG_I2CBSY);
    
    i2c_deinit(I2C0);
    i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0xA2);
    i2c_smbus_type_config(I2C0,I2C_SMBUS_DEVICE);
    /* enable I2C0 */
    i2c_enable(I2C0);
    /* enable acknowledge */
    i2c_ack_config(I2C0,I2C_ACK_ENABLE);
    i2c_flag_clear(I2C0,I2C_FLAG_I2CBSY);
}

unsigned char i2c1_buffer_read(uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte)
{  
    _Bool ack;
    ack = i2c_buffer_read(I2C1, Slave_address, reg_address, p_buffer, number_of_byte);
    return ack;
}


unsigned char i2c1_buffer_write(uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte)
{
    _Bool ack;
    ack = i2c_buffer_write(I2C1, Slave_address, write_address, p_buffer, number_of_byte);
    return ack;
}

unsigned char i2c0_buffer_read(uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte)
{  
    _Bool ack;
    ack = i2c_buffer_read(I2C0, Slave_address, reg_address, p_buffer, number_of_byte);
    return ack;
}


unsigned char i2c0_buffer_write(uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte)
{
    _Bool ack;
    ack = i2c_buffer_write(I2C0, Slave_address, write_address, p_buffer, number_of_byte);
    return ack;
}

unsigned char i2c_buffer_read(uint32_t I2Cx, uint8_t Slave_address, uint8_t reg_address, uint8_t* p_buffer, uint16_t number_of_byte)
{  
    uint16_t timingout = TIMEOUT;
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2Cx, I2C_FLAG_I2CBSY))
      i2c_init();
    if(2 == number_of_byte)
    {
        i2c_ackpos_config(I2Cx,I2C_ACKPOS_NEXT);
    }
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2Cx);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_SBSEND));
    /* send slave address to I2C bus */
    i2c_master_addressing(I2Cx, Slave_address, I2C_TRANSMITTER);
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_ADDSEND)) 
    {
      timingout--;
      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_AERR) | (timingout==0))
      {
        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_AERR);
        i2c_stop_on_bus(I2Cx);
        i2c_init();
        return 0;
      }
      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_BERR) | (timingout==0))
      {
        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_BERR);
        i2c_stop_on_bus(I2Cx);
        i2c_init();
        return 1;
      }
    }
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2Cx, I2C_FLAG_ADDSEND);
    /* wait until the transmit data buffer is empty */
    while(SET != i2c_flag_get( I2Cx , I2C_FLAG_TBE));
    /* enable I2Cx*/
    i2c_enable(I2Cx);
    /* send the EEPROM's internal address to write to */
    i2c_data_transmit(I2Cx, reg_address);
    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_BTC));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2Cx);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_SBSEND));
    /* send slave address to I2C bus */
    i2c_master_addressing(I2Cx, Slave_address, I2C_RECEIVER);
    if(number_of_byte < 3)
    {
        /* disable acknowledge */
        i2c_ack_config(I2Cx,I2C_ACK_DISABLE);
    }
    timingout = TIMEOUT;
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_ADDSEND))    
    if(2 == number_of_byte)
    {
        timingout--;
        if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_AERR) | (timingout==0))
        {
            i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_AERR);
            i2c_stop_on_bus(I2Cx);
            i2c_init();
            return 0;
        }
        if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_BERR) | (timingout==0))
        {
            i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_BERR);
            i2c_stop_on_bus(I2Cx);
            i2c_init();
            return 0;
        }
    }
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2Cx,I2C_FLAG_ADDSEND);
    if(1 == number_of_byte)
    {
        /* send a stop condition to I2C bus */
        i2c_stop_on_bus(I2Cx);
    }
    /* while there is data to be read */
    while(number_of_byte){
        if(3 == number_of_byte){
            /* wait until BTC bit is set */
            while(!i2c_flag_get(I2Cx, I2C_FLAG_BTC));
            /* disable acknowledge */
            i2c_ack_config(I2Cx,I2C_ACK_DISABLE);
        }
        if(2 == number_of_byte){
            /* wait until BTC bit is set */
            while(!i2c_flag_get(I2Cx, I2C_FLAG_BTC));
            /* send a stop condition to I2C bus */
            i2c_stop_on_bus(I2Cx);
        }
        /* wait until the RBNE bit is set and clear it */
        if(i2c_flag_get(I2Cx, I2C_FLAG_RBNE)){
            /* read a byte from the EEPROM */
            *p_buffer = i2c_data_receive(I2Cx);
            /* point to the next location where the byte read will be saved */
            p_buffer++; 
            /* decrement the read bytes counter */
            number_of_byte--;
        } 
    }
    
        // test
      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_AERR) | (timingout==0))
      {
        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_AERR);
        i2c_stop_on_bus(I2Cx);
        i2c_init();
        return 0;
      }
//      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_BERR) | (timingout==0))
//      {
//        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_BERR);
//        i2c_init();
//        i2c0_buffer_write(Slave_address, reg_address, p_buffer, number_of_byte);
//        return 1;
//      }
    
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2Cx)&0x0200);
    /* enable acknowledge */
    i2c_ack_config(I2Cx, I2C_ACK_ENABLE);
    i2c_ackpos_config(I2Cx, I2C_ACKPOS_CURRENT);
    return 1;
}



unsigned char i2c_buffer_write(uint32_t I2Cx, uint8_t Slave_address, uint8_t write_address, uint8_t* p_buffer, uint8_t number_of_byte)
{
    uint16_t timingout = TIMEOUT;
    /* wait until I2C bus is idle */
    while(i2c_flag_get(I2Cx, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2Cx);
    /* wait until SBSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_SBSEND));
    /* send slave address to I2C bus */
    i2c_master_addressing(I2Cx, Slave_address, I2C_TRANSMITTER);
    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_ADDSEND)) 
    {
      timingout--;
      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_AERR) | (timingout==0))
      {
        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_AERR);
        i2c_stop_on_bus(I2Cx);
        i2c_init();
        return 0;
      }
      if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_BERR) | (timingout==0))
      {
        i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_BERR);
        i2c_init();
        i2c0_buffer_write(Slave_address, write_address, p_buffer, number_of_byte);
        return 1;
      }
    }
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2Cx,I2C_FLAG_ADDSEND);
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2Cx, I2C_FLAG_TBE));
    /* send the EEPROM's internal address to write to : only one byte address */
    i2c_data_transmit(I2Cx, write_address);
    /* wait until BTC bit is set */
    while(!i2c_flag_get(I2Cx, I2C_FLAG_BTC));
    /* while there is data to be written */
    while(number_of_byte--){  
        i2c_data_transmit(I2Cx, *p_buffer);
        
        /* point to the next byte to be written */
        p_buffer++; 
        timingout = TIMEOUT;
        /* wait until BTC bit is set */
        while(!i2c_flag_get(I2Cx, I2C_FLAG_BTC))
        {
            timingout--;
            if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_AERR) | (timingout==0))
            {
                i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_AERR);
                i2c_stop_on_bus(I2Cx);
                i2c_init();
                return 0;
            }
            if(i2c_interrupt_flag_get(I2Cx, I2C_INT_FLAG_BERR) | (timingout==0))
            {
                i2c_interrupt_flag_clear(I2Cx, I2C_INT_FLAG_BERR);
                i2c_init();
                i2c0_buffer_write(Slave_address, write_address, p_buffer, number_of_byte);
                return 1;
            }
        }
          
    }
    

    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2Cx);
    
    /* wait until the stop condition is finished */
    while(I2C_CTL0(I2Cx)&0x0200);
    return 1;
}

运行结果及详细报错内容

img

  MSDA
  [2C-SDA
  MSCL
  I2C-SOL
  LSDA
  2C-SDA
 11
  LSCL              一王
  2C-SO
 10
我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%
我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”
  • 写回答

1条回答 默认 最新

  • 少林and叔叔 2023-05-30 09:34
    关注

    现在是I2C0能用还是I2C1能用?

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月10日
  • 创建了问题 5月25日

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突