要求通过单片机实现以下功能:
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