STM32-IIC configuration explanation

Publisher:shmilydeLatest update time:2017-10-25 Source: eefocusKeywords:STM32  IIC Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

STM32-IIC Configuration Explanation (Original) STM32 - I2C Introduction: The I2C bus interface connects the microcontroller and the serial I2C bus. It provides multi-host functionality and controls all I2C bus-specific timing, protocols, arbitration and timing. It supports both standard and fast modes. In addition, the I2C of STM32 can be operated using DMA. This article mainly uses an example to introduce the configuration method of STM32-I2C and which library functions are called in the project to realize the communication of I2C devices . Example: Write data to the device AT24C02 and read the stored data. Let's first talk about the basic configuration of the port of the STM32 I2C module. The STM32 Chinese reference manual can be used to find out which mode the corresponding pin should be configured to when using I2C. Both the SCL and SDA pins are configured as open-drain multiplexed outputs.
I use STM32F103VET6, which has 2 I2C interfaces. The I/O port is defined as PB6-I2C_SCL,
PCB 7-I2C1_SDA; PB10-I2C_SCL, PB11-I2C_SDA. The corresponding port can be found in the manual.
The picture and text are as follows:
Call the library function to configure the I2C port (this article uses PB6 and PB7 ports):
The program code is as follows:

void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO structure definition
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //Enable I2C IO port

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //Open drain output
GPIO_Init(GPIOB, &GPIO_InitStructure); //Initialize structure configuration
}

void I2C_Mode_config(void)
{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); I2C_InitTypeDef

I2C_InitStructure;

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

C_OwnAddress1 =0x0A;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed ​​= 400000; I2C_Init(I2C1, &I2C_InitStructure); } Well, the working mode of the I2C module inside STM32 is set up like this. Next, we need to complete the communication with the external device AT24C02 (EEPROM). The code analysis will be divided into two parts. The first part is: write , and the second part is: read operation to AT24C02. Part 1 (Write): Note: I2C_PageSize is a macro definition #define I2C_PageSize 8 ; void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite) { u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0; Addr = WriteAddr % I2C_PageSize; // Check if the input address is an integer multiple of 8 count = I2C_PageSize - Addr; // Indicates the distance from the first address of the next page (number of steps) NumOfPage = NumByteToWrite / I2C_PageSize; // Calculate how many pages there are in total NumOfSingle = NumByteToWrite % I2C_PageSize; // Calculate the remainder of the data that is not enough for one page if(Addr == 0) // If the input address is the first page address { if(NumOfPage == 0) //If there is less than one page of data { I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//Call the write function, the remainder of NumOfSingle is less than one page as the actual parameterI2C_EE_WaitEepromStandbyState();//Wait for the EEPROM device to complete internal operations } else //If there is more than one page of data { while(NumOfPage--)//Use a while loop to execute the page write loop operation, write as many times as there are pages { I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); //Call the write function, and use the I2C_PageSize variable as the actual parameter to execute page writeI2C_EE_WaitEepromStandbyState ();//Wait for the EEPROM device to complete internal operations



































