[MCU framework][bsp layer][cx32l003][bsp_i2c] I2C/IIC hardware configuration and use

Publisher:RadiantEnergyLatest update time:2022-09-21 Source: csdn Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Introduction to I2C

I2C is a two-wire bidirectional serial bus that provides a simple and efficient method for exchanging data between devices. The I2C standard is a true multi-host bus with conflict detection and arbitration mechanisms. It prevents data conflicts when two or more hosts request control of the bus at the same time.


The I2C bus controller can meet various specifications of the I2C bus and support all transmission modes for communicating with the I2C bus.


The I2C bus uses "SCL" (serial clock bus) and "SDA" (serial data bus) to transmit information between connected devices. Data is transmitted synchronously byte by byte on the SDA data line through the SCL clock line control between the master and the slave. Each byte is 8 bits long. One SCL clock pulse transmits one data bit. Data is transmitted starting from the highest bit MSB. Each transmitted byte is followed by an acknowledge bit. Each bit is sampled when SCL is high; therefore, the SDA line can only change when SCL is low, and SDA remains stable when SCL is high. When SCL is high, the jump on the SDA line is regarded as a command interrupt (START or STOP), and the I2C logic can handle the transmission of bytes autonomously. It can keep track of the serial transmission, and there is also a status register (I2C_SR) that reflects the status of the I2C bus controller and the I2C bus.


I2C Key Features

The I2C controller supports the following features:

⚫ Support four working modes: host send/receive, slave send/receive

⚫ Support three working speeds: standard (100Kbps)/fast (400Kbps)/high speed (1Mbps)

⚫ Support 7-bit addressing function

⚫ Support noise filtering function

⚫ Support broadcast address

⚫ Support interrupt status query function


I2C Protocol Description

Usually the standard I2C transmission protocol consists of four parts:


Start signal or repeated start signal


Slave address transmission and R/W bit transmission


data transmission


Stop signal


insert image description here
insert image description here


/********************************************************************************

* @file    bsp_i2c.c

* @author jianqiang.xue

* @version V1.0.0

* @date    2021-04-11

* @brief   NULL

********************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include

#include


#include "RTE_Components.h"

#include CMSIS_device_header

#include "cx32l003_hal.h"


#include "bsp_gpio.h"

#include "bsp_i2c.h"


/* Private Includes ----------------------------------------------------------*/

#include "business_gpio.h"

#include "business_function.h"


/* Private Variables ---------------------------------------------------------*/

#if BS_I2C0_EN

// Define IIC0 information handle

static I2C_HandleTypeDef i2c0_handle_t = {

    .Instance        = I2C,

    .Init.master = I2C_MASTER_MODE_ENABLE, // Master mode enable

    .Init.slave = I2C_SLAVE_MODE_DISABLE, // Slave mode disabled

    .Mode = HAL_I2C_MODE_MASTER, // Master mode

    .Init.broadack = I2C_BROAD_ACK_DISABLE, // Broadcast address response disabled

    .Init.speedclock = BS_I2C0_SPEED_RATE, // I2C transfer rate

    .State           = HAL_I2C_STATE_RESET

};

#endif


/**

 * @brief [Initialization] IIC initialization

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @retval None

 */

void bsp_i2c_init(bsp_i2c_bus_t i2c_bus)

{

#if BS_I2C0_EN

    if (i2c_bus == I2C_BUS0)

    {

        __HAL_RCC_I2C_CLK_ENABLE();

        BS_I2C0_SDA_GPIO_CLK_ENABLE();

        bsp_gpio_init_i2c(BS_I2C0_SCL_GPIO_PORT, BS_I2C0_SCL_PIN, GPIO_AF4_I2C_SCL);

        bsp_gpio_init_i2c(BS_I2C0_SDA_GPIO_PORT, BS_I2C0_SDA_PIN, GPIO_AF4_I2C_SDA);

        HAL_I2C_Init(&i2c0_handle_t);

    }

#endif

}


/**

 * @brief [Deinitialization] IIC turns off the clock and resets the pin

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @retval None

 */

void bsp_i2c_deinit(bsp_i2c_bus_t i2c_bus)

{

#if BS_I2C0_EN

    if (i2c_bus == I2C_BUS0)

    {

        __HAL_RCC_I2C_CLK_DISABLE();

        bsp_gpio_deinit(BS_I2C0_SCL_GPIO_PORT, BS_I2C0_SCL_PIN);

        bsp_gpio_deinit(BS_I2C0_SDA_GPIO_PORT, BS_I2C0_SDA_PIN);

        HAL_I2C_DeInit(&i2c0_handle_t);

    }

#endif

}


