2013-08-29 189 views
5

Tôi có một số vấn đề với ngắt I2C2, tôi đã bật ngắt nhưng trình xử lý ngắt không bao giờ thực thi.Trình xử lý ngắt i2c stm32

Đây là khởi 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; 
} 

Dưới đây là cấu hình ngắt:

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

Và đây là xử lý ngắt:

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

Bất kỳ ý tưởng? BR, Edgar.

Trả lời

5

Được rồi, vì vậy bạn đã liệt kê cấu hình và trình xử lý ngắt của bạn, nhưng về khởi tạo I2C của bạn nói chung thì sao?

Bạn sẽ không tạo ra bất kỳ bất kỳ ngắt nào nếu I2C không được khởi tạo.

Bạn nên nhận ra khối này (hoặc một số tương tự của nó):

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  

đâu I2C_Config có thể được định nghĩa như sau:

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

} 

Và I2C_InitTypeDef được định nghĩa như sau:

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; 

Lưu ý: Sử dụng bộ #define 's (perh aps trong tiêu đề) trong khi cấu hình giúp cuộc sống dễ dàng hơn. Ví dụ:

#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 

... Và MOST quan trọng, hãy nhìn vào "stm32f4xx_i2c.c" sẵn here. Đọc qua nhận xét "Cách sử dụng trình điều khiển này" ở trên cùng.

+0

Lưu ý: nếu không tìm thấy giá trị #define ở trên, hãy đảm bảo bao gồm "stm32f4xx_rcc.h", "stm32f4xx_gpio.h" và "stm32f4xx.h", trong dự án của bạn. – bunkerdive

+0

Nếu bạn đã có tất cả điều này trong dự án của bạn, hãy đăng nó để chúng tôi có thể xem những gì bạn đã làm ở đó. – bunkerdive

+0

Tôi đã có mã initilization. Tôi đã thay đổi từ i2c3 thành i2c2 nhưng vẫn không hoạt động. –