在之前的使用I2C的经历中,主要是I2C死锁问题让我也困扰了一段时间。不过后来经过多方资料,最后还是把这个问题解决了。以下驱动程序已集成了此功能。
什么是死锁,在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。 而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电 平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种 死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导 致I2C总线进入死锁状态。
解决死锁问题,我主要总结出两点:
1,连接MCU和I2C从机的复位引脚。(保证同时复位)
2,通过图1官方所述进行软件复位。
图1:
如果您所选的芯片符合如下时序,那么就可以使用这个驱动程序。
图2:
这里对本驱动程序进行说明,主驱动程序主要使用中断的方式进行数据发送,官方列程是使用的DMA方式,在大数据量传送时使用DMA还是比较好的,这里使用中断方式,主要是为了方便操作。如果是小数据大量传送时,中断方式要更高效。
打开I2C
void BSP_I2cOpen(uint8_t I2C_x, uint32_t clockSpeed);
关闭I2C
void BSP_I2cClose(uint8_t I2C_x);
向I2C从设备写数据
uint32_t BSP_I2cWrite(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t writeAddress, uint16_t writeLen);
从I2C从设备读数据
uint32_t BSP_I2cRead(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t readAddress, uint16_t readLen);
读取I2C总线空闲状态
uint32_t BSP_I2cIdleState(uint8_t I2C_x);
1 /*
2 ********************************************************************************
3 *
4 * BSP_I2c.c
5 *
6 * File : BSP_I2c.c
7 * Version : V1.0
8 * Author : whq
9 * Mode : Thumb2
10 * Toolchain :
11 * Description : STM32F4xx I2C驱动程序
12 *
13 * History :
14 * Date : 2013.07.24
15 *******************************************************************************/
16
17 #include
18
19 #include "misc.h"
20 #include "stm32f4xx_i2c.h"
21 #include "stm32f4xx_gpio.h"
22 #include "stm32f4xx_rcc.h"
23
24 #include "BSP_I2c.h"
25
26
27 static void _I2cTxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam);
28 static void _I2cRxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam);
29
30
31 static I2C_PARAM_TYPE I2C_PARAM[I2Cn] = {0};
32
33 static I2C_TypeDef* const I2C_NUM[I2Cn] = {
34 #if I2C_1_EN
35 BSP_I2C1,
36 #endif
37 #if I2C_2_EN
38 BSP_I2C2,
39 #endif
40 #if I2C_3_EN
41 BSP_I2C3,
42 #endif
43 };
44 static const uint32_t I2C_CLK[I2Cn] = {
45 #if I2C_1_EN
46 BSP_I2C1_CLK,
47 #endif
48 #if I2C_2_EN
49 BSP_I2C2_CLK,
50 #endif
51 #if I2C_3_EN
52 BSP_I2C3_CLK,
53 #endif
54 };
55
56 static const uint32_t I2C_AF_PORT[I2Cn] = {
57 #if I2C_1_EN
58 BSP_I2C1_AF_Port,
59 #endif
60 #if I2C_2_EN
61 BSP_I2C2_AF_Port,
62 #endif
63 #if I2C_3_EN
64 BSP_I2C3_AF_Port,
65 #endif
66 };
67 static const uint8_t I2C_SCL_AF_Source[I2Cn] = {
68 #if I2C_1_EN
69 BSP_I2C1_SCL_AF_Source,
70 #endif
71 #if I2C_2_EN
72 BSP_I2C2_SCL_AF_Source,
73 #endif
74 #if I2C_3_EN
75 BSP_I2C3_SCL_AF_Source,
76 #endif
77 };
78 static const uint8_t I2C_SDA_AF_Source[I2Cn] = {
79 #if I2C_1_EN
80 BSP_I2C1_SDA_AF_Source,
81 #endif
82 #if I2C_2_EN
83 BSP_I2C2_SDA_AF_Source,
84 #endif
85 #if I2C_3_EN
86 BSP_I2C3_SDA_AF_Source,
87 #endif
88 };
89
90 static GPIO_TypeDef* const I2C_SCL_PORT[I2Cn] = {
91 #if I2C_1_EN
92 BSP_I2C1_SCL_GPIO_PORT,
93 #endif
94 #if I2C_2_EN
95 BSP_I2C2_SCL_GPIO_PORT,
96 #endif
97 #if I2C_3_EN
98 BSP_I2C3_SCL_GPIO_PORT,
99 #endif
100 };
101 static const uint32_t I2C_SCL_CLK[I2Cn] = {
102 #if I2C_1_EN
103 BSP_I2C1_SCL_GPIO_CLK,
104 #endif
105 #if I2C_2_EN
106 BSP_I2C2_SCL_GPIO_CLK,
107 #endif
108 #if I2C_3_EN
109 BSP_I2C3_SCL_GPIO_CLK,
110 #endif
111 };
112 static const uint16_t I2C_SCL_PIN[I2Cn] = {
113 #if I2C_1_EN
114 BSP_I2C1_SCL_PIN,
115 #endif
116 #if I2C_2_EN
117 BSP_I2C2_SCL_PIN,
118 #endif
119 #if I2C_3_EN
120 BSP_I2C3_SCL_PIN,
121 #endif
122 };
123
124 static GPIO_TypeDef* const I2C_SDA_PORT[I2Cn] = {
125 #if I2C_1_EN
126 BSP_I2C1_SDA_GPIO_PORT,
127 #endif
128 #if I2C_2_EN
129 BSP_I2C2_SDA_GPIO_PORT,
130 #endif
131 #if I2C_3_EN
132 BSP_I2C3_SDA_GPIO_PORT,
133 #endif
134 };
135 static const uint32_t I2C_SDA_CLK[I2Cn] = {
136 #if I2C_1_EN
137 BSP_I2C1_SDA_GPIO_CLK,
138 #endif
139 #if I2C_2_EN
140 BSP_I2C2_SDA_GPIO_CLK,
141 #endif
142 #if I2C_3_EN
143 BSP_I2C3_SDA_GPIO_CLK,
144 #endif
145 };
146 static const uint16_t I2C_SDA_PIN[I2Cn] = {
147 #if I2C_1_EN
148 BSP_I2C1_SDA_PIN,
149 #endif
150 #if I2C_2_EN
151 BSP_I2C2_SDA_PIN,
152 #endif
153 #if I2C_3_EN
154 BSP_I2C3_SDA_PIN,
155 #endif
156 };
157
158 static const uint32_t I2C_IRQn[I2Cn] = {
159 #if I2C_1_EN
160 BSP_I2C1_IRQn,
161 #endif
162 #if I2C_2_EN
163 BSP_I2C2_IRQn,
164 #endif
165 #if I2C_3_EN
166 BSP_I2C3_IRQn,
167 #endif
168 };
169
170
171 /*******************************************************************************
172 * Function Name : void BSP_I2cOpen(uint8_t I2C_x, uint32_t clockSpeed)
173 * Description : 打开I2C口
174 * Input : I2C_x: I2C_1, I2C_2
175 clockSpeed: 时钟线频率
176 * Output :
177 * Other :
178 * Date : 2013.07.24
179 *******************************************************************************/
180 void BSP_I2cOpen(uint8_t I2C_x, uint32_t clockSpeed)
181 {
182 I2C_InitTypeDef I2C_InitStructure;
183 GPIO_InitTypeDef GPIO_InitStructure;
184 NVIC_InitTypeDef NVIC_InitStructure;
185
186 /* Enable peripheral clocks ----------------------------------------------*/
187 /* Enable I2C clock */
188 RCC_APB1PeriphClockCmd(I2C_CLK[I2C_x], ENABLE);
189 /* Enable GPIOB clock */
190 RCC_AHB1PeriphClockCmd(I2C_SCL_CLK[I2C_x] | I2C_SDA_CLK[I2C_x], ENABLE);
191 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
192
193 I2C_Cmd(I2C_NUM[I2C_x], DISABLE);
194 I2C_DeInit(I2C_NUM[I2C_x]);
195
196 /* Connect I2C_SCL*/
197 GPIO_PinAFConfig(I2C_SCL_PORT[I2C_x], I2C_SCL_AF_Source[I2C_x], I2C_AF_PORT[I2C_x]);
198 /* Connect I2C_SDA*/
199 GPIO_PinAFConfig(I2C_SDA_PORT[I2C_x], I2C_SDA_AF_Source[I2C_x], I2C_AF_PORT[I2C_x]);
200
201 /* Configure I2C pins: SCL and SDA ---------------------------------------*/
202 GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN[I2C_x];
203 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
204 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
205 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
206 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
207 GPIO_Init(I2C_SCL_PORT[I2C_x], &GPIO_InitStructure);
208
209 GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN[I2C_x];
210 GPIO_Init(I2C_SDA_PORT[I2C_x], &GPIO_InitStructure);
211
212 /* DISABLE I2C event and buffer interrupt */
213 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, DISABLE);
214
215 /* I2C configuration -----------------------------------------------------*/
216 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
217 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
218 I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS;
219 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
220 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
221 I2C_InitStructure.I2C_ClockSpeed = clockSpeed;
222 I2C_Init(I2C_NUM[I2C_x], &I2C_InitStructure);
223
224 memset (&I2C_PARAM[I2C_x], 0, sizeof(I2C_PARAM_TYPE));
225
226 /* Configure and enable I2C interrupt ------------------------------------*/
227 NVIC_InitStructure.NVIC_IRQChannel = I2C_IRQn[I2C_x];
228 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
229 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
230 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
231 NVIC_Init(&NVIC_InitStructure);
232
233 /* Enable I2C ------------------------------------------------------------*/
234 I2C_Cmd(I2C_NUM[I2C_x], ENABLE);
235 }
236
237 /*******************************************************************************
238 * Function Name : void _I2CDelay(volatile uint32_t count)
239 * Description : 延迟程序
240 * Input :
241 * Output :
242 * Other :
243 * Date : 2013.08.15
244 *******************************************************************************/
245 void _I2CDelay(volatile uint32_t count)
246 {
247 for (; count > 0; count--);
248 }
249
250 /*******************************************************************************
251 * Function Name : void BSP_I2cClose(uint8_t I2C_x)
252 * Description : 关闭I2C口 并释放总线
253 * Input :
254 * Output :
255 * Other :
256 * Date : 2013.07.24
257 *******************************************************************************/
258 void BSP_I2cClose(uint8_t I2C_x)
259 {
260 GPIO_InitTypeDef GPIO_InitStructure;
261 uint16_t i = 0;
262
263 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, DISABLE);
264 RCC_APB1PeriphClockCmd(I2C_CLK[I2C_x], DISABLE);
265 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, DISABLE);
266
267 I2C_Cmd(I2C_NUM[I2C_x], DISABLE);
268 I2C_DeInit(I2C_NUM[I2C_x]);
269
270 /* Configure I2C pins: SCL and SDA ---------------------------------------*/
271 GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN[I2C_x];
272 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
273 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
274 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
275 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
276 GPIO_Init(I2C_SCL_PORT[I2C_x], &GPIO_InitStructure);
277
278 GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN[I2C_x];
279 GPIO_Init(I2C_SDA_PORT[I2C_x], &GPIO_InitStructure);
280
281 _I2CDelay(100);
282 for (i = 16; i > 0; i--) //16个时钟 脉冲 释放I2C总线
283 {
284 GPIO_ResetBits(I2C_SCL_PORT[I2C_x], I2C_SCL_PIN[I2C_x]);
285 _I2CDelay(100);
286 GPIO_SetBits(I2C_SCL_PORT[I2C_x], I2C_SCL_PIN[I2C_x]);
287 _I2CDelay(100);
288 }
289
290 GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN[I2C_x];
291 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
292 GPIO_Init(I2C_SCL_PORT[I2C_x], &GPIO_InitStructure);
293
294 GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN[I2C_x];
295 GPIO_Init(I2C_SDA_PORT[I2C_x], &GPIO_InitStructure);
296
297 memset (&I2C_PARAM[I2C_x], 0, sizeof(I2C_PARAM_TYPE));
298 }
299
300 /*******************************************************************************
301 * Function Name : uint32_t BSP_I2cWrite(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t writeAddress, uint16_t writeLen)
302 * Description : I2C向从机发送数据
303 * Input : I2C_x: I2C_1, I2C_2
304 buff: 要发送的数据
305 i2cSaleAddress: 从机ID号
306 writeAddress: 写入的地址
307 writeLen: 要写入的数据长度
308 * Output :
309 * Other : 本函数为非阻塞式 执行完后调用BSP_I2cIdleState 是否执行完毕
310 * Date : 2013.07.24
311 *******************************************************************************/
312 uint32_t BSP_I2cWrite(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t writeAddress, uint16_t writeLen)
313 {
314 if (I2C_x >= I2C_MAX)
315 return 0;
316
317 if (NULL == buff)
318 return 0;
319
320 if (0 == writeLen)
321 return 0;
322
323 if (0 != I2C_PARAM[I2C_x].idle)
324 return 0;
325
326 I2C_PARAM[I2C_x].idle = 1;
327 I2C_PARAM[I2C_x].id = i2cSaleAddress;
328 I2C_PARAM[I2C_x].addr = writeAddress;
329 I2C_PARAM[I2C_x].index = 0;
330 I2C_PARAM[I2C_x].r_w = 0;
331 I2C_PARAM[I2C_x].bufLen = writeLen;
332 I2C_PARAM[I2C_x].pBuff = buff;
333 I2C_PARAM[I2C_x].FunCallBack = (void (*)(uint8_t, void *))_I2cTxIRQ;
334
335 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, ENABLE);
336 I2C_AcknowledgeConfig(I2C_NUM[I2C_x], ENABLE);
337 /* Send I2C START condition */
338 I2C_GenerateSTART(I2C_NUM[I2C_x], ENABLE);
339 return writeLen;
340 }
341
342 /*******************************************************************************
343 * Function Name : uint32_t BSP_I2cRead(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t readAddress, uint16_t readLen)
344 * Description : I2C 读取数据
345 * Input : I2C_x: I2C_1, I2C_2
346 buff: 读数缓冲区
347 i2cSaleAddress: 从机ID号
348 readAddress: 读取的地址
349 readLen: 要读取的数据长度
350 * Output :
351 * Other : 本函数为非阻塞式 执行完后调用BSP_I2cIdleState 是否执行完毕
352 * Date : 2013.07.24
353 *******************************************************************************/
354 uint32_t BSP_I2cRead(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t readAddress, uint16_t readLen)
355 {
356 if (I2C_x >= I2C_MAX)
357 return 0;
358
359 if (NULL == buff)
360 return 0;
361
362 if (0 == readLen)
363 return 0;
364
365 if (0 != I2C_PARAM[I2C_x].idle)
366 return 0;
367
368 I2C_PARAM[I2C_x].idle = 1;
369 I2C_PARAM[I2C_x].id = i2cSaleAddress;
370 I2C_PARAM[I2C_x].addr = readAddress;
371 I2C_PARAM[I2C_x].index = 0;
372 I2C_PARAM[I2C_x].r_w = 1;
373 I2C_PARAM[I2C_x].bufLen = readLen;
374 I2C_PARAM[I2C_x].pBuff = buff;
375 I2C_PARAM[I2C_x].FunCallBack = (void (*)(uint8_t, void *))_I2cTxIRQ;
376
377 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, ENABLE);
378 I2C_AcknowledgeConfig(I2C_NUM[I2C_x], ENABLE);
379 /* Send I2C START condition */
380 I2C_GenerateSTART(I2C_NUM[I2C_x], ENABLE);
381 return readLen;
382 }
383
384 /*******************************************************************************
385 * Function Name : uint32_t BSP_I2cIdleState(uint8_t I2C_x)
386 * Description : 查询是否总线空闲 如果为空闲则读取参数
387 * Input : I2C_x: I2C_1, I2C_2
388 * Output : return: 0)空闲 1)忙碌
389 * Other :
390 * Date : 2013.07.24
391 *******************************************************************************/
392 uint32_t BSP_I2cIdleState(uint8_t I2C_x)
393 {
394 return (I2C_PARAM[I2C_x].idle || I2C_GetFlagStatus(I2C_NUM[I2C_x], I2C_FLAG_BUSY));
395 }
396
397 /*******************************************************************************
398 * Function Name : static void _I2cTxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam)
399 * Description : 发送数据中断函数
400 * Input :
401 * Output :
402 * Other :
403 * Date : 2013.07.24
404 *******************************************************************************/
405 static void _I2cTxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam)
406 {
407 switch (I2C_GetLastEvent(I2C_NUM[I2C_x]))
408 {
409 /* Test on I2Cx EV5 and clear it */
410 case I2C_EVENT_MASTER_MODE_SELECT:
411 I2C_Send7bitAddress(I2C_NUM[I2C_x], pParam->id, I2C_Direction_Transmitter);
412 break;
413
414 /* Test on I2Cx EV6 and first EV8 and clear them */
415 case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
416 /* Send the first data */
417 I2C_SendData(I2C_NUM[I2C_x], pParam->addr); /* EV8 just after EV6 */
418 break;
419
420 case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
421 if((pParam->index < pParam->bufLen) && (pParam->r_w == 0))
422 {
423 /* Transmit buffer data */
424 I2C_SendData(I2C_NUM[I2C_x], pParam->pBuff[pParam->index++]);
425 }
426 else
427 {
428 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_BUF, DISABLE);
429 }
430 break;
431
432 /* Test on I2Cx EV8 and clear it */
433 case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
434 if (pParam->r_w != 0)
435 {
436 pParam->FunCallBack = (void (*)(uint8_t, void *))_I2cRxIRQ;
437 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_BUF, ENABLE);
438 I2C_GenerateSTART(I2C_NUM[I2C_x], ENABLE);
439 }
440 else
441 {
442 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, DISABLE);
443 I2C_AcknowledgeConfig(I2C_NUM[I2C_x], DISABLE);
444 I2C_GenerateSTOP(I2C_NUM[I2C_x], ENABLE);
445 pParam->idle = 0; //接收结束标志
446 }
447 break;
448 }
449 }
450
451 /*******************************************************************************
452 * Function Name : static void _I2cRxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam)
453 * Description : 接收数据中断函数
454 * Input :
455 * Output :
456 * Other :
457 * Date : 2013.07.24
458 *******************************************************************************/
459 static void _I2cRxIRQ(uint8_t I2C_x, I2C_PARAM_TYPE *pParam)
460 {
461 switch (I2C_GetLastEvent(I2C_NUM[I2C_x]))
462 {
463 /* Test on I2Cx EV5 and clear it */
464 case I2C_EVENT_MASTER_MODE_SELECT:
465 /* Send I2Cx slave Address for write */
466 I2C_Send7bitAddress(I2C_NUM[I2C_x], pParam->id, I2C_Direction_Receiver);
467 break;
468
469 /* Test on I2Cx EV6 and first EV8 and clear them */
470 case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
471 if (pParam->index == (pParam->bufLen - 1))
472 {
473 I2C_AcknowledgeConfig(I2C_NUM[I2C_x], DISABLE);
474 I2C_GenerateSTOP(I2C_NUM[I2C_x], ENABLE);
475 }
476 break;
477
478 /* Test on I2Cx EV2 and clear it */
479 case I2C_EVENT_MASTER_BYTE_RECEIVED:
480 pParam->pBuff[pParam->index++] = I2C_ReceiveData(I2C_NUM[I2C_x]);
481
482 if (pParam->index == (pParam->bufLen - 1))
483 {
484 I2C_AcknowledgeConfig(I2C_NUM[I2C_x], DISABLE);
485 I2C_GenerateSTOP(I2C_NUM[I2C_x], ENABLE);
486 }
487 else if (pParam->index >= pParam->bufLen)
488 {
489 pParam->FunCallBack = (void (*)(uint8_t, void *))_I2cTxIRQ; //默认进接收中断
490 I2C_ITConfig(I2C_NUM[I2C_x], I2C_IT_EVT | I2C_IT_BUF, DISABLE);
491 pParam->idle = 0;
492 }
493 break;
494 }
495 }
496
497 #if I2C_1_EN
498 /*******************************************************************************
499 * Function Name : void I2C1_EV_IRQHandler(void)
500 * Description : I2C1中断函数
501 * Input :
502 * Output :
503 * Other :
504 * Date : 2013.07.24
505 *******************************************************************************/
506 void I2C1_EV_IRQHandler(void)
507 {
508 if (I2C_PARAM[I2C_1].FunCallBack)
509 {
510 I2C_PARAM[I2C_1].FunCallBack(I2C_1, &I2C_PARAM[I2C_1]);
511 }
512 }
513 #endif
514
515 #if I2C_2_EN
516 /*******************************************************************************
517 * Function Name : void I2C2_EV_IRQHandler(void)
518 * Description : I2C2中断函数
519 * Input :
520 * Output :
521 * Other :
522 * Date : 2013.07.24
523 *******************************************************************************/
524 void I2C2_EV_IRQHandler(void)
525 {
526 if (I2C_PARAM[I2C_2].FunCallBack)
527 {
528 I2C_PARAM[I2C_2].FunCallBack(I2C_2, &I2C_PARAM[I2C_2]);
529 }
530 }
531 #endif
532
533 #if I2C_3_EN
534 /*******************************************************************************
535 * Function Name : void I2C3_EV_IRQHandler(void)
536 * Description : I2C3中断函数
537 * Input :
538 * Output :
539 * Other :
540 * Date : 2013.07.24
541 *******************************************************************************/
542 void I2C3_EV_IRQHandler(void)
543 {
544 if (I2C_PARAM[I2C_3].FunCallBack)
545 {
546 I2C_PARAM[I2C_3].FunCallBack(I2C_3, &I2C_PARAM[I2C_3]);
547 }
548 }
549 #endif
BSP_I2c.c
1/*
2******************************************************************************
3 *
4 * BSP_I2c.h
5 *
6 * File : BSP_I2c.h
7 * Version : V1.0
8 * Author : whq
9 * Mode : Thumb2
10 * Toolchain :
11 * Description : I2C驱动头文件
12 *
13 * History :
14 * Date : 2013.07.24
15 *******************************************************************************/
16
17 #ifndef _BSP_I2C_H_
18 #define _BSP_I2C_H_
19
20 #include
21
22 #define I2C_1_EN 1
23 #define I2C_2_EN 1
24 #define I2C_3_EN 1
25
26 #if !(I2C_1_EN || I2C_2_EN ||I2C_3_EN)
27 #error "请至少打开一路I2C"
28 #endif
29
30 typedef enum {
31 #if I2C_1_EN
32 I2C_1,
33 #endif
34 #if I2C_2_EN
35 I2C_2,
36 #endif
37 #if I2C_3_EN
38 I2C_3,
39 #endif
40 I2C_MAX
41 }I2C_ENUM;
42
43 #define I2Cn I2C_MAX
44 #define I2C_1_0 //无映射:I2C_1_0,映射1:I2C_1_1
45 #define I2C_2_0
46 #define I2C_3_0 //无映射:I2C_3_0,映射1:I2C_3_1
47
48 #define I2C_SLAVE_ADDRESS 0x30 //本STM32芯片地址
49
50
51 /******************************类型声明****************************************/
52
53 typedef struct {
54 volatile uint8_t idle; //空闲标志 0)空闲 1)忙碌
55 uint8_t r_w; //读写标志 0)写 1)读
56 uint8_t id; //从机设备ID号
57 uint8_t addr; //要读写的地址
58 volatile uint16_t index; //当前缓冲区数据长度
59 uint16_t bufLen; //要发送或接收的数据长度
60 uint8_t * volatile pBuff; //缓冲区首地址
61 void (* volatile FunCallBack)(uint8_t, void *);//中断回调函数
62 }I2C_PARAM_TYPE;
63
64 /******************************************************************************/
65
66
67 /**
68 * @brief I2C1 Interface pins
69 */
70 #define BSP_I2C1 I2C1
71 #define BSP_I2C1_CLK RCC_APB1Periph_I2C1
72 #define BSP_I2C1_AF_Port GPIO_AF_I2C1
73 #define BSP_I2C1_IRQn I2C1_EV_IRQn
74
75 #if defined(I2C_1_2) //自由组合区
76 #define BSP_I2C1_SCL_AF_Source GPIO_PinSource8
77 #define BSP_I2C1_SCL_PIN GPIO_Pin_8
78 #define BSP_I2C1_SCL_GPIO_PORT GPIOB
79 #define BSP_I2C1_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB
80
81 #define BSP_I2C1_SDA_AF_Source GPIO_PinSource9
82 #define BSP_I2C1_SDA_PIN GPIO_Pin_9
83 #define BSP_I2C1_SDA_GPIO_PORT GPIOB
84 #define BSP_I2C1_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB
85
86 #elif defined(I2C_1_1)
87 #define BSP_I2C1_SCL_AF_Source GPIO_PinSource8
88 #define BSP_I2C1_SCL_PIN GPIO_Pin_8
89 #define BSP_I2C1_SCL_GPIO_PORT GPIOB
90 #define BSP_I2C1_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB
91
92 #define BSP_I2C1_SDA_AF_Source GPIO_PinSource9
93 #define BSP_I2C1_SDA_PIN GPIO_Pin_9
94 #define BSP_I2C1_SDA_GPIO_PORT GPIOB
95 #define BSP_I2C1_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB
96
97 #else
98 #define BSP_I2C1_SCL_AF_Source GPIO_PinSource6
99 #define BSP_I2C1_SCL_PIN GPIO_Pin_6
100 #define BSP_I2C1_SCL_GPIO_PORT GPIOB
101 #define BSP_I2C1_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB
102
103 #define BSP_I2C1_SDA_AF_Source GPIO_PinSource7
104 #define BSP_I2C1_SDA_PIN GPIO_Pin_7
105 #define BSP_I2C1_SDA_GPIO_PORT GPIOB
106 #define BSP_I2C1_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB
107 #endif
108
109 /**
110 * @brief I2C2 Interface pins
111 */
112 #define BSP_I2C2 I2C2
113 #define BSP_I2C2_CLK RCC_APB1Periph_I2C2
114 #define BSP_I2C2_AF_Port GPIO_AF_I2C2
115 #define BSP_I2C2_IRQn I2C2_EV_IRQn
116
117 #if defined(I2C_2_3) //自由组合区
118 #define BSP_I2C2_SCL_AF_Source GPIO_PinSource4
119 #define BSP_I2C2_SCL_PIN GPIO_Pin_4
120 #define BSP_I2C2_SCL_GPIO_PORT GPIOH
121 #define BSP_I2C2_SCL_GPIO_CLK RCC_AHB1Periph_GPIOH
122
123 #define BSP_I2C2_SDA_AF_Source GPIO_PinSource5
124 #define BSP_I2C2_SDA_PIN GPIO_Pin_5
125 #define BSP_I2C2_SDA_GPIO_PORT GPIOH
126 #define BSP_I2C2_SDA_GPIO_CLK RCC_AHB1Periph_GPIOH
127
128 #elif defined(I2C_2_2)
129 #define BSP_I2C2_SCL_AF_Source GPIO_PinSource4
130 #define BSP_I2C2_SCL_PIN GPIO_Pin_4
131 #define BSP_I2C2_SCL_GPIO_PORT GPIOH
132 #define BSP_I2C2_SCL_GPIO_CLK RCC_AHB1Periph_GPIOH
133
134 #define BSP_I2C2_SDA_AF_Source GPIO_PinSource5
135 #define BSP_I2C2_SDA_PIN GPIO_Pin_5
136 #define BSP_I2C2_SDA_GPIO_PORT GPIOH
137 #define BSP_I2C2_SDA_GPIO_CLK RCC_AHB1Periph_GPIOH
138
139 #elif defined(I2C_2_1)
140 #define BSP_I2C2_SCL_AF_Source GPIO_PinSource1
141 #define BSP_I2C2_SCL_PIN GPIO_Pin_1
142 #define BSP_I2C2_SCL_GPIO_PORT GPIOF
143 #define BSP_I2C2_SCL_GPIO_CLK RCC_AHB1Periph_GPIOF
144
145 #define BSP_I2C2_SDA_AF_Source GPIO_PinSource0
146 #define BSP_I2C2_SDA_PIN GPIO_Pin_0
147 #define BSP_I2C2_SDA_GPIO_PORT GPIOF
148 #define BSP_I2C2_SDA_GPIO_CLK RCC_AHB1Periph_GPIOF
149
150 #else
151 #define BSP_I2C2_SCL_AF_Source GPIO_PinSource10
152 #define BSP_I2C2_SCL_PIN GPIO_Pin_10
153 #define BSP_I2C2_SCL_GPIO_PORT GPIOB
154 #define BSP_I2C2_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB
155
156 #define BSP_I2C2_SDA_AF_Source GPIO_PinSource11
157 #define BSP_I2C2_SDA_PIN GPIO_Pin_11
158 #define BSP_I2C2_SDA_GPIO_PORT GPIOB
159 #define BSP_I2C2_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB
160 #endif
161
162 /**
163 * @brief I2C3 Interface pins
164 */
165 #define BSP_I2C3 I2C3
166 #define BSP_I2C3_CLK RCC_APB1Periph_I2C3
167 #define BSP_I2C3_AF_Port GPIO_AF_I2C3
168 #define BSP_I2C3_IRQn I2C3_EV_IRQn
169
170 #if defined(I2C_3_2) //自由组合区
171 #define BSP_I2C3_SCL_AF_Source GPIO_PinSource8
172 #define BSP_I2C3_SCL_PIN GPIO_Pin_8
173 #define BSP_I2C3_SCL_GPIO_PORT GPIOA
174 #define BSP_I2C3_SCL_GPIO_CLK RCC_AHB1Periph_GPIOA
175
176 #define BSP_I2C3_SDA_AF_Source GPIO_PinSource8
177 #define BSP_I2C3_SDA_PIN GPIO_Pin_8
178 #define BSP_I2C3_SDA_GPIO_PORT GPIOH
179 #define BSP_I2C3_SDA_GPIO_CLK RCC_AHB1Periph_GPIOH
180
181 #elif defined(I2C_3_1)
182 #define BSP_I2C3_SCL_AF_Source GPIO_PinSource8
183 #define BSP_I2C3_SCL_PIN GPIO_Pin_8
184 #define BSP_I2C3_SCL_GPIO_PORT GPIOA
185 #define BSP_I2C3_SCL_GPIO_CLK RCC_AHB1Periph_GPIOA
186
187 #define BSP_I2C3_SDA_AF_Source GPIO_PinSource9
188 #define BSP_I2C3_SDA_PIN GPIO_Pin_9
189 #define BSP_I2C3_SDA_GPIO_PORT GPIOC
190 #define BSP_I2C3_SDA_GPIO_CLK RCC_AHB1Periph_GPIOC
191
192 #else
193 #define BSP_I2C3_SCL_AF_Source GPIO_PinSource7
194 #define BSP_I2C3_SCL_PIN GPIO_Pin_7
195 #define BSP_I2C3_SCL_GPIO_PORT GPIOH
196 #define BSP_I2C3_SCL_GPIO_CLK RCC_AHB1Periph_GPIOH
197
198 #define BSP_I2C3_SDA_AF_Source GPIO_PinSource8
199 #define BSP_I2C3_SDA_PIN GPIO_Pin_8
200 #define BSP_I2C3_SDA_GPIO_PORT GPIOH
201 #define BSP_I2C3_SDA_GPIO_CLK RCC_AHB1Periph_GPIOH
202 #endif
203
204
205
206 /******************************函数声明****************************************/
207 void BSP_I2cOpen(uint8_t I2C_x, uint32_t clockSpeed);
208 void BSP_I2cClose(uint8_t I2C_x);
209 uint32_t BSP_I2cWrite(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t writeAddress, uint16_t writeLen);
210 uint32_t BSP_I2cRead(uint8_t I2C_x, uint8_t *buff, uint16_t i2cSaleAddress, uint8_t readAddress, uint16_t readLen);
211 uint32_t BSP_I2cIdleState(uint8_t I2C_x);
212
213
214
215 #endif