活动介绍

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) { /* Check the UART handle allocation */ if (huart == NULL) { return HAL_ERROR; } /* Check the parameters */ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { /* The hardware flow control is available only for USART1, USART2, USART3 and USART6. Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5. */ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); } else { assert_param(IS_UART_INSTANCE(huart->Instance)); } assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); if (huart->gState == HAL_UART_STATE_RESET) { /* Allocate lock resource and initialize it */ huart->Lock = HAL_UNLOCKED; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) UART_InitCallbacksToDefault(huart); if (huart->MspInitCallback == NULL) { huart->MspInitCallback = HAL_UART_MspInit; } /* Init the low level hardware */ huart->MspInitCallback(huart); #else /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ } huart->gState = HAL_UART_STATE_BUSY; /* Disable the peripheral */ __HAL_UART_DISABLE(huart); /* Set the UART Communication parameters */ UART_SetConfig(huart); /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); /* Enable the peripheral */ __HAL_UART_ENABLE(huart); /* Initialize the UART state */ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; return HAL_OK; }

时间: 2023-12-06 15:42:48 浏览: 198
这是HAL库中初始化UART外设的函数。它会首先检查传入的参数是否合法,然后根据传入的参数设置UART通信参数,最后使能UART外设并将状态设置为READY。在这个函数中还会调用HAL_UART_MspInit()或者用户自定义的MspInitCallback()函数来初始化外设的引脚和时钟等低级硬件。
相关问题

这个函数怎么使用HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) { /* Check the UART handle allocation */ if (huart == NULL) { return HAL_ERROR; } /* Check the parameters */ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { /* The hardware flow control is available only for USART1, USART2, USART3 and USART6. Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5. */ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); } else { assert_param(IS_UART_INSTANCE(huart->Instance)); } assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); if (huart->gState == HAL_UART_STATE_RESET) { /* Allocate lock resource and initialize it */ huart->Lock = HAL_UNLOCKED; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) UART_InitCallbacksToDefault(huart); if (huart->MspInitCallback == NULL) { huart->MspInitCallback = HAL_UART_MspInit; } /* Init the low level hardware */ huart->MspInitCallback(huart); #else /* Init the low level hardware : GPIO, CLOCK */ HAL_UART_MspInit(huart); #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ } huart->gState = HAL_UART_STATE_BUSY; /* Disable the peripheral */ __HAL_UART_DISABLE(huart); /* Set the UART Communication parameters */ UART_SetConfig(huart); /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); /* Enable the peripheral */ __HAL_UART_ENABLE(huart); /* Initialize the UART state */ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; return HAL_OK; }

这个函数是HAL库(STM32的驱动库)中的UART初始化函数,用于初始化指定的UART外设。它的参数是一个UART_HandleTypeDef类型的指针,其中包含了UART的初始化参数和外设的实例。函数执行过程中会进行一系列的参数检查,包括检查参数是否为空、硬件流控制是否可用、数据位长度是否合法等等。如果UART的gState状态为HAL_UART_STATE_RESET,那么它会先初始化底层硬件资源(包括GPIO和时钟),否则会直接进行配置和使能。最后,函数会将UART的状态设置为HAL_UART_STATE_READY,表示初始化完成。

怎么使用这个函数初始化串口3HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef huart) { / Check the UART handle allocation / if (huart == NULL) { return HAL_ERROR; } / Check the parameters / if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { / The hardware flow control is available only for USART1, USART2, USART3 and USART6. Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5. / assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); } else { assert_param(IS_UART_INSTANCE(huart->Instance)); } assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); if (huart->gState == HAL_UART_STATE_RESET) { / Allocate lock resource and initialize it / huart->Lock = HAL_UNLOCKED; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) UART_InitCallbacksToDefault(huart); if (huart->MspInitCallback == NULL) { huart->MspInitCallback = HAL_UART_MspInit; } / Init the low level hardware / huart->MspInitCallback(huart); #else / Init the low level hardware : GPIO, CLOCK / HAL_UART_MspInit(huart); #endif / (USE_HAL_UART_REGISTER_CALLBACKS) / } huart->gState = HAL_UART_STATE_BUSY; / Disable the peripheral / __HAL_UART_DISABLE(huart); / Set the UART Communication parameters / UART_SetConfig(huart); / In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register./ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); / Enable the peripheral / __HAL_UART_ENABLE(huart); / Initialize the UART state */ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; return HAL_OK; }

这个函数是用来初始化UART串口的,具体的使用方法如下: 1. 首先需要定义一个`UART_HandleTypeDef`类型的结构体变量`huart`,并对其中的各个成员变量进行配置,例如: ``` UART_HandleTypeDef huart; huart.Instance = USART3; huart.Init.BaudRate = 115200; huart.Init.WordLength = UART_WORDLENGTH_8B; huart.Init.StopBits = UART_STOPBITS_1; huart.Init.Parity = UART_PARITY_NONE; huart.Init.Mode = UART_MODE_TX_RX; huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart.Init.OverSampling = UART_OVERSAMPLING_16; ``` 2. 调用`HAL_UART_Init()`函数进行初始化,将上述结构体变量传入该函数即可。 ``` HAL_StatusTypeDef result = HAL_UART_Init(&huart); if (result != HAL_OK) { // 初始化失败,进行错误处理 } else { // 初始化成功,进行后续操作 } ``` 在该函数内部,会先进行一些参数检查,然后根据参数配置寄存器,最终完成UART串口的初始化。
阅读全文

相关推荐

