10

I2C2 中断有一些问题,我已启用中断但处理程序中断从未执行。

这是 i2c2 初始化:

void i2c2InitSlave(void)
{
    I2C_DeInit(I2C2);
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    /*I2C2 Peripheral clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

    /* Enable GPIO clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);

    // I2C2 SCL and SDA Pin configuration
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOH, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOH, GPIO_PinSource4, GPIO_AF_I2C2);
        GPIO_PinAFConfig(GPIOH, GPIO_PinSource5, GPIO_AF_I2C2);

    /* Initialize I2C peripheral */
    /* I2C Init */
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = SLAVE_ADDRESS;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_ClockSpeed = 100000;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    /* Enable I2C2 */
    I2C_Cmd(I2C2, ENABLE);
    I2C_Init(I2C2, &I2C_InitStructure);

    Tx_Index = 0;
    Rx_Index = 0;
}

下面是中断配置:

NVIC_InitTypeDef NVIC_InitStructure;

/* Configure the I2C event priority */
NVIC_InitStructure.NVIC_IRQChannel                   = I2C2_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
NVIC_Init(&NVIC_InitStructure);

这是中断处理程序:

/**
* @brief  Interrupt handler for i2c interface.
* @param  None
* @retval None
*/

void I2C2_EV_IRQHandler(void)
{
    switch(I2C_GetLastEvent(I2C2))
    {
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED :
        break;
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:
        i2c_read_packet[Rx_Index] = I2C_ReceiveData(I2C2); // Store the packet in i2c_read_packet.
        Rx_Index++;
        break;
    case I2C_EVENT_SLAVE_STOP_DETECTED :
        Rx_Index = 0;
        packets_recv_i2c++;
        i2cProcessPacket();
        break;
    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
        I2C_SendData(I2C2, i2c_packet_to_send[0]);
        Tx_Index++;
        break;
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
        I2C_SendData(I2C2, i2c_packet_to_send[Tx_Index]);
        Tx_Index++;
        break;
    case I2C_EVENT_SLAVE_ACK_FAILURE:
        Tx_Index = 0;
        packets_sent_i2c++;
        break;
    default:
        break;
    }
}

任何想法?BR,埃德加。

4

1 回答 1

7

好的,你已经列出了你的中断配置和处理程序,但是你的 I2C 初始化一般呢?

如果 I2C 未初始化,您将不会产生任何中断。

你应该认出这个块(或它的一些类似物):

I2C_InitTypeDef  I2C_InitStructure;

/* I2C Struct Initialize */  
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
I2C_InitStructure.I2C_OwnAddress1 = 0xA0;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

/* I2C Enable and Init */
I2C_Cmd(I2C2, ENABLE);
I2C_Init(I2Cx, &I2C_InitStructure);  

I2C_Config(); //See implementation below

I2C_ITConfig(I2Cx, ENABLE); //Part of the STM32 I2C driver    

其中 I2C_Config 可以定义如下:

void I2C_Config(void){
  GPIO_InitTypeDef  GPIO_InitStructure;

  /* RCC Configuration */
  /*I2C Peripheral clock enable */
  RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);

  /*SDA GPIO clock enable */
  RCC_AHB1PeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE);

  /*SCL GPIO clock enable */
  RCC_AHB1PeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE);

  /* Reset I2Cx IP */
  RCC_APB1PeriphResetCmd(I2Cx_CLK, ENABLE);

  /* Release reset signal of I2Cx IP */
  RCC_APB1PeriphResetCmd(I2Cx_CLK, DISABLE);

  /* GPIO Configuration */
  /*Configure I2C SCL pin */
  GPIO_InitStructure.GPIO_Pin = I2Cx_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStructure);

  /*Configure I2C SDA pin */
  GPIO_InitStructure.GPIO_Pin = I2Cx_SDA_PIN;
  GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStructure);

  /* Connect PXx to I2C_SCL */
  GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, I2Cx_SCL_AF);

  /* Connect PXx to I2C_SDA */
  GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, I2Cx_SDA_AF);

}

I2C_InitTypeDef 定义如下:

typedef struct  
{
  uint32_t I2C_ClockSpeed;      //Specifies the clock frequency.
                                //This parameter must be set to a value lower than 400kHz

  uint16_t I2C_Mode;            //Specifies the I2C mode.
                                //This parameter can be a value of @ref I2C_mode 

  uint16_t I2C_DutyCycle;       //Specifies the I2C fast mode duty cycle.
                                //This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode 

  uint16_t I2C_OwnAddress1;     //Specifies the first device own address.
                                //This parameter can be a 7-bit or 10-bit address.

  uint16_t I2C_Ack;             //Enables or disables the acknowledgement.
                                //This parameter can be a value of @ref I2C_acknowledgement

  uint16_t I2C_AcknowledgedAddress; 
                                //Specifies if 7-bit or 10-bit address is acknowledged.
                                //This parameter can be a value of @ref I2C_acknowledged_address
}I2C_InitTypeDef;

注意:在配置过程中使用一组#define's(可能在标题中)会使生活更轻松。例如:

#define I2Cx                          I2C1
#define I2Cx_CLK                      RCC_APB1Periph_I2C1
#define I2Cx_SDA_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define I2Cx_SDA_PIN                  GPIO_Pin_9                
#define I2Cx_SDA_GPIO_PORT            GPIOB                       
#define I2Cx_SDA_SOURCE               GPIO_PinSource9
#define I2Cx_SDA_AF                   GPIO_AF_I2C1

#define I2Cx_SCL_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define I2Cx_SCL_PIN                  GPIO_Pin_6                
#define I2Cx_SCL_GPIO_PORT            GPIOB                    
#define I2Cx_SCL_SOURCE               GPIO_PinSource6
#define I2Cx_SCL_AF                   GPIO_AF_I2C1

...最重要的是,看看这里可用的“ stm32f4xx_i2c.c ” 。通读顶部的“如何使用此驱动程序”评论。

于 2013-08-30T04:16:50.340 回答