2013-08-29 9 views
5

Ich habe einige Probleme mit I2C2-Interrupts, ich habe den Interrupt aktiviert, aber der Handler-Interrupt wird nie ausgeführt. Hieri2c Interrupt-Handler stm32

ist die i2c2 Initialisierung:

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; 
} 

Hier ist die Interrupt-Konfiguration:

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); 

Und hier ist der Interrupt-Handler:

/** 
* @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; 
    } 
} 

Jede Idee? BR, Edgar.

Antwort

5

Okay, also haben Sie Ihre Interrupt-Konfiguration und Handler aufgelistet, aber was ist mit Ihrer I2C-Initialisierung im Allgemeinen?

Sie werden keine Interrupts generieren, wenn der I2C nicht initialisiert ist.

Sie sollten diesen Block erkennen (oder ein Analogon davon):

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  

Wo I2C_Config definiert werden wie folgt:

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); 

} 

Und die I2C_InitTypeDef ist wie folgt definiert:

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; 

Hinweis: Mit einem Satz von #define 's (perh aps in einem Header) während der Konfiguration macht das Leben einfacher. Zum Beispiel:

#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 

... Und MOST wichtiger ist, werfen Sie einen Blick auf "stm32f4xx_i2c.c" verfügbar here. Lesen Sie den Kommentar "Wie Sie diesen Treiber verwenden" oben.

+0

Hinweis: Wenn die obigen #define-Werte nicht gefunden werden, müssen Sie "stm32f4xx_rcc.h", "stm32f4xx_gpio.h" und "stm32f4xx.h" in Ihrem Projekt angeben. – bunkerdive

+0

Wenn Sie bereits alles in Ihrem Projekt haben, posten Sie es, damit wir sehen können, was Sie dort gemacht haben. – bunkerdive

+0

Ich hatte bereits den Initialisierungscode. Ich habe von i2c3 zu i2c2 gewechselt, funktioniert aber immer noch nicht. –