zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程
    002 01 Android 零基础入门 01 Java基础语法 01 Java初识 02 Java简介
    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学
    001 Android Studio 首次编译执行项目过程中遇到的几个常见问题
    Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
    Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验
    监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile
    轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
    轻量级ORM框架——第一篇:Dapper快速学习
    CF888G Xor-MST(异或生成树模板)
  • 原文地址:https://www.cnblogs.com/hiker-blogs/p/3694576.html
Copyright © 2011-2022 走看看