STM32 I2C Slave (SMBUS) mode software reference design

Publisher:EuphoricVoyageLatest update time:2019-04-02 Source: eefocusKeywords:STM32  I2C  Slave  SMBUS Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Everyone is familiar with I2C, which has two lines, CLK and DATA. I believe everyone is more familiar with stm32's I2C. It uses the writing controller method, and the controller directly completes the I2C timing operation. Users do not need to care about the specific logic generated. However, in most cases, the I2C Master mode is used, that is, the master device mode, and it is rarely used as the slave mode. This article talks about how to use stm32 I2C as a slave mode. More strictly speaking, this article talks about the smbus mode.


From the official website stm32 manual, we found the difference between smbus and I2C, you can understand it by yourself:



When actually using it, you can set and use smbus as I2C. From the code, except that the I2C Clock is set to 20K, there is no obvious difference. The following is the setting of I2C smbus mode:


void IIC_Init(void)  

 

{  

 

  GPIO_InitTypeDef GPIO_InitStructure;  

 

  I2C_InitTypeDef I2C_InitStructure;  

 

  

 

//  RCC_APB2PeriphClockCmd  (RCC_APB2Periph_GPIOB , ENABLE);  

 

  

 

   /* Configure I2C1 pins: SCL and SDA */   

 

   GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_6|GPIO_Pin_7; //6:SCL 7:SDA  

 

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

 

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//Out_PP;  

 

   GPIO_Init(GPIOB, &GPIO_InitStructure);   

 

   

 

//   RCC_APB1PeriphClockCmd  (RCC_APB1Periph_I2C1, ENABLE);   

 

   

 

   // Initialize I2C1 clock

 

   // Reset I2C1 device clock in order to avoid non-cleared error flags

 

   //__I2C_RCC_RESET(CPAL_I2C_CLK [Device]);

 

   RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1,ENABLE);

 

   RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1,DISABLE);

 

   // Enable I2C1 device clock

 

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);

 

   

 

   I2C_DeInit(I2C1);  

 

   I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusDevice;  

 

   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  

 

   I2C_InitStructure.I2C_OwnAddress1 = 0x76;//slave addr  

 

   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  

 

   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  

 

   I2C_InitStructure.I2C_ClockSpeed ​​= 20000;//20K

 

   I2C_Init(I2C1, &I2C_InitStructure);  

 

   I2C_ITConfig(I2C1, I2C_IT_EVT|I2C_IT_BUF, ENABLE);  

 

   I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);

 

   I2C_Cmd(I2C1,ENABLE);  

 

   

 

}  

 


void NVIC_Configuration(void)  

 

{  

 

  NVIC_InitTypeDef NVIC_InitStructure;  

 

 

 

     /* Configure and enable I2Cx event interrupt -------------------------------*/  

 

    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;  

 

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  

 

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

 

    NVIC_Init(&NVIC_InitStructure);  

 

  

 

}  

From the above code, we can see that I2C initializes I2C IO mapping, working mode I2C_Mode_SMBusDevice, slave address 0x76 (customizable), I2C Clock, I2C interrupt vector and other parameters. After the settings are completed, whenever I2C generates data, an IRQ interrupt will be generated and the interrupt processing function I2C1_EV_IRQn will be entered, as shown below:


void I2C1_EV_IRQHandler(void)  

 

{  

 

uint32_t  I2CFlagStatus;  

 

static uint8_t IIC_Data=0;

 

 

 

I2CFlagStatus = I2C_GetLastEvent(I2C1);  // =>  (SR2<<16|SR1)  

 

 

 

// print_info("I2CFlagStatus=0x%x rn",I2CFlagStatus);

 

IIC1_EV_INT_Flag=1;

 

IIC_Get_Data_Flag=1;

 

 

 

if ((I2CFlagStatus & I2C_SR1_ADDR) != 0)//bit1:addr matched  

 

{

 

//print_info("4rn");

 

if(I2CFlagStatus & I2C_SR1_TXE) //bit7 Data register empty (transmitters)  

 

{//read          

 

   Rx_Idx=0;

 

   Tx_Idx = 0;    

 

   I2C_SendData(I2C1, I2C_Buffer_Tx[Tx_Idx]);

 

}

 

else

 

{   

 

}  

 

}

 

 

 

else if((I2CFlagStatus & I2C_SR1_RXNE) != 0)//bit6  RxNE    -Data register not empty (receivers))  

 

{

 

IIC_Data=I2C_ReceiveData(I2C1);

 

I2C_Buffer_Rx[Frame_Idx][Rx_Idx] = IIC_Data;

 

Rx_Idx++;

 

}

 

else if((I2CFlagStatus & I2C_SR1_STOPF) != 0)//bit4  STOPF -Stop detection (slave mode)  

 

{

 

//I2C_Buffer_Rx[0] = num-1;      

 

I2C1->CR1 |= 0x1000;//CR1_PEC_Set;  

 

Rx_Idx_t=Rx_Idx;

 

Rx_Idx=0;

 

Frame_Idx++;

 

I2C1->SR1=0;  

 

I2C1->SR2=0;  

 

}

 

else

 

{  

 

}  

 

}  

 


