STM32 notes-IIC

IIC

principle

I2C (IIC, Inter-Integrated Circuit), a two-wire serial bus, was developed by PHILIPS to connect microcontrollers and their peripherals. It is a serial bus composed of data line SDA and clock SCL, which can send and receive data. Two-way transmission is carried out between the CPU and the controlled IC, and between the IC and the IC, and the high-speed IIC bus can generally reach 400kbps.
Insert picture description here

protocol

Idle state
Start signal
Stop signal
Reply signal
Data validity
Data transmission

  1. Idle state When
    the SDA and SCL signal lines of the I2C bus are at the high level at the same time, it is defined as the idle state of the bus. At this time, the output-stage FETs of each device are in an off state, that is, the bus is released, and the level is pulled high by the respective pull-up resistors of the two signal lines.
    Insert picture description here
    The blue areas in the figure are all high

  2. Start signal
    When SCL is high, SDA jumps from high to low; the start signal is a level jump timing signal, not a level signal.
    Insert picture description here

  3. Stop signal
    Stop signal: When SCL is high, SDA transitions from low to high; the stop signal is also a level transition timing signal, not a level signal.
    Insert picture description here
    Blue line in the figure

  4. Data validity When the
    I2C bus is transmitting data, the data on the data line must remain stable during the high level of the clock signal. Only during the low level period of the clock line, the high or low level of the data line Changes are allowed in the flat state.
    That is: the data needs to be prepared before the rising edge of SCL arrives. And it must be stable before the falling edge.
    Insert picture description here

  5. Response signal ACK
    Each time the transmitter sends a byte, it releases the data line during the clock pulse 9, and the receiver feeds back a response signal. When the response signal is low, it is defined as a valid response bit (ACK for short), indicating that the receiver has successfully received the byte; when the response signal is high, it is defined as a non-acknowledge bit (NACK), which generally means receiving The receiver failed to receive the byte.
    The requirement for feedback of the valid acknowledge bit ACK is that the receiver pulls the SDA line low during the low level period before the 9th clock pulse, and ensures that it is a stable low level during the high level period of the clock. If the receiver is the master, after it receives the last byte, it sends a NACK signal to notify the controlled transmitter to end data transmission and release the SDA line so that the master receiver sends a stop signal P.

to sum up

  • It is stipulated that if one byte is sent, an answer signal must be received; similarly, if one byte is received, an answer signal must be sent.
  • Specify response signal: low level is a valid response (that is, a byte of data is normally received), high level is an invalid response, also called non-response (that is, accepting byte exceptions, or used to end acceptance)

Code

What I used is the STM23407 series chip, and used the library function development, it is simple and easy to understand, the reader can change the pin according to the principle by oneself.

#include "iic.h"
#include "delay.h"

#define SCL  		PBout(8)
#define SDA_OUT  	PBout(9)
#define SDA_IN  	PBin(9)

/*
引脚说明:
	PB8 -- SCL
	PB9 -- SDA
*/

void Iic_Init(void)
{
    
    
	GPIO_InitTypeDef  GPIO_InitStruct;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);	//开启GPIOB时钟
	
	//配置PB8 9引脚
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_8|GPIO_Pin_9;		//引脚8 9
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_OUT;		//输出模式
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP;		//推挽输出
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz; 	//速度50MHz
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;     	//上拉电阻
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	//总线空闲
	SCL = 1;
	SDA_OUT = 1;
}

//SDA模式
void Iic_Sda_Mode(GPIOMode_TypeDef Mode)
{
    
    
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_9;		//引脚9
	GPIO_InitStruct.GPIO_Mode	= Mode;	
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP;	//推挽
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz; //快速
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;     //上拉
	GPIO_Init(GPIOB, &GPIO_InitStruct);
}

//开始信号
void Iic_Start(void)
{
    
    
	Iic_Sda_Mode(GPIO_Mode_OUT); //SDA为输出模式

	//总线空闲 SCL SDA都为高电平
	SCL = 1;				
	SDA_OUT = 1;
	delay_us(5);
	
	SDA_OUT = 0; //启动信号
	delay_us(5);
	SCL = 0;  //钳住总线
}

//停止信号
void Iic_Stop(void)
{
    
    
	Iic_Sda_Mode(GPIO_Mode_OUT);//SDA为输出模式
	
	SCL = 0;			
	SDA_OUT = 0;
	delay_us(5);	
	
	SCL = 1;
	delay_us(5);
	SDA_OUT = 1;
}

//发送一位数据 用来发ack应答信号
void Iic_Send_Ack(u8 ack)
{
    
    
	Iic_Sda_Mode(GPIO_Mode_OUT);
	
	SCL = 0;
	//准备数据
	if(ack == 1)//要发数据1
	{
    
    
		SDA_OUT = 1;	 //引脚输1
	}
	//要发数据0
	if(ack == 0)
	{
    
    
		SDA_OUT = 0;	 //引脚输0
	}	
	
	delay_us(5);
	SCL = 1;
	delay_us(5);
	SCL = 0;

}

//发一个字节
void Iic_Send_Byte(u8 data)
{
    
    
	u8 i;
	Iic_Sda_Mode(GPIO_Mode_OUT);
	
	SCL = 0;
	
	for(i=0; i<8; i++)
	{
    
    
		//准备数据 如数据 0x87 1 0 0 0 0 1 1 1 
		if(data & (1<<(7-i)))  
		{
    
    
			SDA_OUT = 1;	 //引脚输1
		}
		//要发数据0
		else
		{
    
    
			SDA_OUT = 0;	 //引脚输0
		}	
		delay_us(5);
		SCL = 1;
		delay_us(5);
		SCL = 0;
	}
}

//接受一位数据
u8 Iic_Recv_Ack(void)
{
    
    
	u8 ack = 0;
	Iic_Sda_Mode(GPIO_Mode_IN);
	
	SCL = 0;
	delay_us(5);
	SCL = 1;
	delay_us(5);
	if(SDA_IN == 1) //判断引脚电平是否为高电平
	{
    
    
		ack = 1;
	}
	if(SDA_IN == 0) //判断引脚电平是否为低电平
	{
    
    
		ack = 0;
	}	
	
	SCL = 0;

	return ack;
}

//接受一个字节
u8 Iic_Recv_Byte(void)
{
    
    
	u8 i, data = 0;  //0 0 0 0 0 0 0 0
	Iic_Sda_Mode(GPIO_Mode_IN);
	
	SCL = 0;
	//循环8次,接受一个字节
	for(i=0; i<8; i++)
	{
    
    	
		delay_us(5);
		SCL = 1;
		delay_us(5);
		if(SDA_IN == 1) //判断引脚电平是否为高电平
		{
    
    
			data |= (1<<(7-i));
		}
		
		SCL = 0;
	}
	return data;
}	

We have completed the above IIC protocol code, and we can use these codes to use hardware such as OLED, AT24C02.

Guess you like

Origin blog.csdn.net/weixin_46026429/article/details/108521318