硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1564|回复: 0
收起左侧

[客户分享] AT32 I2C程序使用讲解

[复制链接]

22

主题

16

回帖

82

积分

初级会员

积分
82
发表于 2022-2-9 21:54:25 | 显示全部楼层 |阅读模式
本帖最后由 tutu 于 2022-2-9 21:55 编辑

AT32官方BSP里面提供了I2C的使用例程,极大的方便了我们使用I2C,代码位置:BSP里面的project\at_start_f403a\examples\i2c,该路径下有以下四个demo:


communication_dma -- 使用DMA进行传输
communication_int -- 使用中断进行传输
communication_poll -- 使用轮寻的方式传输
eeprom -- eeprom 使用示例


关于I2C传输数据的流程,官方已经封装了一个应用层,用户无需再关心数据传输流程,只需要调用相关接口初始化I2C,然后再调用相关接口传输数据即可,在以下两个文件中:
i2c_application.c
i2c_application.h


i2c_config -- 调用此函数初始化I2C              
i2c_lowlevel_init -- 用户实现这个函数,完成I2C底层初始化,例如初始化GPIO、时钟、中断、DMA等   
                        
i2c_master_transmit -- 主机发送数据-轮询方式
i2c_master_receive -- 主机接收数据-轮询方式
i2c_slave_transmit -- 从机发送数据-轮询方式
i2c_slave_receive -- 从机接收数据-轮询方式
                        
i2c_master_transmit_int -- 主机发送数据-中断方式  
i2c_master_receive_int -- 主机接收数据-中断方式  
i2c_slave_transmit_int -- 从机发送数据-中断方式  
i2c_slave_receive_int -- 从机接收数据-中断方式  
                        
i2c_master_transmit_dma -- 主机发送数据-DMA方式   
i2c_master_receive_dma -- 主机接收数据-DMA方式   
i2c_slave_transmit_dma -- 从机发送数据-DMA方式   
i2c_slave_receive_dma -- 从机接收数据-DMA方式   
                        
i2c_memory_write     -- 写数据到EEPROM-轮询方式      
i2c_memory_write_int -- 写数据到EEPROM-中断方式         
i2c_memory_write_dma -- 写数据到EEPROM-DMA方式         
i2c_memory_read      -- 从EEPROM读数据-轮询方式         
i2c_memory_read_int  -- 从EEPROM读数据-中断方式         
i2c_memory_read_dma  -- 从EEPROM读数据-DMA方式     


我们对communication_dma例程代码进行举例分析

1. 首先实现i2c_lowlevel_init函数,实现I2C的底层初始化
void i2c_lowlevel_init(i2c_handle_type* hi2c)
{
  gpio_init_type gpio_initstructure;
  
  if(hi2c->i2cx == I2Cx_PORT)
  {  
    /* i2c periph clock enable */
    crm_periph_clock_enable(I2Cx_CLK, TRUE);   
    crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
    crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
   
    /* gpio configuration */  
    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;  
    gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
    gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;  
    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  
    /* configure i2c pins: scl */   
    gpio_initstructure.gpio_pins = I2Cx_SCL_PIN;
    gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_initstructure);


    /* configure i2c pins: sda */     
    gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
    gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
   
    /* configure and enable i2c dma channel interrupt */
    nvic_irq_enable(I2Cx_DMA_TX_IRQn, 0, 0);
    nvic_irq_enable(I2Cx_DMA_RX_IRQn, 0, 0);        
   
    /* i2c dma tx and rx channels configuration */
    /* enable the dma clock */
    crm_periph_clock_enable(I2Cx_DMA_CLK, TRUE);
  
    /* i2c dma channel configuration */
    dma_reset(hi2c->dma_tx_channel);
    dma_reset(hi2c->dma_rx_channel);   
   
    hi2c->dma_tx_channel = I2Cx_DMA_TX_CHANNEL;
    hi2c->dma_rx_channel = I2Cx_DMA_RX_CHANNEL;
  
    dma_default_para_init(&hi2c->dma_init_struct);
    hi2c->dma_init_struct.peripheral_inc_enable    = FALSE;
    hi2c->dma_init_struct.memory_inc_enable        = TRUE;
    hi2c->dma_init_struct.peripheral_data_width    = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    hi2c->dma_init_struct.memory_data_width        = DMA_MEMORY_DATA_WIDTH_BYTE;
    hi2c->dma_init_struct.loop_mode_enable         = FALSE;
    hi2c->dma_init_struct.priority                 = DMA_PRIORITY_LOW;
    hi2c->dma_init_struct.direction                = DMA_DIR_MEMORY_TO_PERIPHERAL;
   
    dma_init(hi2c->dma_tx_channel, &hi2c->dma_init_struct);  
    dma_init(hi2c->dma_rx_channel, &hi2c->dma_init_struct);  
   
    i2c_init(hi2c->i2cx, I2C_FSMODE_DUTY_2_1, I2Cx_SPEED);
   
    i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
  }
}

