以下是一个基于STM32的中断实现示例,用于实现您描述的功能:
#include "stm32f4xx.h"
// 定义LED颜色
#define LED_RED GPIO_Pin_0
#define LED_GREEN GPIO_Pin_1
#define LED_BLUE GPIO_Pin_2
// 定义按键
#define KEY1 GPIO_Pin_3
#define KEY2 GPIO_Pin_4
// 定义指示灯当前和保存的颜色
uint16_t currentColor = LED_RED;
uint16_t savedColor = LED_RED;
// 初始化GPIO和中断配置
void GPIO_Config(void)
{
// 启用GPIO时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// 配置LED引脚为输出模式
GPIO_InitTypeDef gpioInit;
gpioInit.GPIO_Mode = GPIO_Mode_OUT;
gpioInit.GPIO_OType = GPIO_OType_PP;
gpioInit.GPIO_Pin = LED_RED | LED_GREEN | LED_BLUE;
gpioInit.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &gpioInit);
// 配置按键引脚为输入模式,带上拉电阻
gpioInit.GPIO_Mode = GPIO_Mode_IN;
gpioInit.GPIO_PuPd = GPIO_PuPd_UP;
gpioInit.GPIO_Pin = KEY1 | KEY2;
GPIO_Init(GPIOA, &gpioInit);
}
// 中断优先级配置
void NVIC_Config(void)
{
NVIC_InitTypeDef nvicInitStruct;
// 配置中断组优先级分组为4位抢占优先级,0位响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
// 配置EXTI线路中断
nvicInitStruct.NVIC_IRQChannel = EXTI3_IRQn;
nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F;
nvicInitStruct.NVIC_IRQChannelSubPriority = 0x00;
nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicInitStruct);
nvicInitStruct.NVIC_IRQChannel = EXTI4_IRQn;
nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F;
nvicInitStruct.NVIC_IRQChannelSubPriority = 0x01;
nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicInitStruct);
}
// 初始化外部中断线路
void EXTI_Config(void)
{
// 配置按键引脚连接到外部中断线路上
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
// 配置外部中断线路,下降沿触发
EXTI_InitTypeDef extiInit;
extiInit.EXTI_Line = EXTI_Line3 | EXTI_Line4;
extiInit.EXTI_Mode = EXTI_Mode_Interrupt;
extiInit.EXTI_Trigger = EXTI_Trigger_Falling;
extiInit.EXTI_LineCmd = ENABLE;
EXTI_Init(&extiInit);
}
// 中断处理函数
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
// 按下KEY1,切换LED颜色并点亮/熄灭指示灯
GPIO_ToggleBits(GPIOA, currentColor);
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)
{
static uint8_t settingMode = 0;
if(settingMode == 0)
{
// 进入颜色设置模式,点亮当前指示灯
GPIO_SetBits(GPIOA, currentColor);
settingMode = 1;
}
else
{
// 保存设置后的颜色并退出设置模式
savedColor = currentColor;
settingMode = 0;
}
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
// 修改当前指示灯颜色
void ChangeCurrentColor(void)
{
if(currentColor == LED_RED)
{
currentColor = LED_GREEN;
}
else if(currentColor == LED_GREEN)
{
currentColor = LED_BLUE;
}
else if(currentColor == LED_BLUE)
{
currentColor = LED_RED;
}
}
int main(void)
{
GPIO_Config();
NVIC_Config();
EXTI_Config();
while(1)
{
// 主循环中可以添加其他功能代码,例如按键检测、处理等
// 在设置模式下,按下KEY1修改当前指示灯颜色(变换顺序 R->G->B 循环)
if(GPIO_ReadInputDataBit(GPIOA, KEY1) == RESET && GPIO_ReadInputDataBit(GPIOA, KEY2) == SET)
{
ChangeCurrentColor();
while(GPIO_ReadInputDataBit(GPIOA, KEY1) == RESET); // 等待KEY1释放
}
// 修改后,KEY1点亮指示灯为保存后颜色
GPIO_SetBits(GPIOA, savedColor);
}
}
请注意,以上代码是一个简单的示例,您可能需要根据您的硬件和具体需求进行适当的修改。
内容由零声教学AI助手提供,问题来源于学员提问




