zhengshuo 发表于 2025-6-18 09:46

i2c总是检测忙碌状态,重映射问题?

i2c_status_type i2c_master_transmit(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout)
{
        volatile int test;
/* initialization parameters */
hi2c->pbuff = pdata;
hi2c->pcount = size;

hi2c->error_code = I2C_OK;

/* wait for the busy flag to be reset */
if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK)
{
                test = gpio_input_data_bit_read(GPIOA,GPIO_PINS_8);
                test = gpio_input_data_bit_read(GPIOB,GPIO_PINS_4);
    return I2C_ERR_STEP_1;
}

/* ack acts on the current byte */
i2c_master_receive_ack_set(hi2c->i2cx, I2C_MASTER_ACK_CURRENT);

/* send slave address */
if(i2c_master_write_addr(hi2c, address, timeout) != I2C_OK)
{
    /* generate stop condtion */
    i2c_stop_generate(hi2c->i2cx);

    return I2C_ERR_STEP_2;
}

/* clear addr flag */
i2c_flag_clear(hi2c->i2cx, I2C_ADDR7F_FLAG);

while(size > 0)
{
    /* wait for the tdbe flag to be set */
    if(i2c_wait_flag(hi2c, I2C_TDBE_FLAG, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK)
    {
      /* generate stop condtion */
      i2c_stop_generate(hi2c->i2cx);

      return I2C_ERR_STEP_3;
    }

    /* write data */
    i2c_data_send(hi2c->i2cx, (*pdata++));
    size--;
}

/* wait for the tdc flag to be set */
if(i2c_wait_flag(hi2c, I2C_TDC_FLAG, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK)
{
    /* generate stop condtion */
    i2c_stop_generate(hi2c->i2cx);

    return I2C_ERR_STEP_4;
}

/* generate stop condtion */
i2c_stop_generate(hi2c->i2cx);

return I2C_OK;
}

void wk_i2c3_init(void)
{
/* add user code begin i2c3_init 0 */
        volatile uint32_t* reg_addr = (volatile uint32_t*)0x40010028;
        volatile uint32_t value_after_setting;
/* add user code end i2c3_init 0 */

gpio_init_type gpio_init_struct;

gpio_default_para_init(&gpio_init_struct);

/* add user code begin i2c3_init 1 */
gpio_pin_remap_config(I2C3_GMUX_0001, TRUE);

/* add user code end i2c3_init 1 */

/* configure the SCL pin */
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_pins = GPIO_PINS_8;
gpio_init(GPIOA, &gpio_init_struct);

/* configure the SDA pin */
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
gpio_init_struct.gpio_pins = GPIO_PINS_4;
gpio_init(GPIOB, &gpio_init_struct);


i2c_init(I2C3, I2C_FSMODE_DUTY_2_1, 100000);
i2c_own_address1_set(I2C3, I2C_ADDRESS_MODE_7BIT, 0x0);
i2c_ack_enable(I2C3, TRUE);
i2c_clock_stretch_enable(I2C3, TRUE);
i2c_general_call_enable(I2C3, FALSE);

/* add user code begin i2c3_init 2 */

/* add user code end i2c3_init 2 */

i2c_enable(I2C3, TRUE);

/* add user code begin i2c3_init 3 */
        value_after_setting = *reg_addr;
        value_after_setting = *reg_addr;
/* add user code end i2c3_init 3 */
}
仿真调试查看到test对应的SCL和SDA均为1,那为什么会进入到busy状态呢?这是首次发送,硬件肯定没问题
初始化I2C3,用了管脚重映射,最后直接寄存器读取查看IOMUX_REMAP5的12-15位确实为0001

zhengshuo 发表于 2025-6-18 09:51

void wk_periph_clock_config(void)
{
/* enable iomux periph clock */
crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);

/* enable gpioa periph clock */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

/* enable gpiob periph clock */
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

/* enable i2c3 periph clock */
crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, TRUE);
       
        /* enable gpioe periph clock */
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);

        /* enable spi4 periph clock */
crm_periph_clock_enable(CRM_SPI4_PERIPH_CLOCK, TRUE);
}

外设时钟已打开
页: [1]
查看完整版本: i2c总是检测忙碌状态,重映射问题?