/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2025 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 "stdio.h" #include "usart.h" int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY); return ch; } /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ osThreadId defaultTaskHandle; osThreadId LED_TaskHandle; osThreadId CMDprocess_TaskHandle; osSemaphoreId BinarySemHandle; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ void StartDefaultTask(void const * argument); void LEDTask(void const * argument); void CMDprocessTask(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 */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* Create the semaphores(s) */ /* definition and creation of BinarySem */ osSemaphoreDef(BinarySem); BinarySemHandle = osSemaphoreCreate(osSemaphore(BinarySem), 1); /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* 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); /* definition and creation of LED_Task */ osThreadDef(LED_Task, LEDTask, osPriorityNormal, 0, 128); LED_TaskHandle = osThreadCreate(osThread(LED_Task), NULL); /* definition and creation of CMDprocess_Task */ osThreadDef(CMDprocess_Task, CMDprocessTask, osPriorityNormal, 0, 128); CMDprocess_TaskHandle = osThreadCreate(osThread(CMDprocess_Task), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* 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 */ for(;;) { osDelay(1); } /* USER CODE END StartDefaultTask */ } /* USER CODE BEGIN Header_LEDTask */ /** * @brief Function implementing the LED_Task thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_LEDTask */ void LEDTask(void const * argument) { /* USER CODE BEGIN LEDTask */ /* Infinite loop */ for(;;) { HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0); osDelay(500); } /* USER CODE END LEDTask */ } /* USER CODE BEGIN Header_CMDprocessTask */ /** * @brief Function implementing the CMDprocess_Task thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_CMDprocessTask */ void CMDprocessTask(void const * argument) { /* USER CODE BEGIN CMDprocessTask */ BaseType_t err = pdFALSE; /* Infinite loop */ for(;;) { if(BinarySemHandle !=0) { err = xSemaphoreTake(BinarySemHandle,portMAX_DELAY); if(err == pdPASS) { printf("CMDprocessTask take the binary Semphore!\r\n"); printf("received CMD is:"); for (int i =0;i<8;i++) printf ("%c",RxBuff[i]); printf ("\n"); if(strncmp((char *)Rxbuff,"LED2on",6) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1,GPIO_PIN_RESET); else if(strncmp((char *)RxBuff,"LED2off",7) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"LED3on",6) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_RESET); else if(strncmp((char *)RxBuff,"LED3off",7) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"BUZZon",6) == 0) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"BUZZoff",7) == 0) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); else printf("invalid CMD,piease input LED2on LED2off BUFFon or BUFFoff\r\n"); } else vTaskDelay(10); } osDelay(1); } /* USER CODE END CMDprocessTask */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { RxBuff[Rx_Count++]=RxByte; if((RxByte==0x0A)&&(BinarySemHandle!=0)) { xSemaphoreGiveFromISR(BinarySemHandle,NULL); print("Semaphore Give FromISR succesed!\r\n"); Rx_Count=0; } if(Rx_Count > 8) { print("Wrong CMD,Please Check...!\r\n"); memset(RxBuff,0,sizeof(RxBuff)); Rx_Count=0; } while(HAL_UART_Receive_IT(&huart1,&RxByte, 1)==HAL_OK); } /* USER CODE END Application */ 中报错/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2025 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 "stdio.h" #include "usart.h" int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY); return ch; } /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ osThreadId defaultTaskHandle; osThreadId LED_TaskHandle; osThreadId CMDprocess_TaskHandle; osSemaphoreId BinarySemHandle; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ void StartDefaultTask(void const * argument); void LEDTask(void const * argument); void CMDprocessTask(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 */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* Create the semaphores(s) */ /* definition and creation of BinarySem */ osSemaphoreDef(BinarySem); BinarySemHandle = osSemaphoreCreate(osSemaphore(BinarySem), 1); /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* 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); /* definition and creation of LED_Task */ osThreadDef(LED_Task, LEDTask, osPriorityNormal, 0, 128); LED_TaskHandle = osThreadCreate(osThread(LED_Task), NULL); /* definition and creation of CMDprocess_Task */ osThreadDef(CMDprocess_Task, CMDprocessTask, osPriorityNormal, 0, 128); CMDprocess_TaskHandle = osThreadCreate(osThread(CMDprocess_Task), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* 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 */ for(;;) { osDelay(1); } /* USER CODE END StartDefaultTask */ } /* USER CODE BEGIN Header_LEDTask */ /** * @brief Function implementing the LED_Task thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_LEDTask */ void LEDTask(void const * argument) { /* USER CODE BEGIN LEDTask */ /* Infinite loop */ for(;;) { HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0); osDelay(500); } /* USER CODE END LEDTask */ } /* USER CODE BEGIN Header_CMDprocessTask */ /** * @brief Function implementing the CMDprocess_Task thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_CMDprocessTask */ void CMDprocessTask(void const * argument) { /* USER CODE BEGIN CMDprocessTask */ BaseType_t err = pdFALSE; /* Infinite loop */ for(;;) { if(BinarySemHandle !=0) { err = xSemaphoreTake(BinarySemHandle,portMAX_DELAY); if(err == pdPASS) { printf("CMDprocessTask take the binary Semphore!\r\n"); printf("received CMD is:"); for (int i =0;i<8;i++) printf ("%c",RxBuff[i]); printf ("\n"); if(strncmp((char *)Rxbuff,"LED2on",6) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1,GPIO_PIN_RESET); else if(strncmp((char *)RxBuff,"LED2off",7) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"LED3on",6) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_RESET); else if(strncmp((char *)RxBuff,"LED3off",7) == 0) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"BUZZon",6) == 0) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); else if(strncmp((char *)RxBuff,"BUZZoff",7) == 0) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); else printf("invalid CMD,piease input LED2on LED2off BUFFon or BUFFoff\r\n"); } else vTaskDelay(10); } osDelay(1); } /* USER CODE END CMDprocessTask */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { RxBuff[Rx_Count++]=RxByte; if((RxByte==0x0A)&&(BinarySemHandle!=0)) { xSemaphoreGiveFromISR(BinarySemHandle,NULL); print("Semaphore Give FromISR succesed!\r\n"); Rx_Count=0; } if(Rx_Count > 8) { print("Wrong CMD,Please Check...!\r\n"); memset(RxBuff,0,sizeof(RxBuff)); Rx_Count=0; } while(HAL_UART_Receive_IT(&huart1,&RxByte, 1)==HAL_OK); } /* USER CODE END Application */