In the interrupt handling function, after an interrupt is generated, the flag bit IIC_Get_Data_Flag is set to 1, and the current I2C status is obtained according to the read I2CFlagStatus status bit, and the data is obtained. Then, in the main function, the data generated by I2C is processed according to the flag bit. After the processing is completed, the IIC_Get_Data_Flag flag bit is set to 0. This is a good way to process data. (PS: The interrupt handling function cannot handle too complex and time-consuming transactions, so as not to affect the real-time nature of the interrupt response, so the data processing process is placed in the main function)


Keywords:STM32  I2C  Slave  SMBUS Reference address:STM32 I2C Slave (SMBUS) mode software reference design

Previous article:STM32 GPIO and the first STM32 program (marquee)
Next article:STM32CubeMX learning tutorial 10: Hardware I2C reading and writing AT24C02

Recommended ReadingLatest update time:2024-11-16 20:51

STM8L051F3 Hardware I2C Slave Example
This article is written at a relatively novice level for reference by novices, so I will try to write it in detail. 1. First we need to check the data sheet to see which port the hardware I2C interface is. I use the STM8L051F3 chip. The I2C of this chip should not be able to reuse other ports. Anyway, I didn't fin
[Microcontroller]
STM8L051F3 Hardware I2C Slave Example
When debugging STM32 programs, some flags are accidentally cleared by the debugging software
During debugging, the status of peripheral registers can be easily viewed using the register or memory display window of the debugging software. Many friends have encountered this problem: they cannot see the changes of certain flag bits in the display window during single-step debugging. When these flag bits should
[Microcontroller]
Detailed explanation of stm32 standard library dma initialization
 STM32's DMA has three types of transfers 1.MM (memory to memory)  2.MP (memory to peripherals) 3.PM (Peripheral to Memory)    The standard library function of STM32 provides an STM32 initialization structure as follows; typedef struct {   uint32_t DMA_PeripheralBaseAddr; //Peripheral address   uint32_t DMA_MemoryBas
[Microcontroller]
Detailed explanation of stm32 stack
1. Heap and stack size   Define the size in startup_stm32f2xx.s Stack_Size           EQU          0x00000400                                AREA       STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem             SPACE     Stack_Size __initial_sp ; Heap Configuration ;        Heap Size (in Bytes) 0x0-0xFFFFFFFF:8
[Microcontroller]
Detailed explanation of stm32 stack
STMicroelectronics adds support for deep quantized neural networks to STM32Cube.AI development tool
STMicroelectronics (ST) has released STM32Cube.AI version 7.2.0, the microcontroller vendor’s first artificial intelligence (AI) development tool supporting ultra-efficient deep quantized neural networks.  STM32Cube.AI converts pre-trained neural networks into C language code that can be run by STM32 microcontro
[Internet of Things]
STMicroelectronics adds support for deep quantized neural networks to STM32Cube.AI development tool
STM32 AD DMA mode
Directly on the code: //Variable definition__IO uint16_t ADCConvertedValue ; //ADC peripheral data register #define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC_DR (ADC rule data register), offset = 0x4c ADC1(0x40012400-0x400127ff) //ADC1_GPIO configuration void ADC1_GPIO_Configuration(void) {   GPIO_InitTypeDef G
[Microcontroller]
STM32 TIMx configuration
Firmware Library V3.5 IAR   void NVIC_Configuration(void) {   /***********************Timer 2 interrupt**********************************/   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//Enable or disable the specified IRQ channelNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority   = 3;//Set the preempti
[Microcontroller]
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号