WriteAddr += I2C_PageSize;//Each time a page write is completed, the corresponding address also needs to be shifted by 8 bits
pBuffer += I2C_PageSize;//The data pointer is shifted by 8 bits
}
if(NumOfSingle!=0)//If there is less than one page of data remainder, execute
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//Call the write function,
the remainder of NumOfSingle that is less than one page is used as the actual parameter
I2C_EE_WaitEepromStandbyState();//Wait for the EEPROM device to complete internal operations
}
}
}
else //The input address is not the home page address
{
if(NumOfPage== 0) //If less than one page
{
I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//Call the write function, NumOfSingle
The remainder that is less than
I2C_EE_WaitEepromStandbyState(); //Wait for the EEPROM device to complete internal operations
}
else //If there is one page or more than one page
{
NumByteToWrite -= count; //Fill the default position after the address with data. The amount of data is the value of count . The value of the NumByteToWrite variable is the number of unsent
data after filling in the data NumOfPage = NumByteToWrite / I2C_PageSize; //Number of remaining pages NumOfSingle = NumByteToWrite % I2C_PageSize; //Number of data less than one page if (count != 0) //Fill the default position after the address with data { I2C_EE_PageWrite(pBuffer, WriteAddr, count); //Call the write function with count as the actual parameter to fill the default part of the address with data I2C_EE_WaitEepromStandbyState(); //Wait for EEPROM The device completes the internal operation WriteAddr += count; //After adding count, the address is shifted to the first address of the next page pBuffer += count; //The data pointer moves count bits } while(NumOfPage--) //Write the remaining pages of data to the EEPROM { I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); //Call the write function and use the I2C_PageSize variable as the actual parameter to perform page write I2C_EE_WaitEepromStandbyState(); //Wait for the EEPROM device to complete the internal operation WriteAddr += I2C_PageSize; //Shift the address by 8 bits pBuffer += I2C_PageSize; //Shift the data pointer by 8 bits } if(NumOfSingle != 0) //Write less than one page of data to the EEPROM { I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); //Call the write function, The remainder of NumOfSingle that is not enough for one page is taken as the actual parameter I2C_EE_WaitEepromStandbyState(); //Wait for the EEPROM device to complete internal operations } } } } In the above write operations, we take the frequently called I2C_EE_PageWrite function and the I2C_EE_WaitEepromStandbyState function and combine them with the STM32 Chinese reference manual pictures and text for comparative analysis . When reading the I2C_EE_PageWrite function, please read it in conjunction with the above timing diagram and the following code! Note: EEPROM_ADDRESS is the device address. You can write it according to your specific device address. For example: #define EEPROM_ADDRESS 0xA0 void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite) { I2C_GenerateSTART(I2C1, ENABLE);//Generate start bitwhile (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //Clear EV5 I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direc ti on_Transmitter);//Send device addresswhile (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //ADDR=1, clear EV6 I2C_SendData(I2C1, WriteAddr); //EEPROM The specific storage address location while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //The shift register is not empty, the data register is empty, EV8 is generated, and sending data to DR can clear the event
















































while(NumByteToWrite--) //Use while loop to send data
{
I2C_SendData(I2C1, *pBuffer); //Send data
pBuffer++; //Data pointer shiftwhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//Clear
EV8
}
I2C_GenerateSTOP(I2C1, ENABLE);//Generate stop signal
}

I2C_EE_WaitEepromStandbyState This function is called after each call to the write operation function.
This function is used to detect whether the EEPROM device has completed the internal write operation, and determine whether the device has completed the operation before proceeding
to the next step! The code is as follows:

void I2C_EE_WaitEepromStandbyState(void)
{
vu16 SR1_Tmp = 0;
do
{
I2C_GenerateSTART(I2C1, ENABLE);//Generate start signal
SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);//Read SR1 register
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//Send device
address clear
event
}while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));//If no
response it means that the EEPROM device is still working until the operation is completed and the loop body is jumped out!
I2C_ClearFlag(I2C1, I2C_FLAG_AF);//Clear AF flag bit
I2C_GenerateSTOP(I2C1, ENABLE); //Generate stop signal
}
Part 2 (Read):
From the above AT24C02 read timing diagram, we can know that the read part needs to generate two start signals
. In addition, the master device sends a NACK after receiving the last byte from the slave device. After receiving the NACK, the slave device
releases control of the SCL and SDA lines; the master device can send a stop/restart condition.
● In order to generate a NACK pulse after receiving the last byte, the ACK bit must be cleared after reading the second-to-last data byte (after
the second-to-last RxNE event).
● In order to generate a stop/restart condition, the software must set the STOP/START bit after reading the second-to-last data byte (after the second-to
-last RxNE event).
● When receiving only one byte, the generation bit of the response and stop
conditions .
Please read the code and the figure together!

