通过两个按键(按键1和按键2)控制两个LED灯(LED1和LED2)循环点亮,要求按键2的按键中断能中断按键1的按键中断。
时间: 2024-04-05 08:11:42 浏览: 187
STM32_外部中断之按键控制点亮LED灯
5星 · 资源好评率100%
以下是基于STM32F4的示例程序,实现了按键1和按键2控制两个LED灯循环点亮,且按键2中断能够中断按键1中断:
```
#include "stm32f4xx.h"
int main(void)
{
// 初始化GPIO
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
// 初始化NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
NVIC_Init(&NVIC_InitStruct);
// 初始化EXTI
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Line = EXTI_Line1;
EXTI_Init(&EXTI_InitStruct);
int led1_on = 1, led2_on = 0; // 初始状态
while(1)
{
if (led1_on)
{
GPIO_SetBits(GPIOC, GPIO_Pin_8);
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
led1_on = 0;
led2_on = 1;
}
else if (led2_on)
{
GPIO_SetBits(GPIOC, GPIO_Pin_9);
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
led1_on = 1;
led2_on = 0;
}
}
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line1);
EXTI_GenerateSWInterrupt(EXTI_Line0);
}
}
```
在这个示例中,我们使用了PA0和PA1作为按键输入,PC8和PC9作为LED输出。
按键1和按键2都使用了外部中断模式,当按键被按下时,会产生一个上升沿和一个下降沿的中断事件。按键1的中断优先级低于按键2,因此按键2可以中断按键1的中断。在中断处理函数中,我们只需要清除中断标志并调用`EXTI_GenerateSWInterrupt`函数来产生按键1的中断即可。
LED的控制使用了一个简单的状态机,每次循环都会切换两个LED的状态。
阅读全文