[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

Recommended ReadingLatest update time:2024-11-23 02:49

(Notes summary) The composition and working principle of the I2C serial bus
Commonly used serial expansion buses include: I2C bus, SPI bus, single bus, Microwire/PLUS. I2C Serial Bus Overview The I2C serial bus is a high-performance serial bus that has the bus arbitration and high-speed and low-speed device synchronization functions required by multi-host systems. The I2C bus has only t
[Microcontroller]
(Notes summary) The composition and working principle of the I2C serial bus
Code and comments for implementing I2C as a slave hardware interrupt on STM32F207
People say that writing drivers is simple. There are usually reference programs on the Internet or demos on the official website. But what if you can't understand the example code? There is really no good way, you can only bite the bullet and spend time studying it yourself. Generally speaking, to understand the cod
[Microcontroller]
Design and implementation of keyboard driver based on I2C bus
With the rapid development of embedded systems, embedded PCs are widely used in many fields. Among them, embedded keyboards, as a human-computer interaction tool, play a very important role. The usual keyboard design adopts an array design. For example, a keyboard with 9 key values ​​requires 6 general I/O ports to ac
[Microcontroller]
Design and implementation of keyboard driver based on I2C bus
I2C display circuit based on P87LPC764 and SAA1064
Introduction: I2C bus is an inter-chip serial transmission bus launched by Philips. It uses two lines, serial data line (SDA) and serial clock line (SCL), to achieve perfect full-duplex synchronous data transmission, which can easily form a multi-machine system and peripheral device expansion system. The I2C bus is
[Microcontroller]
(2) I2c bus SDA\SCL and start and end conditions
I2C uses only two wires (SDA and SCL) to transfer data between devices connected to the bus. Each device is identified by a unique address (whether it is a microprocessor, LCD driver, memory, or keyboard interface), and It can be used as a transmitter or receiver depending on the function of the device. The LCD driver
[Microcontroller]
I2C bus timing simulation based on GAL
\ The FI1200 MK2 series TV signal front-end processor is designed by Philips for RF applications in computer multimedia environments. FI1256 MK2 is a model in this series. It is small in size, compact in structure, stable in performance, can directly demodulate video and audio signals from RF signals, and only
[Analog Electronics]
I2C bus timing simulation based on GAL
STM8L15X Hardware I2C Debug Summary
Recently, I received a project that required the use of hardware I2C on STM8L to communicate with SN3731. The user was a solution provider, and the hardware designer did not leave any test points. He directly soldered the board. During debugging, all ports except the swio port could not be used. The hardware designer
[Microcontroller]
Application of AT24C02 chip on I2C bus
When the I2C bus is transmitting data, the data on the data line must remain stable while the clock signal is at a high level. The high or low level state of the data line is allowed to change only when the signal on the clock line is at a low level.                   Start and stop signals: When the SCL line
[Microcontroller]
Application of AT24C02 chip on I2C bus
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号