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)
{
}
|