void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)//Two
start
{
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //Call library function to detect whether the I2C device
is in BUSY stateI2C_GenerateSTART
(I2C1, ENABLE);//Turn on signalwhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//Clear EV5
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//Write
device addresswhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
Clear EV6
I2C_SendData(I2C1, ReadAddr); //Send the read addresswhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//Clear EV8
I2C_GenerateSTART(I2C1, ENABLE);//Turn on the signalwhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//Clear EV5
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);//Transmit the device address
, the master is readingwhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//Clear
EV6
while(NumByteToRead)
{
if(NumByteToRead == 1)//Enter the if statement when only the last data is left
{
I2C_AcknowledgeConfig(I2C1, DISABLE); //Disable the response bit when there is a data at the end
I2C_GenerateSTOP(I2C1, ENABLE); //Enable the stop bit when there is a data at the end
}
if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) //Read data
{
*pBuffer = I2C_ReceiveData(I2C1);//Call library function to fetch data into pBuffer
pBuffer++; //Pointer shift
NumByteToRead--;//Number of bytes minus 1 
}
}
I2C_AcknowledgeConfig(I2C1, ENABLE);//Enable the acknowledge bit and wait for next communication
}
The STM32-IIC configuration explanation ends here!
If there is anything wrong, please give me more advice and I will correct it in time;
welcome everyone to communicate and learn with me, thank you.

Keywords:STM32  IIC Reference address:STM32-IIC configuration explanation

Previous article:Issues that should be noted when using hardware simulation serial port interrupt processing function in STM32
Next article:STM32 external interrupt usage precautions

Recommended ReadingLatest update time:2024-11-16 13:47

Solar-LED Street Light Solution Based on STM32 MCU
As fossil energy is decreasing and the problem of global warming caused by excessive greenhouse gas emissions is becoming more and more important, people are actively developing various types of renewable energy on the one hand, and advocating green environmental protection technologies for energy conservation and e
[Microcontroller]
Solar-LED Street Light Solution Based on STM32 MCU
STM32 as SPI slave, read data
Background: In a project, one device sends data to another device via the SPI interface, but I need to obtain the SPI data information sent by this device. The SPI of STM32 can be used as a master or a slave. There are relatively few routines for using it as a slave. After several hours of tossing today, I finally got
[Microcontroller]
STM32 NVIC interrupt priority setting
I have been using STM32 to do projects for a while, but I suddenly found that I don’t know anything about NVIC, so today I reviewed the knowledge of NVIC and my own understanding of NVIC interrupt priority settings, hoping to help you:   The setting of NVIC interrupt priority has never been clear;   The specific funct
[Microcontroller]
STM32 timer self-study notes
I have been studying STM32 timers for more than a week, and it is really confusing. The various modes are mainly because we don't know much about the application of the various modes of the timer. However, we can get started quickly with the basic part of the timer. That is, the update event interrupt after the timer
[Microcontroller]
STM32 timer self-study notes
STM32 matrix keyboard input through serial port three output
Configuring Matrix Keyboard Input //PA0~PA3 are push-pull output //PA4~PA7 are pull-up inputs //PA9- RXD PA10- TXD   void  KEY44_Init(void) { //PA0~PA3 are push-pull output   GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_P
[Microcontroller]
STM32 core address mapping description in Cortex
1. Cortex-M3 supports a maximum of 4GB of storage space, and its address mapping relationship is as follows 2. Memory Mapping Example: 256KB Flash 48KB SRAM IROM1 is the on-chip program memory, that is, the integrated Flash memory on the chip. The Flash size of this processor is 256KB, that is, 0x40000
[Microcontroller]
STM32 core address mapping description in Cortex
STM32 program transplantation_Internal flash boot times management
1. Test environment: STM32C8T6 2. Test interface: 3. The serial port uses serial port 1, baud rate 9600 MCU pins------------CH340 pins VCC--------------------VCC GND-------------------GND PA9--------------------RXD   PA10-------------------TXD 1. Function: 1. Use STM32 internal falsh to record the number of boot times
[Microcontroller]
STM32 program transplantation_Internal flash boot times management
stm32 controls mpu9250 nine-axis sensor
1. Hardware  mpu mpu9250  and add a new DMP folder  2. Halib  no  3.          Remember to define the settings and shield some codes, otherwise errors will be reported. At the same time, the baud rate of the host computer should be set and data verification should be turned off.  4. Main #include "mpu.h"#include "mpu9
[Microcontroller]
stm32 controls mpu9250 nine-axis sensor
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号