STM32软件读写IIC

STM32 的IIC外设

​ STM32的I2C外设可用作通讯的主机及从机,支持100Kbit/s和400Kbit/s的速率,支持7位、10 位设备地址,支持DMA数据传输,并具有数据校验功能。

STM32 的 IIC 架构

STM32的IIC外设

通讯引脚

STM32上的IIC引脚定义

​ I2C 的所有硬件架构都是根据图中左侧SCL线和SDA线展开的(其中的SMBA线用于SMBUS的 警告信号,I2C通讯没有使用)。STM32芯片有多个I2C外设,它们的I2C通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚

IIC的结构体参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
typedef struct
{
  uint32_t I2C_ClockSpeed; 
  uint16_t I2C_Mode;   
  uint16_t I2C_DutyCycle; 
  uint16_t I2C_OwnAddress1;  
  uint16_t I2C_Ack;     
  uint16_t I2C_AcknowledgedAddress;   
    
}I2C_InitTypeDef;

IIC代码参考

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "i2c.h"

//EEPROM设备地址
#define EEPROM_Addr		0xA0


/*
1.初始化IIC相关的GPIO
2.配置IIC外设的工作模式
3.编写IIC写入EEPROM的Byte Write函数
4.编写IIC读取EEPROM的RANDOM Read函数
5.使用Read函数及Write函数进行读写校验
6.编写page write 及seq read函数并校验


*/


void I2C_EE_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	I2C_InitTypeDef I2C_InitStructure;
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C模式
	I2C_InitStructure.I2C_ClockSpeed = 400000; //配置时钟SCL频率
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //2:1
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能应答
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //使用7位地址模式
	I2C_InitStructure.I2C_OwnAddress1 = 0x5f;// STM上I2C自身地址 (自己选择一个7位地址,不要跟其他I2C设备的地址冲突)
	I2C_Init(I2C1, &I2C_InitStructure);
	
	I2C_Cmd(I2C1, ENABLE);
	
	

}



//向EEPROM写入一个字节

void EEPROM_Byte_Write(uint8_t addr, uint8_t data)
{
	
	I2C_GenerateSTART(I2C1, ENABLE); //产生起始信号
	
	//检测EV5事件是否产生
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
	
	//EV5事件被检测到
	I2C_Send7bitAddress(I2C1, EEPROM_Addr, I2C_Direction_Transmitter);
	
	//检测EV6 (和EV8事件)
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR);

	//EV6事件被检测到
	//stm32会把第一个发送的数据认作地址
	I2C_SendData(I2C1, addr);
	
	//检测EV8事件
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING) == ERROR);
	
	//EV8事件被检测到,开始发送数据
	I2C_SendData(I2C1, data);
	
	//检测EV8_2(结束)事件(即数据传输完成)
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR);
	
	//检测到EV8_2事件,产生停止信号
	I2C_GenerateSTOP(I2C1, ENABLE);
	
}


//从EEPROM读取数据
void EEPROM_Read(uint8_t addr, uint8_t *data, uint8_t numByteToRead)	//形参是指针时就可以改变实参
{
	
	I2C_GenerateSTART(I2C1, ENABLE); //产生起始信号
	
	//检测EV5事件是否产生
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
	
	//EV5事件被检测到
	I2C_Send7bitAddress(I2C1, EEPROM_Addr, I2C_Direction_Transmitter);
	
	//检测EV6 (和EV8事件)
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR);

	//EV6事件被检测到
	//stm32会把第一个发送的数据认作地址
	I2C_SendData(I2C1, addr);
	
	//检测EV8事件
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING) == ERROR);
	
	//第二次起始信号
	I2C_GenerateSTART(I2C1, ENABLE); //产生起始信号
	
	//检测EV5事件是否产生
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == ERROR);
	
	//EV5事件被检测到
	I2C_Send7bitAddress(I2C1, EEPROM_Addr, I2C_Direction_Receiver);
	
	//检测EV6 (和EV8事件)
	while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == ERROR);
	
	//检测到EV6事件,会自动接收一个字节

	while(numByteToRead)
	{
		if(numByteToRead == 1)
		{
			//如果是最后一个字节,产生一个非应答信号
			I2C_AcknowledgeConfig(I2C1, DISABLE);
			
		}
		
		//检测EV7事件
		while(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) == ERROR);
		
		//EV7事件被检测到,即数据寄存器有新的有效数据
		*data =I2C_ReceiveData(I2C1);
		data++;   //指针指向下一个字节
		
		
		numByteToRead--;
	}	
	

	//数据传输完成,产生停止信号
	I2C_GenerateSTOP(I2C1, ENABLE);
	
	//结束后,将应答配置默认为使能状态,以便下次通讯
	I2C_AcknowledgeConfig(I2C1, ENABLE);
	
}



void EEPROM_WaitForWriteEnd(void)
{



}
22324
使用 Hugo 构建
主题 StackJimmy 设计