/* 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 */
这个程序上电后舵机不工作是为什么,该怎么解决
最新发布