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
/********************************************************************************
* @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);
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
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- EEWORLD University - What is an antenna vibrator?
- Selling new and second-hand Xilinx development boards, both high-end and low-end
- [RISC-V MCU CH32V103 Review] First Look at CH32V103
- May was quite busy, and my hand broke.
- Important parameters of Rfid technology
- Pre-registration for the prize-winning live broadcast | Infineon system solutions make electric motorcycle design more reliable and efficient!
- Embedded systems and real-time software development
- What methods do you generally use to recruit or find jobs? Which platform is used more often?
- Summary of the points to note when using CCS8.0 to program MSP430G2553
- picture