要求通过单片机实现以下功能:
1.单片机有三种工作模式(定义全局变量MM表示模式,MM=1,2,3表示三种不同的模式)
- LED控制模式
- 风扇控制模式
- 蜂鸣器控制模式
2.可以在某一个模式下通过拓展板KEY1按键控制设备
按键按下一次,设备打开,按键再按下一次,设备关闭(设备管脚输出反向电平)
3.关于模式的切换可以通过以下两种方式:
- 通过串口通信,电脑端发送当前模式(设置串口接收中断,接收到的字符串进行比较)
- 电脑发送BEE,进入蜂鸣器控制模式
- 电脑发送FAN ,进行风扇控制模式
- 电脑发送LED,进入LED模式
- 通过底板用户自定义按键进行模式切换
- 按键按下一次进入LE
D模式,再按一次,进入风扇模式,再按一下,进入蜂鸣器模式char buf[128];//用于接受数据 int MM=0; uint32_t lastDebounceTime = 0; // 上次有效触发的时间 const uint32_t debounceDelay = 10; // 消抖时间阈值(单位ms)int find_char(const char *str, char c) {int i = 0;while (str[i] != '\0'){if (str[i] == c){return i; // 找到字符,返回索引}i++;}return -1; // 未找到字符,返回 -1 }// 手动实现字符串长度计算 int string_length(const char *str) {int len = 0;while (str[len] != '\0'){len++;}return len; }int compare_strings(const char *str1, const char *str2) {while (*str1 && *str2){if (*str1 != *str2){return 0; // 不相等}str1++;str2++;}// 如果两个字符串都结束了,说明完全相等return (*str1 == '\0' && *str2 == '\0') ? 1 : 0; }void ToggleDevicePin(int mode) {switch (mode){case 0:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);break;case 1:HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);break;case 2:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);break;default:break;} } void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {if (GPIO_Pin == GPIO_PIN_9){ToggleDevicePin(MM); // 根据当前模式切换管脚状态}else if (GPIO_Pin == GPIO_PIN_12){uint32_t currentTime = HAL_GetTick(); // 获取当前时间(ms)// 消抖逻辑if ((currentTime - lastDebounceTime) > debounceDelay){lastDebounceTime = currentTime; // 更新上次触发时间MM = (MM + 1) % 3; // 切换 MM 状态}} }void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {printf("uart1_recv intterrput OK:%s\n",buf);static int index = 0; // 当前接收缓冲区索引if (buf[index] == '\n' || index >= sizeof(buf) - 1) // 检测到换行符或缓冲区已满{buf[index] = '\0'; // 标记字符串结束//dataReady = 1; // 设置数据接收完成标志index = 0; // 重置缓冲区索引}else{index++; // 增加索引,准备接收下一个字符}HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf[index], 1); // 继续接收 }
- 按键按下一次进入LE