• 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
  • 相关阅读:
    事务管理思考
    sleep、yield、wait的区别
    线程异常
    线程
    JAVA线程中断
    volatile synchronized在线程安全上的区别
    jms amqp activemq rabbitmq的区别
    servlet不是线程安全的
    雪花算法
    个人税收申报时候对于“全年一次性奖金“的处理
  • 原文地址:https://www.cnblogs.com/hiker-blogs/p/3694576.html
Copyright © 2020-2023  润新知