本帖最后由 xyz549040622 于 2023-9-8 23:21 编辑
程序设计:用户按键触发LED的亮灭,按下按键的时候,LED点亮,按键弹起的时候,LED熄灭,采用中断方式进行捕获。
根据原理图得知,用户LED1-PA0,按键S2-PA14。
根据上面原理图可以得出逻辑,挡S2低电平的时候,LED1点亮,S2悬空的时候,LED1熄灭,采用中断方式触发。
因此,我们可以配置PA0为输出,默认输出高电平,熄灭LED,不使能中断。配置PA14为输入,内部弱上拉,使能中断,双向触发,既上升沿和下降沿都可以触发中断。
使用syscfg配置。软件的配置如下:
我们看看IO的初始化代码,很明显的对IO的中断进行了初始化,并使能了PA14的中断。SYSCONFIG_WEAK void SYSCFG_DL_GPIO_init(void)
{
DL_GPIO_initDigitalOutput(GPIO_LEDS_USER_LED_1_IOMUX);
DL_GPIO_initDigitalInputFeatures(GPIO_SWITCHES_USER_SWITCH_1_IOMUX,
DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP,
DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_DISABLE);
DL_GPIO_setPins(GPIOA, GPIO_LEDS_USER_LED_1_PIN);
DL_GPIO_enableOutput(GPIOA, GPIO_LEDS_USER_LED_1_PIN);
DL_GPIO_setLowerPinsPolarity(GPIOA, DL_GPIO_PIN_14_EDGE_RISE_FALL);
DL_GPIO_clearInterruptStatus(GPIOA, GPIO_SWITCHES_USER_SWITCH_1_PIN);
DL_GPIO_enableInterrupt(GPIOA, GPIO_SWITCHES_USER_SWITCH_1_PIN);
}
然后就是在NVIC中断控制器中启用特定于设备的中断。
NVIC_EnableIRQ(GPIO_SWITCHES_INT_IRQN);
这里虽然使能的是GPIOA_INT_IRQn,但其实占用的是17号异常,INT_GROUP1,所以中断函数需要在INT_GROUP1里面编辑的
typedef enum IRQn
{
NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /* 3 Hard Fault Interrupt */
SVCall_IRQn = -5, /* 11 SV Call Interrupt */
PendSV_IRQn = -2, /* 14 Pend SV Interrupt */
SysTick_IRQn = -1, /* 15 System Tick Interrupt */
FLASHCTL_INT_IRQn = 0, /* 16 FLASHCTL_INT Interrupt */
WWDT0_INT_IRQn = 0, /* 16 WWDT0_INT Interrupt */
DEBUGSS_INT_IRQn = 0, /* 16 DEBUGSS_INT Interrupt */
SYSCTL_INT_IRQn = 0, /* 16 SYSCTL_INT Interrupt */
GPIOA_INT_IRQn = 1, /* 17 GPIOA_INT Interrupt */
COMP0_INT_IRQn = 1, /* 17 COMP0_INT Interrupt */
TIMG1_INT_IRQn = 2, /* 18 TIMG1_INT Interrupt */
ADC0_INT_IRQn = 4, /* 19 ADC0_INT Interrupt */
SPI0_INT_IRQn = 9, /* 25 SPI0_INT Interrupt */
UART1_INT_IRQn = 13, /* 29 UART1_INT Interrupt */
UART0_INT_IRQn = 15, /* 31 UART0_INT Interrupt */
TIMG0_INT_IRQn = 16, /* 32 TIMG0_INT Interrupt */
TIMG2_INT_IRQn = 18, /* 34 TIMG2_INT Interrupt */
TIMG4_INT_IRQn = 20, /* 36 TIMG4_INT Interrupt */
I2C0_INT_IRQn = 24, /* 40 I2C0_INT Interrupt */
I2C1_INT_IRQn = 25, /* 41 I2C1_INT Interrupt */
DMA_INT_IRQn = 31, /* 47 DMA_INT Interrupt */
} IRQn_Type;
最后就是中断处理函数了:
void GROUP1_IRQHandler(void)
{
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
case GPIO_SWITCHES_INT_IIDX:
/* If SW is high, turn the LED off */
if (DL_GPIO_readPins(
GPIO_SWITCHES_PORT, GPIO_SWITCHES_USER_SWITCH_1_PIN)) {
DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
}
/* Otherwise, turn the LED on */
else {
DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
}
break;
}
}
我们需要在void GROUP1_IRQHandler(void)中进行函数的编辑。
首先是获取IIDX索引,GPIO中断的IIDX==1。也就是CPUSS_INT_GROUP_IIDX_STAT_INT0,然后读取PA14的输入电平,进行LED的操作。
这样把读取电平,然后翻转LED的程序放到中断的好处是,减少了CPU的开销,不需要一直循环读取电平的状态。
|