// #include "exti_button.h" // #include "button.h" // #include "led.h" // /* // * ---按键-----+--PIN--+---输入方式---+--CNF 位的值--+--MODE 位的值--+--按下状态-- // * KEY0 | PC9 | 上拉输入 | 10 | 00 | 0 // * KEY1 | PC8 | 上拉输入 | 10 | 00 | 0 // * KEY2(WK_UP) | PA0 | 下拉输入 | 10 | 00 | 1 // */ // /* // * 外部终端实验,当 Key2 按下时,点亮或熄灭 LED2 // */ // // 初始化 Key2,将 Key2 设置成中断控制。 // void exti_button2_init(void) // { // NVIC_InitTypeDef NVIC_InitStruct; // EXTI_InitTypeDef EXTI_InitStruct; // // 开启按键的时钟,并初始化 PC8/PC9/PA0 的输入模式 // button_init(); // // 开启按键的复用 IO 时钟(使用中断必须开启复用时钟) // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // // 开启并设置 NVIC // // 设置 EXTI0 的设置 // NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // // 抢占是优先级 // NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // // 子优先级 // NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; // NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStruct); // // 开启并设置 EXTI // // 配置 EXTI0 的中断线选择 PA0 // GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // // EXTI 的第 0 号线 // EXTI_InitStruct.EXTI_Line = EXTI_Line0; // // 中断还是事件,我们 // EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // // 上升沿触发 // EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // // 使能 // EXTI_InitStruct.EXTI_LineCmd = ENABLE; // // // EXTI_Init(&EXTI_InitStruct); // } // // EXTI0 的中断处理函数 // void EXTI0_IRQHandler(void) // { // if (EXTI_GetITStatus(EXTI_Line0) == SET) // { // // 清除中断挂起屏蔽位 // EXTI_ClearITPendingBit(EXTI_Line0); // led_set_status(2, !led_get_status(2)); // } // } #include "exti_button.h" #include "button.h" #include "led.h" #include "beep.h" /* * ---按键-----+--PIN--+---输入方式---+--CNF 位的值--+--MODE 位的值--+--按下状态-- * KEY0 | PC9 | 上拉输入 | 10 | 00 | 0 * KEY1 | PC8 | 上拉输入 | 10 | 00 | 0 * KEY2(WK_UP) | PA0 | 下拉输入 | 10 | 00 | 1 */ /* * 外部终端实验,当 Key0 按下时,点亮或熄灭 LED0 */ // 初始化 Key0,将 Key0 设置成中断控制。 void exti_button0_init(void) // 函数名可以改一下,更清晰 { NVIC_InitTypeDef NVIC_InitStruct; EXTI_InitTypeDef EXTI_InitStruct; // 开启按键的时钟,并初始化 PC8/PC9/PA0 的输入模式 button_init(); // 开启复用 IO 时钟(使用中断必须开启复用时钟) RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // --- 1. 修改 NVIC 配置 --- // 设置 EXTI9_5 的中断通道 NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn; // 从 EXTI0_IRQn 修改为 EXTI9_5_IRQn // 抢占优先级 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // 子优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; // 子优先级也可以调整 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // --- 2. 修改 EXTI 配置 --- // 配置 EXTI9 的中断线选择 PC9 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource9); // 从 GPIOA, PinSource0 修改 // EXTI 的第 9 号线 EXTI_InitStruct.EXTI_Line = EXTI_Line9; // 从 EXTI_Line0 修改为 EXTI_Line9 // 模式:中断 EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // KEY0 是上拉输入,按下变低电平,所以是下降沿触发 EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 使能 EXTI_InitStruct.EXTI_LineCmd = ENABLE; // 初始化 EXTI_Init(&EXTI_InitStruct); } // --- 3. 修改中断服务函数 --- // EXTI9_5 的中断处理函数 (处理 EXTI 线 5 到 9) // void EXTI9_5_IRQHandler(void) // { // // 检查是否是 EXTI Line9 触发的中断 // if (EXTI_GetITStatus(EXTI_Line9) == SET) // { // // 清除 Line9 上的中断挂起屏蔽位 // EXTI_ClearITPendingBit(EXTI_Line9); // // --- 4. 修改控制的 LED --- // // 翻转 LED0 的状态 // led_set_status(1, !led_get_status(1)); // } // // 如果你还用了 EXTI5, 6, 7, 8,可以在这里继续添加 if 判断 // } void EXTI9_5_IRQHandler(void) { // 检查是否是 EXTI Line9 触发的中断 if (EXTI_GetITStatus(EXTI_Line9) == SET) { // 清除 Line9 上的中断挂起屏蔽位 EXTI_ClearITPendingBit(EXTI_Line9); // --- 核心修改部分:翻转蜂鸣器的状态 --- // 1. 读取蜂鸣器引脚(PC7)当前的输出状态 // GPIO_ReadOutputDataBit返回0或1 if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7) == 1) { // 如果当前是响的 (高电平), 就关闭它 beep_off(); } else { // 如果当前是关的 (低电平), 就打开它 beep_on(); } } }