CN / EN
文档反馈
感谢关注汇顶文档,期待您的宝贵建议!
感谢您的反馈,祝您愉快!

I2C ADXL345

I2C ADXL345示例实现了I2C驱动与I2C设备通信,通过I2C向ADXL345发送数据,并从ADXL345读取数据。

I2C ADXL345示例的源代码和工程文件位于SDK_Folder\projects\peripheral\i2c\i2c_master_adxl345,其中工程文件在文件夹Keil_5下。

代码理解

示例工程流程图如图 16所示:

图 16 I2C ADXL345示例工程流程图
  1. 配置I2C模块。

    I2C详细配置参数请参考I2C DMA UART。此示例工程中,speed选择I2C_SPEED_400K,addressing_mode选择I2C_ADDRESSINGMODE_7BIT,general_call_mode选择I2C_GENERALCALL_DISABLE。

  2. I2C硬件初始化。
    void hal_i2c_msp_init(i2c_handle_t *p_i2c)
    {
        gpio_init_t gpio_config = GPIO_DEFAULT_CONFIG;
    
    /*---------------------- Configure the I2C Pins -----------------------*/
        gpio_config.mode = GPIO_MODE_MUX;
        gpio_config.pull = GPIO_PULLUP;
        gpio_config.mux  = I2C_GPIO_MUX;
        gpio_config.pin  = I2C_SCL_PIN | I2C_SDA_PIN;
        hal_gpio_init(I2C_GPIO_PORT, &gpio_config);						  (1)
    
    	/*------------------- Configure the DMA for I2C ------------------*/
        /* Configure the DMA handler for Transmission process */
        s_dma_tx_handle.channel = DMA_Channel0;
        s_dma_tx_handle.init.src_request = DMA_REQUEST_MEM;
        s_dma_tx_handle.init.dst_request = p_i2c->p_instance == I2C0) ? DMA_REQUEST_I2C0_TX : DMA_REQUEST_I2C1_TX;
        s_dma_tx_handle.init.direction = DMA_MEMORY_TO_PERIPH;
        s_dma_tx_handle.init.src_increment = DMA_SRC_INCREMENT;		              	(2)
        s_dma_tx_handle.init.dst_increment = DMA_DST_NO_CHANGE;			              (3)
        s_dma_tx_handle.init.src_data_alignment = DMA_SDATAALIGN_BYTE;		               (4)
        s_dma_tx_handle.init.dst_data_alignment = DMA_DDATAALIGN_BYTE;		               (5)
        s_dma_tx_handle.init.mode = DMA_NORMAL;
        s_dma_tx_handle.init.priority = DMA_PRIORITY_LOW;
    
        hal_dma_deinit(&s_dma_tx_handle);
        hal_dma_init(&s_dma_tx_handle);
    
    /* Associate the initialized DMA handle to the I2C handle */
        __HAL_LINKDMA(p_i2c, p_dmatx, s_dma_tx_handle);						(6)
    
       /* Configure the DMA handler for reception process */
        s_dma_rx_handle.channel = DMA_Channel1;
        s_dma_rx_handle.init.src_request = (p_i2c->p_instance == I2C0) ? DMA_REQUEST_I2C0_RX : DMA_REQUEST_I2C1_RX;
        s_dma_rx_handle.init.dst_request = DMA_REQUEST_MEM;
        s_dma_rx_handle.init.direction = DMA_PERIPH_TO_MEMORY;
        s_dma_rx_handle.init.src_increment = DMA_SRC_NO_CHANGE;			              (7)
        s_dma_rx_handle.init.dst_increment = DMA_DST_INCREMENT;			              (8)
        s_dma_rx_handle.init.src_data_alignment = DMA_SDATAALIGN_BYTE;		               (9)
        s_dma_rx_handle.init.dst_data_alignment = DMA_DDATAALIGN_BYTE;		              (10)
        s_dma_rx_handle.init.mode = DMA_NORMAL;
        s_dma_rx_handle.init.priority = DMA_PRIORITY_LOW;
    
        hal_dma_deinit(&s_dma_rx_handle);
        hal_dma_init(&s_dma_rx_handle);
    
       /* Associate the initialized DMA handle to the the I2C handle */
        __HAL_LINKDMA(p_i2c, p_dmarx, s_dma_rx_handle);	                   	         (11)
    
        /* NVIC for DMA */
        hal_nvic_set_priority(DMA_IRQn, 0, 1);
        hal_nvic_clear_pending_irq(DMA_IRQn);
        hal_nvic_enable_irq(DMA_IRQn);
    
        /* NVIC for I2C */
        hal_nvic_set_priority(I2C_GET_IRQNUM(p_i2c->p_instance), 0, 1);
        hal_nvic_clear_pending_irq(I2C_GET_IRQNUM(p_i2c->p_instance));
        hal_nvic_enable_irq(I2C_GET_IRQNUM(p_i2c->p_instance));}
    

    具体流程说明如下:

    (1):硬件IO初始化,将I2C映射的引脚配置为I2C模式。

    (2)~(5):配置TX DMA通道源和目标的地址增长模式和传输单元位宽。I2C TX通道源为RAM内数组,地址为自增模式;目标为I2C TX FIFO地址,地址不需要增长。I2C TX通道的传输单元位宽为8 bits。

    (6):将TX DMA通道句柄注册进I2C实例句柄内。

    (7)~(10):配置RX DMA通道源和目标的地址增长模式和传输单元位宽。I2C RX通道源为I2C RX FIFO地址,地址不需要增长;目标为RAM内数组,地址为自增模式。I2C RX通道的传输单元位宽为8 bits。

    (11):将RX DMA通道句柄注册进I2C实例句柄内。

  3. 用户需根据不同I2C设备在I2C驱动中实现设备的读写操作。代码如下:
    void i2c_write_adxl345(uint8_t reg_addr, uint8_t *buf, uint8_t size)
    {
        uint8_t wdata[256] = {0};
    
        wdata[0] = reg_addr;
        memcpy(&wdata[1], buf, size);
        hal_i2c_master_transmit(&g_i2c_handle, SLAVE_DEV_ADDR, wdata, size + 1, 5000);
    }
    
    void i2c_read_adxl345(uint8_t reg_addr, uint8_t *buf, uint8_t size)
    {
        uint8_t wdata[1] = {0};
    
        wdata[0] = reg_addr;
        hal_i2c_master_transmit(&g_i2c_handle, SLAVE_DEV_ADDR, wdata, 1, 5000);
        hal_i2c_master_receive(&g_i2c_handle, SLAVE_DEV_ADDR, buf, size, 5000);
    }
    

测试验证

  1. 用GProgrammer下载i2c_master_adxl345至开发板。
  2. 将开发板串口连接至PC端,打开并配置GRUart。
  3. 在GRUart的Receive Data窗口中将会显示通过I2C向ADXL345传感器发送数据,并从ADXL345传感器读取数据并打印ADXL345数据的执行过程。

扫描关注

打开微信,使用“扫一扫”即可关注。