i2c 中断处理程序 stm32
Posted
技术标签:
【中文标题】i2c 中断处理程序 stm32【英文标题】:i2c interrupt handler stm32 【发布时间】:2013-09-02 00:30:20 【问题描述】: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, 埃德加。
【问题讨论】:
我正在尝试设置一个带有中断的从 i2c,并且考虑到我在非电气方面的背景,我遇到了困难。您能否提供一个参考来帮助我了解您是如何进行设置的?例如I2C_GetLastEvent
的实现。一个 github 存储库将是最好的。
【参考方案1】:
好的,您已经列出了您的中断配置和处理程序,但是您的 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
(可能在标题中)会使生活更轻松。例如:
#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
...而且 MOST 重要的是,看看 here 可用的“stm32f4xx_i2c.c”。通读顶部的“如何使用此驱动程序”评论。
【讨论】:
注意:如果找不到上面的#define值,请确保在您的项目中包含“stm32f4xx_rcc.h”、“stm32f4xx_gpio.h”和“stm32f4xx.h”。 如果您的项目中已经包含所有这些,请将其发布,以便我们可以看到您在其中所做的工作。 我已经有了初始化代码。我已从 i2c3 更改为 i2c2,但仍然无法正常工作。 您需要调用 I2C_ITConfig(I2C2, ENABLE)。我看到您编辑了您的帖子以包含您的初始化代码,但没有看到此列表。试一试。 我会尽快尝试的。我会让你知道。谢谢!以上是关于i2c 中断处理程序 stm32的主要内容,如果未能解决你的问题,请参考以下文章