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

[复制链接]
 楼主| zhengshuo 发表于 2025-6-18 09:46 | 显示全部楼层 |阅读模式
  1. i2c_status_type i2c_master_transmit(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout)
  2. {
  3.         volatile int test;
  4.   /* initialization parameters */
  5.   hi2c->pbuff = pdata;
  6.   hi2c->pcount = size;

  7.   hi2c->error_code = I2C_OK;

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

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

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

  22.     return I2C_ERR_STEP_2;
  23.   }

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

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

  33.       return I2C_ERR_STEP_3;
  34.     }

  35.     /* write data */
  36.     i2c_data_send(hi2c->i2cx, (*pdata++));
  37.     size--;
  38.   }

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

  44.     return I2C_ERR_STEP_4;
  45.   }

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

  48.   return I2C_OK;
  49. }

  1. void wk_i2c3_init(void)
  2. {
  3.   /* add user code begin i2c3_init 0 */
  4.         volatile uint32_t* reg_addr = (volatile uint32_t*)0x40010028;
  5.         volatile uint32_t value_after_setting;
  6.   /* add user code end i2c3_init 0 */

  7.   gpio_init_type gpio_init_struct;

  8.   gpio_default_para_init(&gpio_init_struct);

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

  11.   /* add user code end i2c3_init 1 */

  12.   /* configure the SCL pin */
  13.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
  14.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  15.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  16.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  17.   gpio_init_struct.gpio_pins = GPIO_PINS_8;
  18.   gpio_init(GPIOA, &gpio_init_struct);

  19.   /* configure the SDA pin */
  20.   gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
  21.   gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  22.   gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  23.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  24.   gpio_init_struct.gpio_pins = GPIO_PINS_4;
  25.   gpio_init(GPIOB, &gpio_init_struct);


  26.   i2c_init(I2C3, I2C_FSMODE_DUTY_2_1, 100000);
  27.   i2c_own_address1_set(I2C3, I2C_ADDRESS_MODE_7BIT, 0x0);
  28.   i2c_ack_enable(I2C3, TRUE);
  29.   i2c_clock_stretch_enable(I2C3, TRUE);
  30.   i2c_general_call_enable(I2C3, FALSE);

  31.   /* add user code begin i2c3_init 2 */

  32.   /* add user code end i2c3_init 2 */

  33.   i2c_enable(I2C3, TRUE);

  34.   /* add user code begin i2c3_init 3 */
  35.         value_after_setting = *reg_addr;
  36.         value_after_setting = *reg_addr;
  37.   /* add user code end i2c3_init 3 */
  38. }

仿真调试查看到test对应的SCL和SDA均为1,那为什么会进入到busy状态呢?这是首次发送,硬件肯定没问题
初始化I2C3,用了管脚重映射,最后直接寄存器读取查看IOMUX_REMAP5的12-15位确实为0001
 楼主| zhengshuo 发表于 2025-6-18 09:51 | 显示全部楼层
  1. void wk_periph_clock_config(void)
  2. {
  3.   /* enable iomux periph clock */
  4.   crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);

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

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

  9.   /* enable i2c3 periph clock */
  10.   crm_periph_clock_enable(CRM_I2C3_PERIPH_CLOCK, TRUE);
  11.        
  12.         /* enable gpioe periph clock */
  13.   crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);

  14.         /* enable spi4 periph clock */
  15.   crm_periph_clock_enable(CRM_SPI4_PERIPH_CLOCK, TRUE);
  16. }


外设时钟已打开
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

1

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部