8.1 临界区和竞争条件 2转

/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" #include "main.h" #include "cmsis_os.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "usart.h" #include "gpio.h" #include "tim.h" #include <string.h> #include <stdio.h> /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define MOTOR_PWM_MAX 19999 // PWM最大值 (Period - 1) #define MOTOR_PWM_MIN 0 // PWM最小值 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ struct uart3_rx_t { int num,ok,en; uint8_t data[28]; int class; float score; int x1,y1,x2,y2; uint8_t datarx; }uart3_rx; struct uart2_rx_t { int num,ok,en; uint8_t data[3]; int shexiangtou_en; int manzaijianche_en; int dangban_en; int youhailaji_en; int chuyulaji_en; int kehuishou_en; int qitalaji_en; uint8_t datarx; }uart2_rx; struct pingmu_tx_t { int manzai,ok,en; int class; float score; int x1,y1,x2,y2; }pingmu_tx; osThreadId motorTaskHandle; osThreadId motor2TaskHandle; osThreadId manzaiTaskHandle; osThreadId txTaskHandle; osThreadId uart6MutexHandle; // 新增:电机控制超声波测距任务句柄 osThreadId motorControlTaskHandle; // 电机控制任务句柄 osThreadId ultrasonicTaskHandle; // 超声波测距任务句柄 // 新增:超声波测距变量 float ultrasonic1_distance = 0.0f; // 超声波1测量距离 (cm) float ultrasonic2_distance = 0.0f; // 超声波2测量距离 (cm) // 新增:舵机状态跟踪变量 typedef enum { SERVO_IDLE = 0, // 舵机空闲状态(在原位) SERVO_WORKING = 1, // 舵机正在执行分类动作 SERVO_RETURNING = 2 // 舵机正在回到原位 } ServoState_t; volatile ServoState_t servoState = SERVO_IDLE; // 舵机状态 volatile uint32_t servoWorkStartTime = 0; // 舵机工作开始时间 // 新增:电机启动停止延时控制变量 volatile uint32_t motor1_startConditionStartTime = 0; // 电机1启动条件开始时间 volatile uint32_t motor2_startConditionStartTime = 0; // 电机2启动条件开始时间 volatile uint8_t motor1_startConditionActive = 0; // 电机1启动条件是否激活 volatile uint8_t motor2_startConditionActive = 0; // 电机2启动条件是否激活 volatile uint32_t motor1_stopConditionStartTime = 0; // 电机1停止条件开始时间 volatile uint32_t motor2_stopConditionStartTime = 0; // 电机2停止条件开始时间 volatile uint8_t motor1_stopConditionActive = 0; // 电机1停止条件是否激活 volatile uint8_t motor2_stopConditionActive = 0; // 电机2停止条件是否激活 // 电机当前状态 volatile uint8_t motor1_running = 0; // 电机1是否正在运行 volatile uint8_t motor2_running = 0; // 电机2是否正在运行 /* USER CODE END Variables */ osThreadId defaultTaskHandle; osSemaphoreId motorHandle; osSemaphoreId motor2Handle; osSemaphoreId rxlubancatHandle; osSemaphoreId rxpingmuHandle; osSemaphoreId bujingdianjiHandle; osSemaphoreId manzaiSignalHandle; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ int fun (int a,int b, int c); //_Noreturn void motorTask(void const * argument); _Noreturn void motor2Task(void const * argument); //_Noreturn void bujingdianjiTask(void const * argument); _Noreturn void manzaiTask(void const * argument); _Noreturn void txTask(void const * argument); // 新增:电机控制超声波测距任务函数声明 _Noreturn void motorControlTask(void const * argument); // 核心电机控制任务 _Noreturn void ultrasonicTask(void const * argument); // 超声波测距任务 /* USER CODE END FunctionPrototypes */ void StartDefaultTask(void const * argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ /* GetIdleTaskMemory prototype (linked to static allocation support) */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xIdleTaskTCBBuffer; static StackType_t xIdleStack[configMINIMAL_STACK_SIZE]; void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; *ppxIdleTaskStackBuffer = &xIdleStack[0]; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* place for user code */ } /* USER CODE END GET_IDLE_TASK_MEMORY */ /** * @brief FreeRTOS initialization * @param None * @retval None */ void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* USER CODE BEGIN RTOS_MUTEX */ osMutexDef(uartMutex); osMutexId uartMutexHandle = osMutexCreate(osMutex(uartMutex)); osMutexDef(uart6Mutex); uart6MutexHandle = osMutexCreate(osMutex(uart6Mutex)); /* USER CODE END RTOS_MUTEX */ /* Create the semaphores(s) */ /* definition and creation of motor */ osSemaphoreDef(motor); motorHandle = osSemaphoreCreate(osSemaphore(motor), 1); /* definition and creation of motor2 */ osSemaphoreDef(motor2); motor2Handle = osSemaphoreCreate(osSemaphore(motor2), 1); /* definition and creation of rxlubancat */ osSemaphoreDef(rxlubancat); rxlubancatHandle = osSemaphoreCreate(osSemaphore(rxlubancat), 1); /* definition and creation of rxpingmu */ osSemaphoreDef(rxpingmu); rxpingmuHandle = osSemaphoreCreate(osSemaphore(rxpingmu), 1); osSemaphoreDef(manzaiSignal); manzaiSignalHandle = osSemaphoreCreate(osSemaphore(manzaiSignal), 1); /* definition and creation of bujingdianji */ osSemaphoreDef(bujingdianji); bujingdianjiHandle = osSemaphoreCreate(osSemaphore(bujingdianji), 1); /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ HAL_UART_Receive_IT(&huart1, (uint8_t *)&uart3_rx.datarx, 1); HAL_UART_Receive_IT(&huart6, (uint8_t *)&uart2_rx.datarx, 1); HAL_NVIC_SetPriority(USART1_IRQn, 6, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_SetPriority(USART6_IRQn, 5, 0); HAL_NVIC_EnableIRQ(USART6_IRQn); /* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */ /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ /* definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ // osThreadDef(motorTask, motorTask, osPriorityNormal, 0, 128); // 添加舵机初始化 //__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 1300); // 舵机1初始位置 //__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, 2030); // 舵机2初始位置 // HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); // 启动PWM输出 // HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); // servoState = SERVO_IDLE; // 设置初始状态 // motorTaskHandle = osThreadCreate(osThread(motorTask), NULL); // 保留现有的舵机控制任务 osThreadDef(motor2Task, motor2Task, osPriorityAboveNormal, 0, 128); motor2TaskHandle = osThreadCreate(osThread(motor2Task), NULL); // 保留现有的满载检测任务 osThreadDef(manzaiTask, manzaiTask, osPriorityNormal, 0, 128); manzaiTaskHandle = osThreadCreate(osThread(manzaiTask), NULL); // 保留现有的串口屏通讯任务 osThreadDef(txTask, txTask, osPriorityNormal, 2, 128); txTaskHandle = osThreadCreate(osThread(txTask), NULL); // 新增:电机控制任务 osThreadDef(motorControlTask, motorControlTask, osPriorityNormal, 0, 256); motorControlTaskHandle = osThreadCreate(osThread(motorControlTask), NULL); // 新增:超声波测距任务 osThreadDef(ultrasonicTask, ultrasonicTask, osPriorityLow, 0, 256); ultrasonicTaskHandle = osThreadCreate(osThread(ultrasonicTask), NULL); /* USER CODE END RTOS_THREADS */ } /* USER CODE BEGIN Header_StartDefaultTask */ /** * @brief Function implementing the defaultTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void const * argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ uart2_rx.manzaijianche_en = 1; for(;;) { xSemaphoreTake(rxpingmuHandle,portMAX_DELAY); switch (uart2_rx.data[1]) { case 1: uart2_rx.shexiangtou_en=0; break; case 0: uart2_rx.shexiangtou_en=1; break; case 3: uart2_rx.manzaijianche_en=0; break; case 2: uart2_rx.manzaijianche_en=1; break; case 4: uart2_rx.dangban_en=0; break; case 5: uart2_rx.dangban_en=1; break; case 6: uart2_rx.youhailaji_en=0; break; case 7: uart2_rx.youhailaji_en=1; break; case 8: uart2_rx.chuyulaji_en=0; break; case 9: uart2_rx.chuyulaji_en=1; break; case 10: uart2_rx.kehuishou_en=0; break; case 11: uart2_rx.kehuishou_en=1; break; case 12: uart2_rx.qitalaji_en=0; break; case 13: uart2_rx.qitalaji_en=1; break; default: break; } osDelay(100); } /* USER CODE END StartDefaultTask */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ /* _Noreturn void motorTask(void const * argument) { for(;;) { xSemaphoreTake(motorHandle,portMAX_DELAY); // __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,1410); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,1500); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,1000); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_3,1000); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,1000); osDelay(1000); xSemaphoreGive(motor2Handle); xSemaphoreTake(motorHandle,portMAX_DELAY); // __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,1050); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,1500); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,1500); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_3,1500); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,1500); osDelay(1000); } } */ // 保留现有的舵机控制任务 - 增加状态跟踪 _Noreturn void motor2Task(void const * argument) { // 上电首次执行初始化动作 __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 1300); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, 2030); osDelay(500); // 确保舵机到位 servoState = SERVO_IDLE; for(;;) { xSemaphoreTake(motor2Handle, portMAX_DELAY); if(uart3_rx.ok && uart2_rx.shexiangtou_en == 1 && servoState == SERVO_IDLE) { uart3_rx.ok = 0; // 清除标志 //xSemaphoreTake(motor2Handle, portMAX_DELAY); //uint8_t current_class = uart3_rx.class; // 🎯 设置舵机工作状态 servoState = SERVO_WORKING; //servoWorkStartTime = HAL_GetTick(); switch (uart3_rx.class) { case 0: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; case 1: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,1570); break; case 2: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,2000); osDelay(1000); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; case 3: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,2000); osDelay(500); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,1570); break; default: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2030); break; } osDelay(1000); // 执行分类动作的延时 // 🎯 设置舵机回到原位状态 servoState = SERVO_RETURNING; __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2030); osDelay(1000); // 回到原位的延时 // 🎯 设置舵机空闲状态 servoState = SERVO_IDLE; } osDelay(10); } } // 保留现有的满载检测任务 _Noreturn void manzaiTask(void const * argument) { static uint32_t debounce_count = 0; for(;;) { osDelay(100); if(HAL_GPIO_ReadPin(load1_GPIO_Port,load1_Pin)==GPIO_PIN_RESET || HAL_GPIO_ReadPin(load2_GPIO_Port,load2_Pin)==GPIO_PIN_RESET || HAL_GPIO_ReadPin(load3_GPIO_Port,load3_Pin)==GPIO_PIN_RESET || HAL_GPIO_ReadPin(load4_GPIO_Port,load4_Pin)==GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) == GPIO_PIN_RESET) // 新增PC2检测 { debounce_count++; if (debounce_count >=5){ pingmu_tx.manzai=1; //xSemaphoreGive(rxlubancatHandle); xSemaphoreGive(manzaiSignalHandle); // 使用独立信号量 debounce_count = 0; osDelay(1000); } } else { debounce_count = 0; } //xSemaphoreTake(manzaiSignalHandle, portMAX_DELAY); // 等待满载信号 } } // 保留现有的串口屏通讯任务 _Noreturn void txTask(void const * argument) { int num=0; const char manzaidata[]={0x74,0x30,0x2E,0x74,0x78,0x74,0x3D,0x22,0xC0,0xAC,0xBB, 0xF8,0xC2,0xFA,0xD4,0xD8,0x22,0xff,0xff,0xff}; // const char kongdata[]={0x74,0x30,0x2E,0x74,0x78,0x74,0x3D,0x22,0x20,0x22,0xff,0xff,0xff}; char play[]={0x70,0x6C,0x61,0x79,0x20,0x30,0x2C,0x30,0x2C,0x30}; unsigned char aa[2]={0}; const char start[]={0x64,0x61,0x74,0x61,0x30,0x2E ,0x69 ,0x6E ,0x73 ,0x65 ,0x72 ,0x74 ,0x28 ,0x22 }; const char end[]={0x22,0x29,0xff,0xff,0xff}; const char end2[]={0xff,0xff,0xff}; //塑料 const char data1[]={0x5E,0xCD,0xC1,0xB6,0xB9,'\0'}; //白色瓶 const char data2[]={0x5E ,0xB0 ,0xD7 ,0xC2 ,0xDC ,0xB2 ,0xB7 ,'\0'}; //红色瓶 const char data3[]={0x5E ,0xBA ,0xFA ,0xC2 ,0xDC ,0xB2 ,0xB7 ,'\0'}; //纸片 const char data4[]={0x5E ,0xD6 ,0xBD ,0xB1 ,0xAD ,'\0'}; //石头 const char data5[]={0x5E ,0xCA ,0xAF ,0xCD ,0xB7 ,'\0'}; //玻片 const char data6[]={0x5E ,0xB4,0xC9 ,0xC6 ,0xAC ,'\0'}; //5号电池 const char data7[]={0x5E ,0x35 ,0xBA ,0xC5 ,0xB5 ,0xE7 ,0xB3 ,0xD8 ,'\0'}; //1号电池 const char data8[]={0x5E ,0x31 ,0xBA ,0xC5 ,0xB5 ,0xE7 ,0xB3 ,0xD8 ,'\0'}; //有害垃圾 const char data10[]={0x5E ,0xD3 ,0xD0 ,0xBA ,0xA6 ,0xC0 ,0xAC ,0xBB ,0xF8 ,0x5E,'\0'}; //厨余垃圾 const char data11[]={0x5E ,0xB3 ,0xF8 ,0xD3 ,0xE0 ,0xC0 ,0xAC ,0xBB ,0xF8 ,0x5E,'\0'}; //可回收垃圾 const char data12[]={0x5E ,0xBF ,0xC9 ,0xBB ,0xD8 ,0xCA ,0xD5 ,0xC0 ,0xAC ,0xBB ,0xF8 ,0x5E,'\0'}; //其他垃圾 const char data13[]={0x5E ,0xC6 ,0xE4 ,0xCB ,0xFB ,0xC0 ,0xAC ,0xBB ,0xF8 ,0x5E,'\0'}; const char* data[]={data8,data4,data7,data5,data6,data2,data3,data1,data1,data1,data1}; uart2_rx.manzaijianche_en=0; uart2_rx.shexiangtou_en=1; for(;;) { //uint8_t current_class = uart3_rx.class; xSemaphoreTake(rxlubancatHandle,portMAX_DELAY); if(uart3_rx.ok && uart2_rx.shexiangtou_en ==1 ){ uart3_rx.ok=0; HAL_GPIO_TogglePin(led0_GPIO_Port,led0_Pin); uart3_rx.class = uart3_rx.data[1] - 0x30; if(servoState == SERVO_IDLE){ //uart3_rx.class = current_class; xSemaphoreGive(motor2Handle); // 触发舵机动作 } //xSemaphoreGive(motor2Handle); // 触发舵机动作 uart3_rx.class=uart3_rx.data[1]-0x30; if(uart3_rx.class<0 || uart3_rx.class>9) uart3_rx.class=11; aa[1]=num%10+0x30; aa[0]=num/10+0x30; HAL_UART_Transmit(&huart6, (uint8_t *) start,sizeof(start),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *)aa, 2,0xFFFF); switch (uart3_rx.class) { case 0: case 2: HAL_UART_Transmit(&huart6, (uint8_t *) data[uart3_rx.class], strlen(data[uart3_rx.class]),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) data10, strlen(data10),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *)aa, 2,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end, sizeof(end),0xFFFF); play[7]=0x30; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); break;//有害垃圾 case 5: case 6: case 7: HAL_UART_Transmit(&huart6, (uint8_t *) data[uart3_rx.class], strlen(data[uart3_rx.class]),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) data11, strlen(data11),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *)aa, 2,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end, sizeof(end),0xFFFF); play[7]=0x31; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); break;//厨余垃圾 case 1: HAL_UART_Transmit(&huart6, (uint8_t *) data[uart3_rx.class], strlen(data[uart3_rx.class]),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) data12, strlen(data12),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *)aa, 2,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end, sizeof(end),0xFFFF); play[7]=0x32; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); break;//可回收垃圾 case 3: case 4: HAL_UART_Transmit(&huart6, (uint8_t *) data[uart3_rx.class], strlen(data[uart3_rx.class]),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) data13, strlen(data13),0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *)aa, 2,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end, sizeof(end),0xFFFF); play[7]=0x33; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); break;//其他垃圾 default: break; } xSemaphoreGive(motor2Handle); num++; if(num>99)num=0; osDelay(2000); } xSemaphoreGive(rxlubancatHandle); if(osSemaphoreWait(manzaiSignalHandle, 0) == osOK) { if(pingmu_tx.manzai==1 && uart2_rx.manzaijianche_en==1){ //HAL_UART_Transmit(&huart6, (uint8_t *) manzaidata, 20,0xFFFF),pingmu_tx.manzai=0; //HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); //HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); // pingmu_tx.manzai=0; //osDelay(200); osMutexWait(uart6MutexHandle, osWaitForever); HAL_UART_Transmit(&huart6, manzaidata, sizeof(manzaidata), HAL_MAX_DELAY); HAL_UART_Transmit(&huart6, play, sizeof(play), HAL_MAX_DELAY); HAL_UART_Transmit(&huart6, end2, sizeof(end2), HAL_MAX_DELAY); osMutexRelease(uart6MutexHandle); pingmu_tx.manzai=0; osDelay(200); } } } } // ========== 🎯 新增:电机控制任务 ========== // 功能:控制两个电机的PWM速度,与舵机控制分开 // 电机1:PA6 (TIM3_CH1) // 电机2:PA7 (TIM3_CH2) _Noreturn void motorControlTask(void const * argument) { uint32_t tickCounter = 0; // 延迟启动 osDelay(1000); for(;;) { // 电机现在由超声波任务自动控制,这里只做周期性检查 if(tickCounter % 50 == 0) { // 可以在这里添加电机状态检查逻辑 } tickCounter++; osDelay(100); } } // ========== 🎯 新增:超声波测距函数 ========== // 简化版本,避免任务阻塞,返回距离值(cm*10) int32_t measureDistanceInt(GPIO_TypeDef* trig_port, uint16_t trig_pin, GPIO_TypeDef* echo_port, uint16_t echo_pin) { volatile uint32_t count = 0; volatile uint32_t time_count = 0; // 1. 确保Trig引脚为低电平 HAL_GPIO_WritePin(trig_port, trig_pin, GPIO_PIN_RESET); // 短暂延时 for(volatile int i = 0; i < 1000; i++) __NOP(); // 2. 发送10μs触发脉冲 HAL_GPIO_WritePin(trig_port, trig_pin, GPIO_PIN_SET); // 10μs延时 @168MHz for(volatile int i = 0; i < 1680; i++) __NOP(); HAL_GPIO_WritePin(trig_port, trig_pin, GPIO_PIN_RESET); // 3. 等待Echo上升沿,超时保护 // count = 0; while(HAL_GPIO_ReadPin(echo_port, echo_pin) == GPIO_PIN_RESET) { count++; if(count > 300000) { return -1; // 等待上升沿超时 } } // 4. 测量Echo高电平持续时间 time_count = 0; while(HAL_GPIO_ReadPin(echo_port, echo_pin) == GPIO_PIN_SET) { time_count++; if(time_count > 500000) { return -2; // 高电平持续过长 } } // 5. 计算距离 int32_t distance_x10 = (time_count * 50) / 1000; // 6. 范围检查:1-100cm if(distance_x10 < 10 || distance_x10 > 1000) { return -3; // 超出合理范围 } return distance_x10; } // ========== 🎯 新增:超声波测距任务 ========== // 真实测距版本,控制电机运行,与舵机同步,不使用USART1发送 _Noreturn void ultrasonicTask(void const * argument) { uint32_t counter = 0; int32_t distance1, distance2; for(;;) { // 测量超声波模块1 (PB2->PD8) distance1 = measureDistanceInt(GPIOB, GPIO_PIN_2, GPIOD, GPIO_PIN_8); // 间隔300ms避免干扰 osDelay(300); // 测量超声波模块2 (PB3->PD9) distance2 = measureDistanceInt(GPIOB, GPIO_PIN_3, GPIOD, GPIO_PIN_9); // ========== 🎯 电机控制逻辑 - 与舵机同步 + 启动停止延时500ms ========== uint32_t currentTime = HAL_GetTick(); // ========== 电机1控制逻辑 ========== if(distance1 > 100 && servoState == SERVO_IDLE) { // distance1是cm*10,所以100表示10cm // 满足启动条件 motor1_stopConditionActive = 0; // 清除停止条件 motor1_stopConditionStartTime = 0; if(motor1_running == 0) { // 电机未运行,需要启动(延时500ms) if(motor1_startConditionActive == 0) { // 刚开始满足启动条件,记录时间 motor1_startConditionActive = 1; motor1_startConditionStartTime = currentTime; } else { // 已经在启动条件中,检查是否已经持续500ms if((currentTime - motor1_startConditionStartTime) >= 500) { // 启动条件持续500ms,真正启动电机 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 6000); // PA6, 30%速度 motor1_running = 1; motor1_startConditionActive = 0; } } } else { // 电机已运行,继续运行 motor1_startConditionActive = 0; // 清除启动条件 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 6000); // PA6, 30%速度 } } else { // 满足停止条件 motor1_startConditionActive = 0; // 清除启动条件 motor1_startConditionStartTime = 0; if(motor1_running == 1) { // 电机正在运行,需要停止(延时500ms) if(motor1_stopConditionActive == 0) { // 刚开始满足停止条件,记录时间 motor1_stopConditionActive = 1; motor1_stopConditionStartTime = currentTime; } else { // 已经在停止条件中,检查是否已经持续500ms if((currentTime - motor1_stopConditionStartTime) >= 500) { // 停止条件持续500ms,真正停止电机 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); // 停止 motor1_running = 0; motor1_stopConditionActive = 0; } } } else { // 电机已停止,保持停止状态 motor1_stopConditionActive = 0; // 清除停止条件 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); // 确保停止 } } // ========== 电机2控制逻辑 ========== if(distance2 > 100 && servoState == SERVO_IDLE) { // distance2是cm*10,所以100表示10cm // 满足启动条件 motor2_stopConditionActive = 0; // 清除停止条件 motor2_stopConditionStartTime = 0; if(motor2_running == 0) { // 电机未运行,需要启动(延时500ms) if(motor2_startConditionActive == 0) { // 刚开始满足启动条件,记录时间 motor2_startConditionActive = 1; motor2_startConditionStartTime = currentTime; } else { // 已经在启动条件中,检查是否已经持续500ms if((currentTime - motor2_startConditionStartTime) >= 500) { // 启动条件持续500ms,真正启动电机 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 6000); // PA7, 30%速度 motor2_running = 1; motor2_startConditionActive = 0; } } } else { // 电机已运行,继续运行 motor2_startConditionActive = 0; // 清除启动条件 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 6000); // PA7, 30%速度 } } else { // 满足停止条件 motor2_startConditionActive = 0; // 清除启动条件 motor2_startConditionStartTime = 0; if(motor2_running == 1) { // 电机正在运行,需要停止(延时500ms) if(motor2_stopConditionActive == 0) { // 刚开始满足停止条件,记录时间 motor2_stopConditionActive = 1; motor2_stopConditionStartTime = currentTime; } else { // 已经在停止条件中,检查是否已经持续500ms if((currentTime - motor2_stopConditionStartTime) >= 500) { // 停止条件持续500ms,真正停止电机 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // 停止 motor2_running = 0; motor2_stopConditionActive = 0; } } } else { // 电机已停止,保持停止状态 motor2_stopConditionActive = 0; // 清除停止条件 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // 确保停止 } } counter++; osDelay(1200); // 每1.5秒测量一次 } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ // UNUSED(huart); /* NOTE: This function Should not be modified, when the callback is needed, the HAL_UART_TxCpltCallback could be implemented in the user file */ BaseType_t xHigherPriorityTaskWoken = pdFALSE; if(huart->Instance == USART6) { // 修复1:使用更可靠的帧头检测 if(uart2_rx.num == 0 && uart2_rx.datarx != 0x70) { // 帧头数据直接丢弃 HAL_UART_Receive_IT(&huart6, (uint8_t*)&uart2_rx.datarx, 1); return; } // 修复2:正确存储数据 if(uart2_rx.num < sizeof(uart2_rx.data)) { uart2_rx.data[uart2_rx.num] = uart2_rx.datarx; uart2_rx.num++; } // 修复3:完整帧检测 if(uart2_rx.num >= 3) { if(uart2_rx.data[2] == 0x71) { // 帧尾检测 uart2_rx.ok = 1; xSemaphoreGiveFromISR(rxpingmuHandle, &xHigherPriorityTaskWoken); } uart2_rx.num = 0; // 重置计数器 } HAL_UART_Receive_IT(&huart6, (uint8_t*)&uart2_rx.datarx, 1); } if(huart ->Instance == USART1){ HAL_GPIO_TogglePin(led1_GPIO_Port,led1_Pin); if(uart3_rx.datarx=='@') uart3_rx.num=0; uart3_rx.data[uart3_rx.num]=uart3_rx.datarx; uart3_rx.num++; if(uart3_rx.num>=28){ uart3_rx.num=0; if(uart3_rx.data[27]==']'){ uart3_rx.ok=1; xSemaphoreGiveFromISR(rxlubancatHandle, &xHigherPriorityTaskWoken); } uart3_rx.num = 0; // 重置缓冲区 } HAL_UART_Receive_IT(&huart1, (uint8_t *)&uart3_rx.datarx, 1); } portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /* USER CODE END Application */ 这个程序上电后舵机不工作是为什么,该怎么解决
最新发布
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值