2. 实现中断函数

void I2Cx_DMA_RX_IRQHandler(void)
{
  i2c_dma_rx_irq_handler(&hi2cx);
}


void I2Cx_DMA_TX_IRQHandler(void)
{
  i2c_dma_tx_irq_handler(&hi2cx);
}

3.调用i2c_config初始化i2c,调用i2c_master_transmit_dma、i2c_slave_receive_dma进行数据收发

int main(void)
{
  i2c_status_type i2c_status;


  /* config nvic priority group */
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);


  system_clock_config();
  
  at32_board_init();
  
  hi2cx.i2cx = I2Cx_PORT;
  
  i2c_config(&hi2cx);
  
  while(1)
  {
   
#if defined (MASTER_BOARD)     
  
    /* wait for key USER_BUTTON press before starting the communication */
    while(at32_button_press() != USER_BUTTON)
    {
    }
   
    /* start the request reception process */  
    if((i2c_status = i2c_master_transmit_dma(&hi2cx, I2Cx_ADDRESS, tx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }
   
    /* wait for the communication to end */  
    if(i2c_wait_end(&hi2cx, I2C_TIMEOUT) != I2C_OK)
    {
      error_handler(i2c_status);
    }
   
    delay_ms(10);
   
    /* start the request reception process */  
    if((i2c_status = i2c_master_receive_dma(&hi2cx, I2Cx_ADDRESS, rx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }
   
    /* wait for the communication to end */  
    if(i2c_wait_end(&hi2cx, I2C_TIMEOUT) != I2C_OK)      
    {
      error_handler(i2c_status);
    }   
   
    if(buffer_compare(tx_buf, rx_buf, BUF_SIZE) == 0)
    {
      at32_led_on(LED3);
    }
    else
    {
      error_handler(i2c_status);
    }
   
#else
   
    /* wait for key USER_BUTTON press before starting the communication */
    while(at32_button_press() != USER_BUTTON)
    {
    }
   
    /* start the transmission process */  
    if((i2c_status = i2c_slave_receive_dma(&hi2cx, rx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }
   
    /* wait for the communication to end */  
    if(i2c_wait_end(&hi2cx, I2C_TIMEOUT) != I2C_OK)   
    {
      error_handler(i2c_status);
    }
   
    if((i2c_status = i2c_slave_transmit_dma(&hi2cx, tx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }
   
    /* wait for the communication to end */  
    if(i2c_wait_end(&hi2cx, I2C_TIMEOUT) != I2C_OK)   
    {
      error_handler(i2c_status);
    }


    if(buffer_compare(tx_buf, rx_buf, BUF_SIZE) == 0)
    {
      at32_led_on(LED3);
    }
    else
    {
      error_handler(i2c_status);
    }
   
#endif
  
  }   
}






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-8 09:24 , Processed in 0.188597 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表