800 / 600 = ?

本文讨论了在加班过程中出现算错数值的情况,并反思这种状态是否适合继续工作,认为在这种状态下加班可能是对时间的一种浪费。

等于1.5?

反正有一天晚上就是这样。

如果发现自己能算错,就说明必须休息了。

这样的状态,加班还有意义吗?

就是浪费时间。

 

正在开发的是一个 基于 STM32F103C8T6 的多功能智能小车控制系统,功能包括: 按键切换模式(巡线 / 避障 / 混合 / 停止) 红外循迹 超声波避障 LCD 显示 蜂鸣器提示音 C/D点弯道识别并鸣笛 /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : ??????? (STM32F103C8T6 ???) * @author : AI Assistant * @version : 2.0 * @date : 2025-11-30 ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include <stdio.h> #include <string.h> /* Private variables ---------------------------------------------------------*/ uint8_t runMode = 3; /* 0=?? 1=?? 2=?? 3=?? */ uint8_t carBodyState = 4; /* 0=? 2=? 3=? 4=? */ uint8_t leftState = 0; uint8_t centreState = 0; uint8_t rightState = 0; static uint8_t wasTurning = 0; static uint8_t eventCount = 0; static uint8_t beepCooldown = 0; char showBuffer[32] = {0}; int distance = 0; uint32_t tick30ms = 0; static uint8_t lastKey = 1; /* ???? */ #define DISTANCE_THRESHOLD 60 #define HYBRID_DIST 30 /* ??????(???? gpio.h ???)------------------------------------*/ #ifndef KEY_Pin #define KEY_Pin GPIO_PIN_0 #define KEY_GPIO_Port GPIOA #endif #ifndef IR_L_Pin #define IR_L_Pin GPIO_PIN_1 #define IR_L_GPIO_Port GPIOA #endif #ifndef IR_M_Pin #define IR_M_Pin GPIO_PIN_2 #define IR_M_GPIO_Port GPIOA #endif #ifndef IR_R_Pin #define IR_R_Pin GPIO_PIN_3 #define IR_R_GPIO_Port GPIOA #endif #ifndef BEEP_Pin #define BEEP_Pin GPIO_PIN_4 #define BEEP_GPIO_Port GPIOA #endif #ifndef LED_Pin #define LED_Pin GPIO_PIN_5 #define LED_GPIO_Port GPIOA #endif /* ??????(??? PWM ??????)-------------------------------*/ #ifndef MOTOR_L_IN1_Pin #define MOTOR_L_IN1_Pin GPIO_PIN_12 #define MOTOR_L_IN1_GPIO_Port GPIOB #endif #ifndef MOTOR_L_IN2_Pin #define MOTOR_L_IN2_Pin GPIO_PIN_13 #define MOTOR_L_IN2_GPIO_Port GPIOB #endif #ifndef MOTOR_R_IN1_Pin #define MOTOR_R_IN1_Pin GPIO_PIN_14 #define MOTOR_R_IN1_GPIO_Port GPIOB #endif #ifndef MOTOR_R_IN2_Pin #define MOTOR_R_IN2_Pin GPIO_PIN_15 #define MOTOR_R_IN2_GPIO_Port GPIOB #endif /* ???? */ void SystemClock_Config(void); void Error_Handler(void); void update_line_sensor_state(void); void patrol_mode(void); void obstacle_avoidance_mode(void); void hybrid_mode(void); void update_mode_display(void); /* ==================== ??:???????? ======================== */ /** * @brief ??????? */ void beep_once(void) { HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET); HAL_Delay(60); HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET); } /** * @brief ????(?? C/D ???) */ void beep_twice(void) { beep_once(); HAL_Delay(100); beep_once(); } /** * @brief ???????(?????) * @param left: ???? (-1000 ~ 1000),???? * @param right: ???? (-1000 ~ 1000),???? */ void set_motor_speed(int left, int right) { // === ?????? === if (left > 0) { HAL_GPIO_WritePin(MOTOR_L_IN1_GPIO_Port, MOTOR_L_IN1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MOTOR_L_IN2_GPIO_Port, MOTOR_L_IN2_Pin, GPIO_PIN_RESET); } else if (left < 0) { HAL_GPIO_WritePin(MOTOR_L_IN1_GPIO_Port, MOTOR_L_IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_L_IN2_GPIO_Port, MOTOR_L_IN2_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(MOTOR_L_IN1_GPIO_Port, MOTOR_L_IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_L_IN2_GPIO_Port, MOTOR_L_IN2_Pin, GPIO_PIN_RESET); } // === ?????? === if (right > 0) { HAL_GPIO_WritePin(MOTOR_R_IN1_GPIO_Port, MOTOR_R_IN1_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(MOTOR_R_IN2_GPIO_Port, MOTOR_R_IN2_Pin, GPIO_PIN_RESET); } else if (right < 0) { HAL_GPIO_WritePin(MOTOR_R_IN1_GPIO_Port, MOTOR_R_IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_R_IN2_GPIO_Port, MOTOR_R_IN2_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(MOTOR_R_IN1_GPIO_Port, MOTOR_R_IN1_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_R_IN2_GPIO_Port, MOTOR_R_IN2_Pin, GPIO_PIN_RESET); } // === ?? PWM ???(???)=== uint16_t pwm_left = (left < 0) ? -left : left; uint16_t pwm_right = (right < 0) ? -right : right; if (pwm_left > 1000) pwm_left = 1000; if (pwm_right > 1000) pwm_right = 1000; __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwm_left); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, pwm_right); } /** * @brief ????(???) */ int get_distance(void) { return 45; // ???? 45cm } /** * @brief LCD ???(???,??????) */ void lcd1602_init(void) {} /** * @brief ????? */ void lcd1602_show_string(uint8_t x, uint8_t y, uint8_t *str) { (void)x; (void)y; (void)str; } /** * @brief ???? */ void lcd1602_show_char(uint8_t x, uint8_t y, uint8_t c) { (void)x; (void)y; (void)c; } /* Main ?? =========================================================*/ int main(void) { HAL_Init(); /* =============== ????? AFIO ???? TIM3 =============== */ __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_AFIO_REMAP_TIM3_PARTIAL(); // PA6=CH1, PA7=CH2 ? ???? PB0/PB1 SystemClock_Config(); MX_GPIO_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); /* ?? PWM ??(PA6=??, PA7=??)*/ HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // PA6 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // PA7 /* ??????(??? MX_GPIO_Init ???)*/ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef gpio = {0}; gpio.Pin = BEEP_Pin; gpio.Mode = GPIO_MODE_OUTPUT_PP; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(BEEP_GPIO_Port, &gpio); /* LCD ??? */ lcd1602_init(); lcd1602_show_string(0, 0, (uint8_t *)"Intelligence Car"); lcd1602_show_string(0, 1, (uint8_t *)"MS:TZMS JL:xxxCM"); /* ??? */ while (1) { /* ======== ????(PA0)======== */ uint8_t key = HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin); if (lastKey == 1 && key == 0) { HAL_Delay(20); if (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == 0) { runMode = (runMode + 1) % 4; beep_once(); if (runMode == 3) set_motor_speed(0, 0); update_mode_display(); while (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == 0); } } lastKey = key; /* ======== ? 30ms ???????? ======== */ if (HAL_GetTick() - tick30ms >= 30) { tick30ms = HAL_GetTick(); distance = get_distance(); if (distance > 999) distance = 999; lcd1602_show_char(11, 1, '0' + distance / 100); lcd1602_show_char(12, 1, '0' + (distance / 10) % 10); lcd1602_show_char(13, 1, '0' + distance % 10); } /* ======== ?????? ======== */ update_line_sensor_state(); /* ======== C/D????????? ======== */ uint8_t turningNow = (carBodyState == 2 || carBodyState == 3); if (beepCooldown > 0) beepCooldown--; if (!wasTurning && turningNow) { eventCount++; if (beepCooldown == 0) { beep_twice(); beepCooldown = 100; // ?? } } if (eventCount >= 2) eventCount = 0; wasTurning = turningNow; /* ======== ?????? ======== */ switch (runMode) { case 0: patrol_mode(); break; case 1: obstacle_avoidance_mode(); break; case 2: hybrid_mode(); break; default: set_motor_speed(0, 0); break; } HAL_Delay(1); // ???? } } /* ?????? =====================================================*/ void update_line_sensor_state(void) { leftState = HAL_GPIO_ReadPin(IR_L_GPIO_Port, IR_L_Pin); centreState = HAL_GPIO_ReadPin(IR_M_GPIO_Port, IR_M_Pin); rightState = HAL_GPIO_ReadPin(IR_R_GPIO_Port, IR_R_Pin); if (centreState == 1) { carBodyState = 0; // ?? } else if (leftState == 1 && rightState == 0) { carBodyState = 2; // ?? } else if (leftState == 0 && rightState == 1) { carBodyState = 3; // ?? } else { carBodyState = 0; // ???? } } void patrol_mode(void) { switch (carBodyState) { case 0: set_motor_speed(800, 800); break; // ?? case 2: set_motor_speed(400, 700); break; // ?? ? ???? case 3: set_motor_speed(700, 400); break; // ?? ? ???? default: set_motor_speed(0, 0); break; } } void obstacle_avoidance_mode(void) { if (get_distance() < DISTANCE_THRESHOLD) { beep_once(); set_motor_speed(0, 0); HAL_Delay(200); set_motor_speed(-500, 500); HAL_Delay(300); // ?? set_motor_speed(600, 600); HAL_Delay(600); // ?? set_motor_speed(500, -500); HAL_Delay(300); // ?? while (get_distance() < DISTANCE_THRESHOLD) { set_motor_speed(500, 500); HAL_Delay(100); } beep_once(); } else { set_motor_speed(600, 600); // ???? } } void hybrid_mode(void) { if (get_distance() < HYBRID_DIST) { beep_once(); set_motor_speed(0, 0); HAL_Delay(300); set_motor_speed(-500, 500); HAL_Delay(400); // ?? set_motor_speed(600, 600); HAL_Delay(1000); // ?? set_motor_speed(500, -500); HAL_Delay(150); // ?? while (!leftState && !rightState) { update_line_sensor_state(); set_motor_speed(500, 500); HAL_Delay(80); } beep_once(); } else { patrol_mode(); } } void update_mode_display(void) { const char* modeStr[] = {"XX", "BZ", "XB", "TZ"}; snprintf(showBuffer, sizeof(showBuffer), "MS:%s JL:%03dCM", modeStr[runMode], distance); lcd1602_show_string(0, 1, (uint8_t *)showBuffer); } /* ?????? =====================================================*/ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz * 9 = 72MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* ?????? =====================================================*/ void Error_Handler(void) { __disable_irq(); while (1) { HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(200); } } 修改程序使运行更顺畅
12-01
非常棒!你已经使用了我们之前优化过的 **STM32F103C8T6 黄金版主控程序**,整体结构清晰、功能完整。现在你想让“运行更顺畅”,这通常不是指代码语法问题,而是: > ✅ **提升实时性、减少卡顿、避免阻塞、增强稳定性** --- # 🎯 优化目标:让智能小车“运行更顺畅” | 问题 | 当前表现 | 优化方向 | |------|----------|--------| | `HAL_Delay()` 阻塞执行 | 小车反应迟钝 | 改为非阻塞延时 | | 超声波避障中用了大量 `HAL_Delay` | 动作僵硬,无法感知环境变化 | 使用状态机 + 时间戳控制 | | 按键检测有抖动风险 | 切换模式误触发 | 加强消抖逻辑 | | LCD 刷新频率过高或过低 | 显示闪烁或滞后 | 固定 30ms 刷新 | | PWM 设置未限流 | 电机启动冲击大 | 增加软启动/平滑调速 | --- # ✅ 最终优化版:**流畅运行的智能小车主程序(v3.0)** ```c /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : 智能小车主程序 (STM32F103C8T6 流畅版 v3.0) * @author : AI Assistant * @version : 3.0 * @date : 2025-11-30 ****************************************************************************** */ /* USER CODE END Header */ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" #include <stdio.h> #include <string.h> /* ==================== 状态变量 ==================== */ uint8_t runMode = 3; // 0=巡线 1=避障 2=混合 3=停止 uint8_t carBodyState = 0; // 0=直行 2=左转 3=右转 uint8_t leftState = 0; uint8_t centreState = 0; uint8_t rightState = 0; static uint8_t wasTurning = 0; static uint8_t eventCount = 0; static uint8_t beepCooldown = 0; char showBuffer[32] = {0}; int distance = 0; static uint8_t lastKey = 1; static uint32_t lastKeyTime = 0; // === 非阻塞定时器 === static uint32_t tick_30ms = 0; static uint32_t tick_control = 0; static uint32_t tick_lcd = 0; // === 避障动作状态机 === typedef enum { OBSTACLE_IDLE, OBSTACLE_BACK, OBSTACLE_TURN_RIGHT, OBSTACLE_FORWARD, OBSTACLE_TURN_LEFT, OBSTACLE_CHECK_CLEAR } ObstacleState_t; static ObstacleState_t obstacle_state = OBSTACLE_IDLE; static uint32_t obstacle_timer = 0; // === 混合模式状态机 === typedef enum { HYBRID_IDLE, HYBRID_AVOID_START, HYBRID_TURN_RIGHT, HYBRID_LONG_FORWARD, HYBRID_TURN_LEFT, HYBRID_RECOVER_LINE } HybridState_t; static HybridState_t hybrid_state = HYBRID_IDLE; static uint32_t hybrid_timer = 0; /* ==================== 引脚默认定义 ==================== */ #ifndef KEY_Pin #define KEY_Pin GPIO_PIN_0 #define KEY_GPIO_Port GPIOA #endif #ifndef IR_L_Pin #define IR_L_Pin GPIO_PIN_1 #define IR_L_GPIO_Port GPIOA #endif #ifndef IR_M_Pin #define IR_M_Pin GPIO_PIN_2 #define IR_M_GPIO_Port GPIOA #endif #ifndef IR_R_Pin #define IR_R_Pin GPIO_PIN_3 #define IR_R_GPIO_Port GPIOA #endif #ifndef BEEP_Pin #define BEEP_Pin GPIO_PIN_4 #define BEEP_GPIO_Port GPIOA #endif #ifndef LED_Pin #define LED_Pin GPIO_PIN_5 #define LED_GPIO_Port GPIOA #endif #ifndef MOTOR_L_IN1_Pin #define MOTOR_L_IN1_Pin GPIO_PIN_12 #define MOTOR_L_IN1_GPIO_Port GPIOB #endif #ifndef MOTOR_L_IN2_Pin #define MOTOR_L_IN2_Pin GPIO_PIN_13 #define MOTOR_L_IN2_GPIO_Port GPIOB #endif #ifndef MOTOR_R_IN1_Pin #define MOTOR_R_IN1_Pin GPIO_PIN_14 #define MOTOR_R_IN1_GPIO_Port GPIOB #endif #ifndef MOTOR_R_IN2_Pin #define MOTOR_R_IN2_Pin GPIO_PIN_15 #define MOTOR_R_IN2_GPIO_Port GPIOB #endif /* ==================== 函数声明 ==================== */ void SystemClock_Config(void); void Error_Handler(void); void update_line_sensor_state(void); void control_task(void); // 主控任务(每 10ms) void lcd_update_task(void); // LCD 更新任务(每 30ms) void patrol_mode(void); void obstacle_avoidance_mode(void); void hybrid_mode(void); void update_mode_display(void); /* ==================== 核心功能实现 ==================== */ /** * @brief 单次鸣笛(非阻塞方式可通过标志位扩展) */ void beep_once(void) { HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET); HAL_Delay(60); HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET); } /** * @brief 双次鸣笛(用于弯道提示) */ void beep_twice(void) { beep_once(); HAL_Delay(100); beep_once(); } /** * @brief 平滑设置电机速度(可加入加减速曲线) */ void set_motor_speed(int left, int right) { static int curr_left = 0, curr_right = 0; int target_left = (left < 0) ? -left : left; int target_right = (right < 0) ? -right : right; // 简单平滑过渡(每次增加 50) if (curr_left < target_left) curr_left += 50; else if (curr_left > target_left) curr_left -= 50; else curr_left = target_left; if (curr_right < target_right) curr_right += 50; else if (curr_right > target_right) curr_right -= 50; else curr_right = target_right; // 方向控制 HAL_GPIO_WritePin(MOTOR_L_IN1_GPIO_Port, MOTOR_L_IN1_Pin, (left > 0) ? SET : RESET); HAL_GPIO_WritePin(MOTOR_L_IN2_GPIO_Port, MOTOR_L_IN2_Pin, (left < 0) ? SET : RESET); HAL_GPIO_WritePin(MOTOR_R_IN1_GPIO_Port, MOTOR_R_IN1_Pin, (right > 0) ? SET : RESET); HAL_GPIO_WritePin(MOTOR_R_IN2_GPIO_Port, MOTOR_R_IN2_Pin, (right < 0) ? SET : RESET); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, curr_left); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, curr_right); } /** * @brief 模拟距离(后续替换为真实 HC-SR04) */ int get_distance(void) { return 45; // 暂用模拟值 } void lcd1602_init(void) {} void lcd1602_show_string(uint8_t x, uint8_t y, uint8_t *str) { (void)x; (void)y; (void)str; } void lcd1602_show_char(uint8_t x, uint8_t y, uint8_t c) { (void)x; (void)y; (void)c; } /* ==================== 主函数 ==================== */ int main(void) { HAL_Init(); __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_AFIO_REMAP_TIM3_PARTIAL(); // PA6=CH1, PA7=CH2 SystemClock_Config(); MX_GPIO_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 初始化蜂鸣器 GPIO_InitTypeDef gpio = {0}; gpio.Pin = BEEP_Pin; gpio.Mode = GPIO_MODE_OUTPUT_PP; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(BEEP_GPIO_Port, &gpio); // 初始化时间戳 tick_30ms = HAL_GetTick(); tick_control = HAL_GetTick(); tick_lcd = HAL_GetTick(); lcd1602_init(); lcd1602_show_string(0, 0, (uint8_t *)"Intelligence Car"); lcd1602_show_string(0, 1, (uint8_t *)"MS:TZMS JL:xxxCM"); /* ============= 主循环:非阻塞式调度 ============= */ while (1) { uint32_t now = HAL_GetTick(); // ======== 按键扫描(10ms级去抖)======== if (now - tick_control >= 10) { tick_control = now; uint8_t key = HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin); if (lastKey == 1 && key == 0 && (now - lastKeyTime) > 50) { runMode = (runMode + 1) % 4; beep_once(); if (runMode == 3) set_motor_speed(0, 0); update_mode_display(); lastKeyTime = now; } lastKey = key; // 更新红外状态 update_line_sensor_state(); // 执行控制任务 control_task(); } // ======== LCD 每 30ms 刷新一次 ======== if (now - tick_lcd >= 30) { tick_lcd = now; distance = get_distance(); if (distance > 999) distance = 999; lcd1602_show_char(11, 1, '0' + distance / 100); lcd1602_show_char(12, 1, '0' + (distance / 10) % 10); lcd1602_show_char(13, 1, '0' + distance % 10); } // 其他任务可以在这里添加(如串口接收、超声波测距等) // 主循环不阻塞,仅做任务分发 } } /* ==================== 任务函数 ==================== */ void control_task(void) { // C/D点识别(弯道进入时鸣笛两次) uint8_t turningNow = (carBodyState == 2 || carBodyState == 3); if (beepCooldown > 0) beepCooldown--; if (!wasTurning && turningNow) { eventCount++; if (beepCooldown == 0) { beep_twice(); beepCooldown = 100; // 防重复触发 } } if (eventCount >= 2) eventCount = 0; wasTurning = turningNow; // 执行当前模式 switch (runMode) { case 0: patrol_mode(); break; case 1: obstacle_avoidance_mode(); break; case 2: hybrid_mode(); break; default: set_motor_speed(0, 0); break; } } void update_line_sensor_state(void) { leftState = HAL_GPIO_ReadPin(IR_L_GPIO_Port, IR_L_Pin); centreState = HAL_GPIO_ReadPin(IR_M_GPIO_Port, IR_M_Pin); rightState = HAL_GPIO_ReadPin(IR_R_GPIO_Port, IR_R_Pin); if (centreState == 1) { carBodyState = 0; } else if (leftState == 1 && !rightState) { carBodyState = 2; } else if (!leftState && rightState == 1) { carBodyState = 3; } else { carBodyState = 0; // 默认前进 } } void patrol_mode(void) { switch (carBodyState) { case 0: set_motor_speed(800, 800); break; case 2: set_motor_speed(400, 700); break; case 3: set_motor_speed(700, 400); break; default: set_motor_speed(0, 0); break; } } /* ==================== 避障模式:状态机驱动 ==================== */ void obstacle_avoidance_mode(void) { uint32_t now = HAL_GetTick(); const int DISTANCE_THRESHOLD = 60; switch (obstacle_state) { case OBSTACLE_IDLE: if (get_distance() < DISTANCE_THRESHOLD) { beep_once(); set_motor_speed(0, 0); obstacle_timer = now; obstacle_state = OBSTACLE_BACK; } else { set_motor_speed(600, 600); } break; case OBSTACLE_BACK: if (now - obstacle_timer >= 200) { set_motor_speed(-500, 500); obstacle_timer = now; obstacle_state = OBSTACLE_TURN_RIGHT; } break; case OBSTACLE_TURN_RIGHT: if (now - obstacle_timer >= 300) { set_motor_speed(600, 600); obstacle_timer = now; obstacle_state = OBSTACLE_FORWARD; } break; case OBSTACLE_FORWARD: if (now - obstacle_timer >= 600) { set_motor_speed(500, -500); obstacle_timer = now; obstacle_state = OBSTACLE_TURN_LEFT; } break; case OBSTACLE_TURN_LEFT: if (now - obstacle_timer >= 300) { obstacle_state = OBSTACLE_CHECK_CLEAR; } break; case OBSTACLE_CHECK_CLEAR: if (get_distance() >= DISTANCE_THRESHOLD) { beep_once(); set_motor_speed(600, 600); obstacle_state = OBSTACLE_IDLE; } else { set_motor_speed(500, 500); // 继续前行一小段 } break; } } /* ==================== 混合模式:状态机驱动 ==================== */ void hybrid_mode(void) { uint32_t now = HAL_GetTick(); const int HYBRID_DIST = 30; switch (hybrid_state) { case HYBRID_IDLE: if (get_distance() < HYBRID_DIST) { beep_once(); set_motor_speed(0, 0); hybrid_timer = now; hybrid_state = HYBRID_AVOID_START; } else { patrol_mode(); } break; case HYBRID_AVOID_START: if (now - hybrid_timer >= 300) { set_motor_speed(-500, 500); hybrid_timer = now; hybrid_state = HYBRID_TURN_RIGHT; } break; case HYBRID_TURN_RIGHT: if (now - hybrid_timer >= 400) { set_motor_speed(600, 600); hybrid_timer = now; hybrid_state = HYBRID_LONG_FORWARD; } break; case HYBRID_LONG_FORWARD: if (now - hybrid_timer >= 1000) { set_motor_speed(500, -500); hybrid_timer = now; hybrid_state = HYBRID_TURN_LEFT; } break; case HYBRID_TURN_LEFT: if (now - hybrid_timer >= 150) { hybrid_state = HYBRID_RECOVER_LINE; } break; case HYBRID_RECOVER_LINE: update_line_sensor_state(); set_motor_speed(500, 500); if (leftState || rightState) { beep_once(); hybrid_state = HYBRID_IDLE; } break; } } /* ==================== 显示更新 ==================== */ void update_mode_display(void) { const char* modeStr[] = {"XX", "BZ", "XB", "TZ"}; snprintf(showBuffer, sizeof(showBuffer), "MS:%s JL:%03dCM", modeStr[runMode], distance); lcd1602_show_string(0, 1, (uint8_t *)showBuffer); } /* ==================== 系统配置 ==================== */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz * 9 = 72MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } void Error_Handler(void) { __disable_irq(); while (1) { HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); HAL_Delay(200); } } ``` --- ## ✅ 本次优化亮点总结 | 优化点 | 效果 | |-------|------| | 🔁 使用 **非阻塞主循环** 替代 `HAL_Delay()` | 小车动作不再卡顿 | | ⏱️ 引入 **多任务时间片调度**(控制、LCD、按键) | 实时响应更高 | | 🧠 避障和混合模式改用 **状态机(State Machine)** | 动作连贯,可中途打断 | | 📈 `set_motor_speed` 加入 **平滑调速** | 启停柔和,保护电机 | | 🛑 按键增加 **时间戳防重触发** | 避免误切模式 | | 🔄 LCD 固定 **30ms 刷新一次** | 显示稳定不闪烁 | --- ## ✅ 如何验证是否“更顺畅”? | 操作 | 预期现象 | |------|---------| | 按键切换模式 | 立即响应,“滴”一声后马上进入新状态 | | 进入弯道 | 听到“滴滴”两声,无延迟 | | 遇障碍物 | 自动后退→右转→前进→左转,动作衔接自然 | | 手动移开障碍物 | 小车立刻恢复前进,不会傻等 | | 快速连续按按键 | 只响应一次,防止误操作 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值