好的,下面是一个使用Keil uVision5编写的示例代码,满足你的要求。假设你使用的是STM32F103C8T6单片机,并且已经配置好了GPIO和定时器。 ```c / * @file main.c * @brief 声光控制模式切换程序 * @details 上电后8个LED全灭、蜂鸣器不响;通过4个按键K1、K2、K3、K4控制不同的声光模式。 */ #include "stm32f10x.h" // 定义LED和按键的GPIO端口和引脚 #define LED_PORT GPIOC #define LED_PIN_0 GPIO_Pin_0 #define LED_PIN_1 GPIO_Pin_1 #define LED_PIN_2 GPIO_Pin_2 #define LED_PIN_3 GPIO_Pin_3 #define LED_PIN_4 GPIO_Pin_4 #define LED_PIN_5 GPIO_Pin_5 #define LED_PIN_6 GPIO_Pin_6 #define LED_PIN_7 GPIO_Pin_7 #define BUTTON_PORT GPIOA #define BUTTON_K1 GPIO_Pin_0 #define BUTTON_K2 GPIO_Pin_1 #define BUTTON_K3 GPIO_Pin_2 #define BUTTON_K4 GPIO_Pin_3 #define BUZZER_PORT GPIOB #define BUZZER_PIN GPIO_Pin_0 // 定义全局变量 volatile uint8_t mode = 0; // 当前模式 volatile uint8_t led_state = 0x01; // LED状态 // 初始化GPIO void GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); // 配置LED为推挽输出 GPIO_InitStructure.GPIO_Pin = LED_PIN_0 | LED_PIN_1 | LED_PIN_2 | LED_PIN_3 | LED_PIN_4 | LED_PIN_5 | LED_PIN_6 | LED_PIN_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); // 配置按键为浮空输入 GPIO_InitStructure.GPIO_Pin = BUTTON_K1 | BUTTON_K2 | BUTTON_K3 | BUTTON_K4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(BUTTON_PORT, &GPIO_InitStructure); // 配置蜂鸣器为推挽输出 GPIO_InitStructure.GPIO_Pin = BUZZER_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BUZZER_PORT, &GPIO_InitStructure); // 初始化LED和蜂鸣器状态 GPIO_Write(GPIOC, 0x00); // 8个LED全灭 GPIO_WriteBit(GPIOB, BUZZER_PIN, Bit_RESET); // 蜂鸣器不响 } // 按键检测函数 uint8_t Button_Detect(uint16_t button_pin) { uint8_t button_pressed = 0; if (GPIO_ReadInputDataBit(BUTTON_PORT, button_pin) == Bit_RESET) { // 按键按下 Delay(20); // 去抖动 if (GPIO_ReadInputDataBit(BUTTON_PORT, button_pin) == Bit_RESET) { // 再次确认按键按下 while (GPIO_ReadInputDataBit(BUTTON_PORT, button_pin) == Bit_RESET); // 等待按键抬起 button_pressed = 1; } } return button_pressed; } // 延时函数 void Delay(uint32_t nCount) { for (; nCount != 0; nCount--); } // 主函数 int main(void) { GPIO_Init(); // 初始化GPIO while (1) { // 检测按键K1 if (Button_Detect(BUTTON_K1)) { mode = 1; // 切换到模式1 } // 检测按键K2 if (Button_Detect(BUTTON_K2)) { mode = 2; // 切换到模式2 } // 检测按键K3 if (Button_Detect(BUTTON_K3)) { mode = 3; // 切换到模式3 } // 检测按键K4 if (Button_Detect(BUTTON_K4)) { mode = 0; // 切换到模式0 } // 根据当前模式执行相应的操作 switch (mode) { case 0: // 模式0:8个LED全灭、蜂鸣器不响 GPIO_Write(GPIOC, 0x00); // 8个LED全灭 GPIO_WriteBit(GPIOB, BUZZER_PIN, Bit_RESET); // 蜂鸣器不响 break; case 1: // 模式1:蜂鸣器间隔响 GPIO_WriteBit(GPIOB, BUZZER_PIN, Bit_SET); // 蜂鸣器响 Delay(500); // 延时 GPIO_WriteBit(GPIOB, BUZZER_PIN, Bit_RESET); // 蜂鸣器不响 Delay(500); // 延时 break; case 2: // 模式2:8个LED左移流水 GPIO_Write(GPIOC, led_state); // 设置LED状态 led_state <<= 1; // 左移一位 if (led_state == 0x00) { led_state = 0x01; // 重置LED状态 } Delay(200); // 延时 break; case 3: // 模式3:8个LED右移流水 GPIO_Write(GPIOC, led_state); // 设置LED状态 led_state >>= 1; // 右移一位 if (led_state == 0x00) { led_state = 0x80; // 重置LED状态 } Delay(200); // 延时 break; default: break; } } } ``` 代码说明 1. GPIO初始化:配置了LED、按键和蜂鸣器的GPIO端口和引脚。 2. 按键检测函数:`Button_Detect`函数用于检测按键是否被按下并抬起,去抖动处理。 3. 延时函数:`Delay`函数用于产生延时。 4. 主函数:在主循环中检测按键状态,并根据当前模式执行相应的操作。 注意事项 - 延时函数:`Delay`函数使用的是简单的循环延时,适用于简单的应用。如果需要更精确的延时,可以使用定时器。 - 去抖动:按键检测函数中加入了去抖动处理,确保按键状态的准确性。 - 模式切换:通过按键K1、K2、K3、K4分别切换不同的模式。 希望这段代码能满足你的需求!如果有任何问题或需要进一步的修改,请告诉我。 [2024-10-24 16:49:54 | AI写代码神器 | 1570点数解答]