/**

 * @brief i2c read a byte

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param dev_addr: device address

 * @param reg_addr: register address

 * @param r_data: pointer to the data header to be sent

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_read_byte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t reg_addr, uint8_t *r_data)

{

    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        return HAL_I2C_Master_Receive(&i2c0_handle_t, dev_addr, ®_addr, 1, r_data, 1);

#else

        return HAL_ERROR;

#endif

    }

    return HAL_ERROR;

}


/**

 * @brief i2c read multiple bytes

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param dev_addr: device address

 * @param w_data: txbuff header pointer data format: (reg_addr, w_data, w_data1, ...)

 * @param w_size: txbuff length

 * @param r_data: rxbuff head pointer

 * @param r_size: size of rxbuff

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_read_nbyte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t *w_data, uint16_t w_size, uint8_t *r_data, uint16_t r_size)

{

    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        return HAL_I2C_Master_Receive(&i2c0_handle_t, dev_addr, w_data, w_size, r_data, r_size);

#else

        return HAL_ERROR;

#endif

    }

    return HAL_ERROR;

}


/**

 * @brief i2c write a byte

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param dev_addr: device address

 * @param reg_addr: register address

 * @param w_data: byte value to be written

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_write_byte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t reg_addr, uint8_t w_data)

{

    uint8_t right = HAL_OK;


    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        uint8_t data[2] = {reg_addr, w_data};

        ret = HAL_I2C_Master_Transmit(&i2c0_handle_t, dev_addr, data, 2);

#else

        right = HAL_ERROR;

#endif

    }

    else

    {

        right = HAL_ERROR;

    }

    return right;

}


/**

 * @brief i2c write multiple bytes

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param dev_addr: device address

 * @param w_data: txbuff header pointer data format: (reg_addr, w_data, w_data1, ...)

 * @param w_size: txbuff length

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_write_nbyte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t *w_data, uint16_t w_size)

{

    uint8_t right = HAL_OK;


    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        ret = HAL_I2C_Master_Transmit(&i2c0_handle_t, dev_addr, w_data, w_size);

#else

        right = HAL_ERROR;

#endif

    }

    else

    {

        right = HAL_ERROR;

    }

    return right;

}


// ---------------------Bulk function-----------------------------

/**

 * @brief i2c write multiple bytes without stop signal (with start signal and device address)

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param dev_addr: device address

 * @param w_data: txbuff header pointer data format: (reg_addr, w_data, w_data1, ...)

 * @param w_size: txbuff length

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_write_nbyte_nostop(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t *w_data, uint16_t w_size)

{

    uint8_t right = HAL_OK;


    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        ret = HAL_I2C_Master_Transmit_NOStop(&i2c0_handle_t, dev_addr, w_data, w_size);

#else

        right = HAL_ERROR;

#endif

    }

    else

    {

        right = HAL_ERROR;

    }

    return right;

}


/**

 * @brief i2c write multiple bytes without stop signal (without start signal and device address)

 * @note Must be used with [bsp_i2c_write_nbyte_nostop()]

 * @param i2c_bus: IIC group number

 * @param w_data: txbuff header pointer data format: (w_data, w_data1, ...)

 * @param w_size: txbuff length

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_send_nbyte(bsp_i2c_bus_t i2c_bus, uint8_t *w_data, uint16_t w_size)

{

    uint8_t right = HAL_OK;

    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        uint16_t i = 0;

        uint32_t i2c_flag = 0XFF;

        HAL_I2C_Wait_Flag(&i2c0_handle_t, &i2c_flag);

        while (i < w_size)

        {

            i2c_flag = 0XFF;

            HAL_I2C_Send_Byte(&i2c0_handle_t, w_data[i]);

            HAL_I2C_Wait_Flag(&i2c0_handle_t, &i2c_flag);

            if (i2c_flag != I2C_FLAG_MASTER_TX_DATA_ACK) // 0x00000028U

            {

                i2c0_handle_t.State = HAL_I2C_STATE_ERROR;

                i2c0_handle_t.ErrorCode = i2c0_handle_t.PreviousState;

                return HAL_ERROR;

            }

            i++;

        }

#else

        right = HAL_ERROR;

#endif

    }

    else

    {

        right = HAL_ERROR;

    }

    return right;

}


/**

 * @brief Send a stop signal

 * @note   NULL

 * @param i2c_bus: IIC group number

 * @param state: false--clear the interrupt flag true--do not clear the interrupt flag

 * @retval 0--success 1--failure

 */

uint8_t bsp_i2c_stop(bsp_i2c_bus_t i2c_bus, bool state)

{

    uint8_t right = HAL_OK;


    if (i2c_bus == I2C_BUS0)

    {

#if BS_I2C0_EN

        HAL_I2C_Stop_Config(&i2c0_handle_t, (FunctionalState)true);

#else

        right = HAL_ERROR;

#endif

    }

    else

    {

        right = HAL_ERROR;

    }

    return right;

}


/********************************************************************************

* @file    bsp_i2c.h

* @author jianqiang.xue

* @version V1.0.0

* @date    2021-04-11

* @brief   NULL

********************************************************************************/


#ifndef __BSP_I2C_H

#define __BSP_I2C_H


/* Includes ------------------------------------------------------------------*/

#include

#include


/* Public enum ---------------------------------------------------------------*/

typedef enum

{

    I2C_BUS0 = 0,

    I2C_BUS1 = 1,

    I2C_BUS2 = 2,

} bsp_i2c_bus_t;


/* Public Function Prototypes ------------------------------------------------*/


void bsp_i2c_init(bsp_i2c_bus_t i2c_bus);

void bsp_i2c_deinit(bsp_i2c_bus_t i2c_bus);


// Finished product complete set of logic start-response-data-stop


uint8_t bsp_i2c_read_byte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t reg_addr, uint8_t *r_data);

uint8_t bsp_i2c_read_nbyte(bsp_i2c_bus_t i2c_bus, uint8_t dev_addr, uint8_t *w_data, uint16_t w_size, uint8_t *r_data, uint16_t r_size);

[1] [2]
Reference address:[MCU framework][bsp layer][cx32l003][bsp_i2c] I2C/IIC hardware configuration and use

Previous article:[MCU framework][BSP layer][cx32l003][bsp_tim] TIM timer configuration and use
Next article:[MCU framework][bsp layer][cx32l003][bsp_crc] Hardware CRC configuration and use

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号