首页 > 代码库 > STM32F4XX高效驱动篇2 I2C

STM32F4XX高效驱动篇2 I2C

说到I2C很多用过STMF10X硬件I2C方式的工程师,都感觉有点头痛。大部分还是使用软件模拟的方式,I2C由于一般的工作频率是400,100KHz。所以在平凡读取,或所读数据量大时,使用这模拟的方式,还是比较浪费CPU有效工作时间的。

         在之前的使用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 <string.h>
 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 <stdint.h>
 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
BSP_I2c.h