/* 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是否正在运行 volatile uint8_t servo_class_to_act = 0; volatile uint8_t is_playing_manzai = 0; // 满载播报进行中标志 volatile uint32_t manzai_play_start = 0; // 满载播报开始时间 volatile uint32_t garbage_delay_start = 0; // 垃圾识别延迟开始时间 volatile uint8_t garbage_to_play = 0; // 待播放的垃圾类别 /* 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 systemMonitorTask(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, 6, 0); HAL_NVIC_EnableIRQ(USART6_IRQn); TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* 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(systemMonitorTask, systemMonitorTask, osPriorityBelowNormal, 0, 128); osThreadCreate(osThread(systemMonitorTask), 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 */ } _Noreturn void systemMonitorTask(void const * argument) { uint32_t last_heartbeat = HAL_GetTick(); const uint32_t WATCHDOG_TIMEOUT = 30000; // 30秒超时 for(;;) { // 检查任务堆栈使用情况 UBaseType_t uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); if(uxHighWaterMark < 20) { NVIC_SystemReset(); // 堆栈溢出复位 } // 30秒无心跳复位 if(HAL_GetTick() - last_heartbeat > WATCHDOG_TIMEOUT) { NVIC_SystemReset(); } // 更新心跳时间 last_heartbeat = HAL_GetTick(); osDelay(1000); } } /* 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 */ uint32_t last_activity_time = HAL_GetTick(); uart2_rx.manzaijianche_en = 1; for(;;) { //xSemaphoreTake(rxpingmuHandle,portMAX_DELAY); if(xSemaphoreTake(rxpingmuHandle, 100) == pdTRUE) { 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; } last_activity_time = HAL_GetTick(); } if(HAL_GetTick() - last_activity_time > 10000) { // 5秒无活动时软复位 NVIC_SystemReset(); } /* USER CODE END StartDefaultTask */ osDelay(100); } } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void PlayAudio(uint8_t audio_num) { char cmd[] = {0x70,0x6C,0x61,0x79,0x20,0x30,0x2C,0x30,0x2C,0x30, 0xFF,0xFF,0xFF}; cmd[7] = '0' + audio_num; osMutexWait(uart6MutexHandle, osWaitForever); HAL_UART_Transmit(&huart6, (uint8_t *)cmd, sizeof(cmd), HAL_MAX_DELAY); osMutexRelease(uart6MutexHandle); } void PlayGarbageAudio(uint8_t garbage_class) { uint8_t audio_num = 0; switch (garbage_class) { case 0: case 1: case 3: audio_num = 2; break; // 可回收 case 2: case 5: audio_num = 1; break; // 厨余 case 7: case 8: audio_num = 0; break; // 有害 default: audio_num = 3; break; // 其他 } PlayAudio(audio_num); } // 保留现有的舵机控制任务 - 增加状态跟踪 _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); //uint8_t current_class = uart3_rx.class; if(is_playing_manzai) { osDelay(100); continue; // 跳过当前动作 } // 🎯 设置舵机工作状态 servoState = SERVO_WORKING; //servoWorkStartTime = HAL_GetTick(); uint8_t current_class = servo_class_to_act; switch (current_class) { //有害垃圾 case 0: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; //可回收垃圾 case 1: case 8: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,1570); break; //厨余垃圾 case 2: case 5: case 6: case 7: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,2000); osDelay(1000); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; //其它垃圾 case 3: case 4: __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; } osSemaphoreGive(motor2Handle); osDelay(10); } // 保留现有的满载检测任务 _Noreturn void manzaiTask(void const * argument) { for(;;) { osDelay(100); if(HAL_GPIO_ReadPin(load1_GPIO_Port,load1_Pin)==0 || HAL_GPIO_ReadPin(load2_GPIO_Port,load2_Pin)==0 || HAL_GPIO_ReadPin(load3_GPIO_Port,load3_Pin)==0 || HAL_GPIO_ReadPin(load4_GPIO_Port,load4_Pin)==0) { pingmu_tx.manzai=1; xSemaphoreGive(rxlubancatHandle); } } } // 保留现有的串口屏通讯任务 _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(;;) { xSemaphoreTake(rxlubancatHandle,portMAX_DELAY); if(uart3_rx.ok==1 && 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(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; } servo_class_to_act = uart3_rx.class; xSemaphoreGive(motor2Handle); num++; if(num>99)num=0; osDelay(2000); } if(pingmu_tx.manzai==1 && uart2_rx.manzaijianche_en==1){ HAL_UART_Transmit(&huart6, (uint8_t *) manzaidata, 20,0xFFFF),pingmu_tx.manzai=0; play[7]=0x34; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); osDelay(2000); } } } // ========== 🎯 新增:电机控制任务 ========== // 功能:控制两个电机的PWM速度,与舵机控制分开 // 电机1:PA6 (TIM3_CH1) // 电机2:PA7 (TIM3_CH2) _Noreturn void motorControlTask(void const * argument) { uint32_t tickCounter = 0; // 延迟启动 osDelay(1000); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // PA6 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // PA7 for(;;) { // 电机现在由超声波任务自动控制,这里只做周期性检查 if(tickCounter % 50 == 0) { // 可以在这里添加电机状态检查逻辑 } tickCounter++; osDelay(200); } } // ========== 🎯 新增:超声波测距函数 ========== // 简化版本,避免任务阻塞,返回距离值(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; distance_x10 = distance_x10 * 0.95; // 15%校准系数 // 6. 范围检查:1-100cm if(distance_x10 < 5 || distance_x10 > 1000) { return -4; // 超出合理范围 } 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(servoState == SERVO_IDLE){ if(distance1 > 100) { // distance1是cm*10,所以100表示10cm __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 6000); // PA7, 30%速度 } else { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); // 停止 } // ========== 电机2控制逻辑 ========== if(distance2 > 100) { // distance2是cm*10,所以100表示10cm __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 6000); // PA6, 30%速度 (修改:从TIM4_CH2改为TIM3_CH1) } else { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // 停止 (修改:从TIM4_CH2改为TIM3_CH1) } }else{ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); } char msg[60]; sprintf(msg, "D: %ld.%ld, %ld.%ld cm | M1:%s M2:%s\r\n", distance1 > 0 ? distance1/10 : -1, distance1 > 0 ? distance1%10 : 0, distance2 > 0 ? distance2/10 : -1, distance2 > 0 ? distance2%10 : 0, (distance1 > 100) ? "ON" : "OFF", (distance2 > 100) ? "ON" : "OFF"); HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 1000); 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) { // 更健壮的帧检测 static uint8_t frame_buffer[32]; static uint8_t frame_index = 0; // 存储接收到的字节 frame_buffer[frame_index] = uart2_rx.datarx; frame_index = (frame_index + 1) % sizeof(frame_buffer); // 检测结束符 0xFF 0xFF 0xFF if(frame_index >= 3 && frame_buffer[frame_index-3] == 0xFF && frame_buffer[frame_index-2] == 0xFF && frame_buffer[frame_index-1] == 0xFF) { // 复制有效数据 memcpy(uart2_rx.data, frame_buffer, frame_index-3); uart2_rx.num = frame_index-3; uart2_rx.ok = 1; frame_index = 0; xSemaphoreGiveFromISR(rxpingmuHandle, &xHigherPriorityTaskWoken); } 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 */ /* 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是否正在运行 volatile uint8_t servo_class_to_act = 0; volatile uint8_t is_playing_manzai = 0; // 满载播报进行中标志 volatile uint32_t manzai_play_start = 0; // 满载播报开始时间 volatile uint32_t garbage_delay_start = 0; // 垃圾识别延迟开始时间 volatile uint8_t garbage_to_play = 0; // 待播放的垃圾类别 /* 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 systemMonitorTask(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, 6, 0); HAL_NVIC_EnableIRQ(USART6_IRQn); TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); /* 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(systemMonitorTask, systemMonitorTask, osPriorityBelowNormal, 0, 128); osThreadCreate(osThread(systemMonitorTask), 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 */ } _Noreturn void systemMonitorTask(void const * argument) { uint32_t last_heartbeat = HAL_GetTick(); const uint32_t WATCHDOG_TIMEOUT = 30000; // 30秒超时 for(;;) { // 检查任务堆栈使用情况 UBaseType_t uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); if(uxHighWaterMark < 20) { NVIC_SystemReset(); // 堆栈溢出复位 } // 30秒无心跳复位 if(HAL_GetTick() - last_heartbeat > WATCHDOG_TIMEOUT) { NVIC_SystemReset(); } // 更新心跳时间 last_heartbeat = HAL_GetTick(); osDelay(1000); } } /* 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 */ uint32_t last_activity_time = HAL_GetTick(); uart2_rx.manzaijianche_en = 1; for(;;) { //xSemaphoreTake(rxpingmuHandle,portMAX_DELAY); if(xSemaphoreTake(rxpingmuHandle, 100) == pdTRUE) { 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; } last_activity_time = HAL_GetTick(); } if(HAL_GetTick() - last_activity_time > 10000) { // 5秒无活动时软复位 NVIC_SystemReset(); } /* USER CODE END StartDefaultTask */ osDelay(100); } } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ void PlayAudio(uint8_t audio_num) { char cmd[] = {0x70,0x6C,0x61,0x79,0x20,0x30,0x2C,0x30,0x2C,0x30, 0xFF,0xFF,0xFF}; cmd[7] = '0' + audio_num; osMutexWait(uart6MutexHandle, osWaitForever); HAL_UART_Transmit(&huart6, (uint8_t *)cmd, sizeof(cmd), HAL_MAX_DELAY); osMutexRelease(uart6MutexHandle); } void PlayGarbageAudio(uint8_t garbage_class) { uint8_t audio_num = 0; switch (garbage_class) { case 0: case 1: case 3: audio_num = 2; break; // 可回收 case 2: case 5: audio_num = 1; break; // 厨余 case 7: case 8: audio_num = 0; break; // 有害 default: audio_num = 3; break; // 其他 } PlayAudio(audio_num); } // 保留现有的舵机控制任务 - 增加状态跟踪 _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); //uint8_t current_class = uart3_rx.class; if(is_playing_manzai) { osDelay(100); continue; // 跳过当前动作 } // 🎯 设置舵机工作状态 servoState = SERVO_WORKING; //servoWorkStartTime = HAL_GetTick(); uint8_t current_class = servo_class_to_act; switch (current_class) { //有害垃圾 case 0: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; //可回收垃圾 case 1: case 8: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,1300); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,1570); break; //厨余垃圾 case 2: case 5: case 6: case 7: __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,2000); osDelay(1000); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,2430); break; //其它垃圾 case 3: case 4: __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; } osSemaphoreGive(motor2Handle); osDelay(10); } // 保留现有的满载检测任务 _Noreturn void manzaiTask(void const * argument) { for(;;) { osDelay(100); if(HAL_GPIO_ReadPin(load1_GPIO_Port,load1_Pin)==0 || HAL_GPIO_ReadPin(load2_GPIO_Port,load2_Pin)==0 || HAL_GPIO_ReadPin(load3_GPIO_Port,load3_Pin)==0 || HAL_GPIO_ReadPin(load4_GPIO_Port,load4_Pin)==0) { pingmu_tx.manzai=1; xSemaphoreGive(rxlubancatHandle); } } } // 保留现有的串口屏通讯任务 _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(;;) { xSemaphoreTake(rxlubancatHandle,portMAX_DELAY); if(uart3_rx.ok==1 && 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(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; } servo_class_to_act = uart3_rx.class; xSemaphoreGive(motor2Handle); num++; if(num>99)num=0; osDelay(2000); } if(pingmu_tx.manzai==1 && uart2_rx.manzaijianche_en==1){ HAL_UART_Transmit(&huart6, (uint8_t *) manzaidata, 20,0xFFFF),pingmu_tx.manzai=0; play[7]=0x34; HAL_UART_Transmit(&huart6, (uint8_t *) play, 10,0xFFFF); HAL_UART_Transmit(&huart6, (uint8_t *) end2, sizeof(end2),0xFFFF); osDelay(2000); } } } // ========== 🎯 新增:电机控制任务 ========== // 功能:控制两个电机的PWM速度,与舵机控制分开 // 电机1:PA6 (TIM3_CH1) // 电机2:PA7 (TIM3_CH2) _Noreturn void motorControlTask(void const * argument) { uint32_t tickCounter = 0; // 延迟启动 osDelay(1000); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // PA6 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // PA7 for(;;) { // 电机现在由超声波任务自动控制,这里只做周期性检查 if(tickCounter % 50 == 0) { // 可以在这里添加电机状态检查逻辑 } tickCounter++; osDelay(200); } } // ========== 🎯 新增:超声波测距函数 ========== // 简化版本,避免任务阻塞,返回距离值(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; distance_x10 = distance_x10 * 0.95; // 15%校准系数 // 6. 范围检查:1-100cm if(distance_x10 < 5 || distance_x10 > 1000) { return -4; // 超出合理范围 } 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(servoState == SERVO_IDLE){ if(distance1 > 100) { // distance1是cm*10,所以100表示10cm __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 6000); // PA7, 30%速度 } else { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); // 停止 } // ========== 电机2控制逻辑 ========== if(distance2 > 100) { // distance2是cm*10,所以100表示10cm __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 6000); // PA6, 30%速度 (修改:从TIM4_CH2改为TIM3_CH1) } else { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // 停止 (修改:从TIM4_CH2改为TIM3_CH1) } }else{ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); } char msg[60]; sprintf(msg, "D: %ld.%ld, %ld.%ld cm | M1:%s M2:%s\r\n", distance1 > 0 ? distance1/10 : -1, distance1 > 0 ? distance1%10 : 0, distance2 > 0 ? distance2/10 : -1, distance2 > 0 ? distance2%10 : 0, (distance1 > 100) ? "ON" : "OFF", (distance2 > 100) ? "ON" : "OFF"); HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 1000); 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) { // 更健壮的帧检测 static uint8_t frame_buffer[32]; static uint8_t frame_index = 0; // 存储接收到的字节 frame_buffer[frame_index] = uart2_rx.datarx; frame_index = (frame_index + 1) % sizeof(frame_buffer); // 检测结束符 0xFF 0xFF 0xFF if(frame_index >= 3 && frame_buffer[frame_index-3] == 0xFF && frame_buffer[frame_index-2] == 0xFF && frame_buffer[frame_index-1] == 0xFF) { // 复制有效数据 memcpy(uart2_rx.data, frame_buffer, frame_index-3); uart2_rx.num = frame_index-3; uart2_rx.ok = 1; frame_index = 0; xSemaphoreGiveFromISR(rxpingmuHandle, &xHigherPriorityTaskWoken); } 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 */ 这个程序中为什么超声波控制启停无效?该怎么解决

docx
内容概要:本文以电商仓储物流机器人为案例,深度解析机器人开发全流程,涵盖ROS系统搭建、SLAM建图、路径规划、机械臂控制、多机调度等核心技术。首先介绍了分层模块化架构和核心硬件选型,如主控制器、激光雷达、深度相机、驱动底盘和协作机械臂。接着详细讲述了ROS系统开发的核心实战,包括环境感知与SLAM建图、自主导航与动态避障等技术,提供了代码示例和技术关键点。然后探讨了机械臂抓取任务开发,涉及视觉定位系统、运动规划与力控制。随后介绍了多机器人集群调度系统的任务分配模型和通信架构设计。还讨论了安全与可靠性保障措施,包括硬件级安全设计和软件容错机制。最后总结了实战问题与解决方案,以及性能优化成果,并推荐了四大核心代码库和仿真训练平台。 适合人群:对机器人开发感兴趣的研发人员,尤其是有一定编程基础并希望深入了解仓储机器人开发的技术人员。 使用场景及目标:①学习仓储机器人从系统集成到底层硬件部署的全流程;②掌握ROS系统开发的核心技术,如SLAM建图、路径规划、机械臂控制等;③理解多机器人集群调度和安全可靠性设计;④解决实际开发中的常见问题并优化系统性能。 阅读建议:本文内容详实,涵盖了从硬件选型到软件开发的各个方面,建议读者结合实际项目需求,逐步深入学习,并通过实践操作加深理解。同时,利用提供的开源项目和仿真训练平台进行实验和验证。
zip
资源下载链接为: https://pan.quark.cn/s/b7174785e9d3 在西安交通大学的模拟电子技术课程中,Tina 仿真软件得到了广泛应用。Tina 软件由欧洲 DesignSoft Kft. 公司研发,是一款重要的现代化 EDA 软件,可用于模拟及数字电路的仿真分析,在全球四十多个国家流行,拥有二十余种语言版本,包括中文版,内置约两万多个分立或集成电路元器件。 在模拟电路分析方面,Tina 功能强大,具备直流分析、瞬态分析、正弦稳态分析、傅立叶分析、温度扫描、参数扫描、最坏情况及蒙特卡罗统计等常规仿真功能。它还能依据输出电量指标对电路元件参数进行优化计算,具有符号分析功能,可给出时域过渡过程表达式或频域传递函数表达式,并且支持 RF 仿真分析,能绘制零、极点图、相量图、Nyquist 图等。 在数字电路分析方面,Tina 支持 VHDL 语言,拥有 BUS 总线及虚拟连线功能,使电路绘图界面更清晰简洁。该软件可执行电路的 DC、AC、瞬态、傅立叶、噪声等分析,并提供函数发生器、万用表、示波器、XY 记录仪和信号分析仪等虚拟仪器,方便学生进行电路测试与测量。 在西安交通大学,杨建国老师在模拟电子技术领域有着深厚造诣。他是博士生导师,研究方向主要为电子技术及其应用,在模拟电路和单片机应用方面教学经验丰富。杨建国老师著有 6 本相关著作,如《你好,放大器》《新概念模拟电路》等,这些著作受到了广大师生的欢迎,对模拟电子技术知识的传播和教学起到了积极的推动作用 ,为学生深入学习模拟电子技术提供了丰富的知识源泉,结合 Tina 仿真软件,能助力学生更好地理解和掌握模拟电子技术的相关知识与实践技能。

最新推荐

recommend-type

C# Socket通信源码:多连接支持与断线重连功能的物联网解决方案

内容概要:本文介绍了一套基于C#编写的Socket服务器与客户端通信源码,源自商业级物联网项目。这套代码实现了双Socket机制、多连接支持以及断线重连功能,适用于各类C#项目(如MVC、Winform、控制台、Webform)。它通过简单的静态类调用即可获取客户端传输的数据,并内置了接收和发送数据缓冲队列,确保数据传输的稳定性。此外,代码提供了数据读取接口,但不涉及具体的数据处理逻辑。文中详细展示了服务端和客户端的基本配置与使用方法,强调了在实际应用中需要注意的问题,如避免主线程执行耗时操作以防内存膨胀。 适合人群:具备基本C#编程能力的研发人员,尤其是对Socket通信有一定了解并希望快速集成相关功能到现有项目中的开发者。 使用场景及目标:① 需要在短时间内为C#项目增加稳定的Socket通信功能;② 实现多设备间的数据交换,特别是对于智能家居、工业传感器等物联网应用场景。 其他说明:虽然该代码能够满足大多数中小型项目的通信需求,但对于需要高性能、低延迟的金融级交易系统则不太合适。同时,代码并未采用异步技术,因此在面对海量连接时可能需要进一步优化。
recommend-type

STM32CubeIDE 1.10.1代码自动提示补全功能

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 STM32CubeIDE 1.10.1代码自动提示补全功能
recommend-type

专业定制变频器方案:高效节能,智能控制,满足多样化应用需求

内容概要:本文详细介绍了变频器在电气技术领域的应用及其工作原理,重点讨论了变频器的技术方案,包括基于电力电子器件的不同技术方案和控制策略。此外,还提供了变频器控制程序的代码分析,涵盖主程序、输入模块、输出模块和通信模块的关键组成部分,并附有一段简化的伪代码示例,帮助读者更好地理解变频器的内部机制和实际操作方法。 适合人群:从事电气工程、自动化控制及相关领域的技术人员和研究人员。 使用场景及目标:适用于希望深入了解变频器工作原理和技术实现的专业人士,旨在提高他们对变频器的理解和应用能力。 其他说明:随着电力电子技术和控制技术的发展,未来的变频器将更加智能化和高效化,文中提到的内容有助于读者跟上行业发展的步伐。
recommend-type

S7-1200 PLC SCL编写的MODBUS-RTU轮询程序,用于控制32路485设备

内容概要:本文详细介绍了使用西门子SCL语言为S7-1200 PLC编写的MODBUS-RTU轮询程序,该程序主要用于控制多达32台RS485接口的设备。文中不仅展示了主循环和子程序的具体实现方法,还强调了良好的代码注释对于提高程序可读性和易维护性的必要性。此外,针对可能发生的异常状况提供了相应的解决方案,确保系统稳定运行。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些需要利用PLC进行多设备管理的人群。 使用场景及目标:适用于需要通过MODBUS-RTU协议对多个远程IO站或其他兼容设备进行集中管理和监控的应用场合。目的是帮助读者掌握如何构建高效可靠的轮询控制系统,同时提供实用的技术指导。 其他说明:虽然文中给出了一些基本的代码框架和逻辑思路,但实际应用时还需依据具体情况做适当修改和完善。
recommend-type

【仓储机器人开发】基于ROS的自主导航与机械臂控制:全栈技术详解及实战优化

内容概要:本文以电商仓储物流机器人为案例,深度解析机器人开发全流程,涵盖ROS系统搭建、SLAM建图、路径规划、机械臂控制、多机调度等核心技术。首先介绍了分层模块化架构和核心硬件选型,如主控制器、激光雷达、深度相机、驱动底盘和协作机械臂。接着详细讲述了ROS系统开发的核心实战,包括环境感知与SLAM建图、自主导航与动态避障等技术,提供了代码示例和技术关键点。然后探讨了机械臂抓取任务开发,涉及视觉定位系统、运动规划与力控制。随后介绍了多机器人集群调度系统的任务分配模型和通信架构设计。还讨论了安全与可靠性保障措施,包括硬件级安全设计和软件容错机制。最后总结了实战问题与解决方案,以及性能优化成果,并推荐了四大核心代码库和仿真训练平台。 适合人群:对机器人开发感兴趣的研发人员,尤其是有一定编程基础并希望深入了解仓储机器人开发的技术人员。 使用场景及目标:①学习仓储机器人从系统集成到底层硬件部署的全流程;②掌握ROS系统开发的核心技术,如SLAM建图、路径规划、机械臂控制等;③理解多机器人集群调度和安全可靠性设计;④解决实际开发中的常见问题并优化系统性能。 阅读建议:本文内容详实,涵盖了从硬件选型到软件开发的各个方面,建议读者结合实际项目需求,逐步深入学习,并通过实践操作加深理解。同时,利用提供的开源项目和仿真训练平台进行实验和验证。
recommend-type

掌握XFireSpring整合技术:HELLOworld原代码使用教程

标题:“xfirespring整合使用原代码”中提到的“xfirespring”是指将XFire和Spring框架进行整合使用。XFire是一个基于SOAP的Web服务框架,而Spring是一个轻量级的Java/Java EE全功能栈的应用程序框架。在Web服务开发中,将XFire与Spring整合能够发挥两者的优势,例如Spring的依赖注入、事务管理等特性,与XFire的简洁的Web服务开发模型相结合。 描述:“xfirespring整合使用HELLOworld原代码”说明了在这个整合过程中实现了一个非常基本的Web服务示例,即“HELLOworld”。这通常意味着创建了一个能够返回"HELLO world"字符串作为响应的Web服务方法。这个简单的例子用来展示如何设置环境、编写服务类、定义Web服务接口以及部署和测试整合后的应用程序。 标签:“xfirespring”表明文档、代码示例或者讨论集中于XFire和Spring的整合技术。 文件列表中的“index.jsp”通常是一个Web应用程序的入口点,它可能用于提供一个用户界面,通过这个界面调用Web服务或者展示Web服务的调用结果。“WEB-INF”是Java Web应用中的一个特殊目录,它存放了应用服务器加载的Servlet类文件和相关的配置文件,例如web.xml。web.xml文件中定义了Web应用程序的配置信息,如Servlet映射、初始化参数、安全约束等。“META-INF”目录包含了元数据信息,这些信息通常由部署工具使用,用于描述应用的元数据,如manifest文件,它记录了归档文件中的包信息以及相关的依赖关系。 整合XFire和Spring框架,具体知识点可以分为以下几个部分: 1. XFire框架概述 XFire是一个开源的Web服务框架,它是基于SOAP协议的,提供了一种简化的方式来创建、部署和调用Web服务。XFire支持多种数据绑定,包括XML、JSON和Java数据对象等。开发人员可以使用注解或者基于XML的配置来定义服务接口和服务实现。 2. Spring框架概述 Spring是一个全面的企业应用开发框架,它提供了丰富的功能,包括但不限于依赖注入、面向切面编程(AOP)、数据访问/集成、消息传递、事务管理等。Spring的核心特性是依赖注入,通过依赖注入能够将应用程序的组件解耦合,从而提高应用程序的灵活性和可测试性。 3. XFire和Spring整合的目的 整合这两个框架的目的是为了利用各自的优势。XFire可以用来创建Web服务,而Spring可以管理这些Web服务的生命周期,提供企业级服务,如事务管理、安全性、数据访问等。整合后,开发者可以享受Spring的依赖注入、事务管理等企业级功能,同时利用XFire的简洁的Web服务开发模型。 4. XFire与Spring整合的基本步骤 整合的基本步骤可能包括添加必要的依赖到项目中,配置Spring的applicationContext.xml,以包括XFire特定的bean配置。比如,需要配置XFire的ServiceExporter和ServicePublisher beans,使得Spring可以管理XFire的Web服务。同时,需要定义服务接口以及服务实现类,并通过注解或者XML配置将其关联起来。 5. Web服务实现示例:“HELLOworld” 实现一个Web服务通常涉及到定义服务接口和服务实现类。服务接口定义了服务的方法,而服务实现类则提供了这些方法的具体实现。在XFire和Spring整合的上下文中,“HELLOworld”示例可能包含一个接口定义,比如`HelloWorldService`,和一个实现类`HelloWorldServiceImpl`,该类有一个`sayHello`方法返回"HELLO world"字符串。 6. 部署和测试 部署Web服务时,需要将应用程序打包成WAR文件,并部署到支持Servlet 2.3及以上版本的Web应用服务器上。部署后,可以通过客户端或浏览器测试Web服务的功能,例如通过访问XFire提供的服务描述页面(WSDL)来了解如何调用服务。 7. JSP与Web服务交互 如果在应用程序中使用了JSP页面,那么JSP可以用来作为用户与Web服务交互的界面。例如,JSP可以包含JavaScript代码来发送异步的AJAX请求到Web服务,并展示返回的结果给用户。在这个过程中,JSP页面可能使用XMLHttpRequest对象或者现代的Fetch API与Web服务进行通信。 8. 项目配置文件说明 项目配置文件如web.xml和applicationContext.xml分别在Web应用和服务配置中扮演关键角色。web.xml负责定义Web组件,比如Servlet、过滤器和监听器,而applicationContext.xml则负责定义Spring容器中的bean,包括数据源、事务管理器、业务逻辑组件和服务访问器等。 总之,通过上述整合使用原代码的知识点,可以深入理解XFire与Spring框架的结合使用,以及如何开发和部署基本的Web服务。这些技术知识有助于进行更高层次的Web服务开发,以及在复杂的IT环境中灵活运用各种框架和工具。
recommend-type

【Unity2018汉化大揭秘】:一步到位优化中文用户体验

# 摘要 本论文详细介绍了Unity2018汉化项目的实施过程,从理论准备到实践步骤,再到后期的测试与优化,最终分享了汉化经验和心得。首先,强调了汉化项目对于用户体验提升和产品国际化的重要性,并分析了汉化资源的分类、识别与管理方法。接着,详细阐述了汉化工具的选择、脚本编写、资源手动调整等实践步骤,以及汉化质量测试、体验优化和项目维护更新的重要性。论文最后通过案例研究,分析了汉化中的挑战和应对策略,并预测了汉化技术未来的发展方向。整个汉化过程不仅涉及技术层面的操作,还包含了深入的理论研究和实践心得分享,对提升汉化项目的效率和质量具有指导意义。 # 关键字 Unity汉化;用户体验;国际化;资源
recommend-type

iPhone

<think>我们注意到用户意图不明确,但提到了“照片提取”和“其他功能帮助”。因此,我们需要通过搜索来获取关于iPhone照片提取的常见方法以及其他可能的功能帮助。由于用户问题比较宽泛,我们将重点放在照片提取上,因为这是明确提到的关键词。同时,我们也会考虑一些其他常用功能的帮助。首先,针对照片提取,可能涉及从iPhone导出照片、从备份中提取照片、或者从损坏的设备中恢复照片等。我们将搜索这些方面的信息。其次,关于其他功能帮助,我们可以提供一些常见问题的快速指南,如电池优化、屏幕时间管理等。根据要求,我们需要将答案组织为多个方法或步骤,并在每个步骤间换行。同时,避免使用第一人称和步骤词汇。由于
recommend-type

驾校一点通软件:提升驾驶证考试通过率

标题“驾校一点通”指向的是一款专门为学员考取驾驶证提供帮助的软件,该软件强调其辅助性质,旨在为学员提供便捷的学习方式和复习资料。从描述中可以推断出,“驾校一点通”是一个与驾驶考试相关的应用软件,这类软件一般包含驾驶理论学习、模拟考试、交通法规解释等内容。 文件标题中的“2007”这个年份标签很可能意味着软件的最初发布时间或版本更新年份,这说明了软件具有一定的历史背景和可能经过了多次更新,以适应不断变化的驾驶考试要求。 压缩包子文件的文件名称列表中,有以下几个文件类型值得关注: 1. images.dat:这个文件名表明,这是一个包含图像数据的文件,很可能包含了用于软件界面展示的图片,如各种标志、道路场景等图形。在驾照学习软件中,这类图片通常用于帮助用户认识和记忆不同交通标志、信号灯以及驾驶过程中需要注意的各种道路情况。 2. library.dat:这个文件名暗示它是一个包含了大量信息的库文件,可能包含了法规、驾驶知识、考试题库等数据。这类文件是提供给用户学习驾驶理论知识和准备科目一理论考试的重要资源。 3. 驾校一点通小型汽车专用.exe:这是一个可执行文件,是软件的主要安装程序。根据标题推测,这款软件主要是针对小型汽车驾照考试的学员设计的。通常,小型汽车(C1类驾照)需要学习包括车辆构造、基础驾驶技能、安全行车常识、交通法规等内容。 4. 使用说明.html:这个文件是软件使用说明的文档,通常以网页格式存在,用户可以通过浏览器阅读。使用说明应该会详细介绍软件的安装流程、功能介绍、如何使用软件的各种模块以及如何通过软件来帮助自己更好地准备考试。 综合以上信息,我们可以挖掘出以下几个相关知识点: - 软件类型:辅助学习软件,专门针对驾驶考试设计。 - 应用领域:主要用于帮助驾考学员准备理论和实践考试。 - 文件类型:包括图片文件(images.dat)、库文件(library.dat)、可执行文件(.exe)和网页格式的说明文件(.html)。 - 功能内容:可能包含交通法规知识学习、交通标志识别、驾驶理论学习、模拟考试、考试题库练习等功能。 - 版本信息:软件很可能最早发布于2007年,后续可能有多个版本更新。 - 用户群体:主要面向小型汽车驾照考生,即C1类驾照学员。 - 使用方式:用户需要将.exe安装文件进行安装,然后根据.html格式的使用说明来熟悉软件操作,从而利用images.dat和library.dat中的资源来辅助学习。 以上知识点为从给定文件信息中提炼出来的重点,这些内容对于了解“驾校一点通”这款软件的功能、作用、使用方法以及它的发展历史都有重要的指导意义。
recommend-type

【DFLauncher自动化教程】:简化游戏启动流程,让游戏体验更流畅

# 摘要 DFLauncher是一个功能丰富的游戏启动和管理平台,本论文将介绍其安装、基础使用、高级设置、社区互动以及插件开发等方面。通过对配置文件的解析、界面定制、自动化功能的实现、高级配置选项、安全性和性能监控的详细讨论,本文阐述了DFLauncher如何帮助用户更高效地管理和优化游戏环境。此外,本文还探讨了DFLauncher社区的资源分享、教育教程和插件开发等内容,