controller-pcba/Core/Src/freertos.c

1032 lines
32 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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.
* @file freertos.c
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "event_groups.h" // 添加事件组支持
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdint.h> // 添加标准整型定义
#include "stm32f4xx_hal.h" // 添加HAL库定义
#include "dac161s997.h"
#include "ad7124.h"
#include "usart.h"
#include "communication_protocol.h"
#include "tim.h"
#include "gpio.h"
#include "tcpserverc.h"
#include "lwip.h"
#include "lwip/tcp.h" // 添加TCP相关定义
#include "uart_lcd.h"
#include "user_gpio.h"
#include "linear_encoder.h"
#include "lan8742.h"
#include "ad7124_test.h"
#include <string.h> // 添加string.h用于字符串操作
#include "ht1200m.h"
#include "TCA6416.h" // 添加TCA6416头文件
#include "DAC8568.h"
#include "dma.h" // 添加DMA头文件
// 声明外部变量
extern ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX];
/* 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 */
osThreadId lwip_taskHandle;
osThreadId led_taskHandle;
osThreadId adc_taskHandle;
osThreadId io_control_taskHandle; // 合并后的IO控制任务
osThreadId dac_control_taskHandle; // 合并后的DAC控制任务
osThreadId usart6_test_taskHandle;
osThreadId dma_test_taskHandle; // 添加DMA测试任务句柄
// 添加调试变量
static volatile uint32_t uart6_dr_raw = 0; // UART数据寄存器的原始值
static volatile uint8_t uart6_data_bits = 0; // 数据位8位
static volatile uint8_t uart6_parity_bit = 0; // 校验位
static volatile uint8_t uart6_stop_bits = 0; // 停止位
static volatile uint8_t uart6_error_flags = 0; // 错误标志
// 添加RTS引脚监控变量
volatile GPIO_PinState rts_pin_state = GPIO_PIN_RESET; // RTS引脚当前状态
volatile GPIO_PinState rst_pin_state = GPIO_PIN_RESET; // RTS引脚当前状态
volatile uint32_t rts_pin_pull = 0; // RTS引脚上下拉配置
volatile uint32_t rts_pin_mode = 0; // RTS引脚模式
volatile uint32_t rts_pin_speed = 0; // RTS引脚速度
volatile uint32_t rts_pin_alternate = 0; // RTS引脚复用功能
// 添加全局变量用于存储TCA6416引脚状态
volatile uint8_t tca6416_port0_status = 0; // 第一个TCA6416的Port0状态
volatile uint8_t tca6416_port1_status = 0; // 第一个TCA6416的Port1状态
volatile uint8_t tca6416_port2_status = 0; // 第二个TCA6416的Port0状态
volatile uint8_t tca6416_port3_status = 0; // 第二个TCA6416的Port1状态
volatile uint8_t tca6416_port4_status = 0; // 第三个TCA6416的Port0状态
volatile uint8_t tca6416_port5_status = 0; // 第三个TCA6416的Port1状态
// 添加TCA6416测试相关的调试变量
volatile uint8_t tca6416_test_step = 0; // 当前测试步骤
volatile uint8_t tca6416_init_result = 0xFF; // 初始化结果
volatile uint8_t tca6416_init2_result = 0xFF; // 第二个芯片初始化结果
volatile uint8_t tca6416_init3_result = 0xFF; // 第三个芯片初始化结果
volatile uint8_t tca6416_write_data = 0; // 写入的数据
volatile uint8_t tca6416_read_data = 0; // 读取的数据
volatile uint8_t tca6416_error_count = 0; // 错误计数
volatile uint8_t tca6416_test_pattern = 0; // 测试模式
volatile uint8_t tca6416_port0_dir = 0; // Port0方向寄存器值
volatile uint8_t tca6416_port1_dir = 0; // Port1方向寄存器值
volatile uint8_t tca6416_i2c_ack_status = 0; // I2C应答状态
// 添加接收缓冲区
static uint8_t uart6_rx_buffer[1];
static volatile uint8_t uart6_rx_data = 0;
static volatile uint8_t uart6_rx_flag = 0;
// 添加数据缓冲相关变量
#define UART6_BUFFER_SIZE 128
#define UART6_TIMEOUT_MS 50 // 50ms超时认为数据包结束
static uint8_t uart6_data_buffer[UART6_BUFFER_SIZE];
static volatile uint16_t uart6_buffer_index = 0;
static volatile uint32_t uart6_last_rx_time = 0;
// 添加任务同步对象
osSemaphoreId adc_semaphoreHandle;
osSemaphoreId uart6_semaphoreHandle;
osSemaphoreId io_semaphoreHandle; // IO控制任务信号量
osSemaphoreId dac_semaphoreHandle; // DAC控制任务信号量
// DMA测试相关变量
#define DMA_UART_RX_BUFFER_SIZE 256
#define DMA_UART_TX_BUFFER_SIZE 256
#define DMA_ADC_BUFFER_SIZE 32
#define DMA_DAC_BUFFER_SIZE 32
static uint8_t dma_uart_rx_buffer[DMA_UART_RX_BUFFER_SIZE];
static uint8_t dma_uart_tx_buffer[DMA_UART_TX_BUFFER_SIZE];
static uint16_t dma_adc_buffer[DMA_ADC_BUFFER_SIZE];
static uint16_t dma_dac_buffer[DMA_DAC_BUFFER_SIZE];
// DMA传输状态标志
volatile uint8_t dma_uart_rx_complete = 0;
volatile uint8_t dma_uart_tx_complete = 0;
volatile uint8_t dma_adc_complete = 0;
volatile uint8_t dma_dac_complete = 0;
volatile uint16_t dma_uart_rx_count = 0;
volatile uint16_t dma_uart_tx_count = 0;
volatile uint16_t dma_adc_count = 0;
volatile uint16_t dma_dac_count = 0;
// DMA错误计数
volatile uint32_t dma_uart_rx_errors = 0;
volatile uint32_t dma_uart_tx_errors = 0;
volatile uint32_t dma_adc_errors = 0;
volatile uint32_t dma_dac_errors = 0;
// 添加信号量句柄
osSemaphoreId tca6416_semaphoreHandle; // 添加TCA6416信号量句柄
// 添加DMA句柄
DMA_HandleTypeDef hdma_uart6_rx; // UART6接收DMA句柄
DMA_HandleTypeDef hdma_uart6_tx; // UART6发送DMA句柄
/* USER CODE END Variables */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
extern float current_buff[2];
extern uint8_t TCA6416_WritePort_buff[2];
extern struct netif gnetif;
extern ETH_HandleTypeDef heth;
extern struct tcp_pcb *server_pcb_hart1;
extern struct tcp_pcb *server_pcb_hart2;
extern struct tcp_pcb *server_pcb_ble1;
extern struct tcp_pcb *server_pcb_ble2;
extern struct tcp_pcb *server_pcb_control;
extern void tcp_abort(struct tcp_pcb *pcb);
void start_usart6_test_task(void const *argument); // 添加USART6测试任务函数声明
void start_io_control_task(void const *argument); // 添加IO控制任务函数声明
void start_dac_control_task(void const *argument); // 添加DAC控制任务函数声明
void start_dma_test_task(void const *argument); // 添加DMA测试任务函数声明
// 声明外部回调函数
extern void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
extern void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
extern void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
/* USER CODE END FunctionPrototypes */
void start_tcp_task(void const *argument);
void start_led_toggle_task(void const *argument);
void start_adc_task(void const *argument);
void start_io_control_task(void const *argument);
void start_dac_control_task(void const *argument);
void start_dac161s997_test_task(void const *argument);
extern void MX_LWIP_Init(void);
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 */
// 创建同步对象
osSemaphoreDef(adc_semaphore);
adc_semaphoreHandle = osSemaphoreCreate(osSemaphore(adc_semaphore), 1);
osSemaphoreDef(uart6_semaphore);
uart6_semaphoreHandle = osSemaphoreCreate(osSemaphore(uart6_semaphore), 1);
osSemaphoreDef(io_semaphore);
io_semaphoreHandle = osSemaphoreCreate(osSemaphore(io_semaphore), 1);
osSemaphoreDef(dac_semaphore);
dac_semaphoreHandle = osSemaphoreCreate(osSemaphore(dac_semaphore), 1);
// 创建TCA6416信号量
osSemaphoreDef(tca6416_semaphore);
tca6416_semaphoreHandle = osSemaphoreCreate(osSemaphore(tca6416_semaphore), 1);
/* Create the thread(s) */
/* definition and creation of lwip_task */
osThreadDef(lwip_task, start_tcp_task, osPriorityHigh, 0, 512);
lwip_taskHandle = osThreadCreate(osThread(lwip_task), NULL);
/* HART测试任务 - 提高优先级和栈大小 */
osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityAboveNormal, 0, 256);
usart6_test_taskHandle = osThreadCreate(osThread(usart6_test_task), NULL);
/* ADC任务 - 提高优先级和栈大小 */
osThreadDef(adc_task, start_adc_task, osPriorityNormal, 0, 256);
adc_taskHandle = osThreadCreate(osThread(adc_task), NULL);
/* IO控制任务 - 合并TCA6416和GPIO控制 */
osThreadDef(io_control_task, start_io_control_task, osPriorityNormal, 0, 256);
io_control_taskHandle = osThreadCreate(osThread(io_control_task), NULL);
/* DAC控制任务 DAC8568控制 */
osThreadDef(dac_control_task, start_dac_control_task, osPriorityBelowNormal, 0, 256);
dac_control_taskHandle = osThreadCreate(osThread(dac_control_task), NULL);
/* DAC161S997测试任务 - 使用较高优先级以确保及时处理 */
osThreadDef(dac161s997_test_task, start_dac161s997_test_task, osPriorityAboveNormal, 0, 256);
osThreadCreate(osThread(dac161s997_test_task), NULL);
/* USER CODE END RTOS_THREADS */
}
/* USER CODE BEGIN Header_start_tcp_task */
/**
* @brief Function implementing the lwip_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_tcp_task */
void start_tcp_task(void const *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN start_tcp_task */
// 等待网络初始化完成
osDelay(1000);
// 初始化TCP服务器
tcp_echo_init();
uart_lcd_draw_ipaddr(); // 初始化显示IP地址信息
// 添加网络状态变量
static uint8_t last_network_state = 0;
static uint32_t network_down_time = 0;
/* Infinite loop */
for (;;)
{
uint32_t phyreg = 0;
HAL_ETH_ReadPHYRegister(&heth, 0x00, PHY_BSR, &phyreg);
uint8_t current_network_state = ((phyreg >> 2) & 0x1);
// 网络状态发生变化
if (current_network_state != last_network_state)
{
if (current_network_state == 0) // 网络断开
{
/* When the netif link is down this function must be called */
netif_set_link_down(&gnetif);
netif_set_down(&gnetif);
network_down_time = HAL_GetTick();
// 关闭所有TCP连接
if (tcp_echo_flags_hart1 == 1)
{
tcp_abort(server_pcb_hart1);
tcp_echo_flags_hart1 = 0;
}
if (tcp_echo_flags_hart2 == 1)
{
tcp_abort(server_pcb_hart2);
tcp_echo_flags_hart2 = 0;
}
#if (BLE2_USART6 == 1)
if (tcp_echo_flags_ble1 == 1)
{
tcp_abort(server_pcb_ble1);
tcp_echo_flags_ble1 = 0;
}
#endif
if (tcp_echo_flags_ble2 == 1)
{
tcp_abort(server_pcb_ble2);
tcp_echo_flags_ble2 = 0;
}
if (tcp_echo_flags_control == 1)
{
tcp_abort(server_pcb_control);
tcp_echo_flags_control = 0;
}
}
else // 网络恢复
{
/* When the netif is fully configured this function must be called */
netif_set_link_up(&gnetif);
netif_set_up(&gnetif);
// 等待网络稳定
osDelay(1000);
// 重新初始化TCP服务器
tcp_echo_init();
uart_lcd_draw_ipaddr();
}
last_network_state = current_network_state;
}
// 网络断开超过5秒尝试重新初始化
else if (current_network_state == 0 && (HAL_GetTick() - network_down_time) > 5000)
{
// 尝试重新初始化网络
MX_LWIP_Init();
osDelay(1000);
// 重新检查网络状态
HAL_ETH_ReadPHYRegister(&heth, 0x00, PHY_BSR, &phyreg);
if (((phyreg >> 2) & 0x1) == 1)
{
netif_set_link_up(&gnetif);
netif_set_up(&gnetif);
tcp_echo_init();
uart_lcd_draw_ipaddr();
last_network_state = 1;
}
else
{
network_down_time = HAL_GetTick();
}
}
vTaskDelay(1000);
}
/* USER CODE END start_tcp_task */
}
/* USER CODE BEGIN Header_start_led_toggle_task */
/**
* @brief Function implementing the led_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_led_toggle_task */
void start_led_toggle_task(void const *argument)
{
/* USER CODE BEGIN start_led_toggle_task */
/* Infinite loop */
for (;;)
{
HAL_GPIO_TogglePin(LED3_G_GPIO_Port, LED3_G_Pin);
uart_lcd_ecll_control_current_out();
vTaskDelay(500);
}
/* USER CODE END start_led_toggle_task */
}
/* USER CODE BEGIN Header_start_adc_task */
/**
* @brief ADC任务函数实现
* @param argument: 未使用
* @retval None
*/
/* USER CODE END Header_start_adc_task */
void start_adc_task(void const *argument)
{
/* USER CODE BEGIN start_adc_task */
// 初始化两个AD7124设备
ad7124_setup(1); // 初始化两个AD7124设备
ad7124_setup(2); // 初始化两个AD7124设备
/* Infinite loop */
for (;;)
{
// 读取第一个AD7124的所有通道
for (uint8_t ch = AD7124_AIN0; ch < AD7124_CHANNEL_EN_MAX; ch++)
{
ad7124_get_analog(ch, 1);
}
// 读取第二个AD7124的所有通道
for (uint8_t ch = AD7124_AIN0; ch < AD7124_CHANNEL_EN_MAX; ch++)
{
ad7124_get_analog(ch, 2);
}
vTaskDelay(10);
}
/* USER CODE END start_adc_task */
}
/* USER CODE BEGIN Header_start_io_control_task */
/**
* @brief Function implementing the io_control_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_io_control_task */
void start_io_control_task(void const *argument)
{
/* USER CODE BEGIN start_io_control_task */
uint8_t ret = 0;
uint8_t addr_scan_result[8] = {0};
// 等待系统稳定
osDelay(100);
// 初始化TCA6416
tca6416_test_step = 0;
for(uint8_t addr = 0x20; addr <= 0x27; addr++)
{
I2C_Start();
ret = I2C_SendByte(addr << 1);
I2C_Stop();
addr_scan_result[addr - 0x20] = ret;
osDelay(10);
}
// 初始化三个TCA6416芯片
tca6416_init_result = TCA6416_Init();
tca6416_init2_result = TCA6416_Init2();
tca6416_init3_result = TCA6416_Init3();
// 配置第一个TCA6416芯片的端口方向和输出状态
if(tca6416_init_result == 0) // 确保初始化成功
{
// 设置端口为输出模式
TCA6416_SetPortDirection(0, 0x00); // Port0输出
TCA6416_SetPortDirection(1, 0x00); // Port1输出
osDelay(5);
}
// 配置其他两个芯片的端口方向
if(tca6416_init2_result == 0)
{
TCA6416_SetPortDirection2(0, 0xFF); // Port0输入
TCA6416_SetPortDirection2(1, 0xFF); // Port1输入
}
if(tca6416_init3_result == 0)
{
TCA6416_SetPortDirection3(0, 0xFF); // Port0输入
TCA6416_SetPortDirection3(1, 0xFF); // Port1输入
}
/* Infinite loop */
for(;;)
{
// 获取信号量
if(osSemaphoreWait(io_semaphoreHandle, 100) == osOK)
{
TCA6416_WritePort(0, TCA6416_WritePort_buff[1]);
osDelay(5);
TCA6416_WritePort(1, TCA6416_WritePort_buff[0]);
osDelay(5);
// 读取其他芯片状态
if(tca6416_init2_result == 0)
{
if(TCA6416_ReadPort2(0, &tca6416_read_data) == 0)
{
tca6416_port2_status = tca6416_read_data;
}
if(TCA6416_ReadPort2(1, &tca6416_read_data) == 0)
{
tca6416_port3_status = tca6416_read_data;
}
}
if(tca6416_init3_result == 0)
{
if(TCA6416_ReadPort3(0, &tca6416_read_data) == 0)
{
tca6416_port4_status = tca6416_read_data;
}
if(TCA6416_ReadPort3(1, &tca6416_read_data) == 0)
{
tca6416_port5_status = tca6416_read_data;
}
}
// 释放信号量
osSemaphoreRelease(io_semaphoreHandle);
}
// 200ms扫描周期
osDelay(200);
}
/* USER CODE END start_io_control_task */
}
/* USER CODE BEGIN Header_start_dac_control_task */
/**
* @brief Function implementing the dac_control_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_dac_control_task */
void start_dac_control_task(void const *argument)
{
/* USER CODE BEGIN start_dac_control_task */
// 等待系统稳定
osDelay(1000);
// 初始化DAC8568
DAC8568_Init(&hspi3);
HAL_Delay(10);
DAC8568_EnableStaticInternalRef();
/* Infinite loop */
for(;;)
{
// 获取信号量
if(osSemaphoreWait(dac_semaphoreHandle, 100) == osOK)
{
// 处理DAC161S997输出
// current_buff[0] = 12.0f; // 示例值
// dac161s997_output(DAC161S997, current_buff[0]);
// 处理DAC8568输出
// uint16_t dac_value = 32768; // 示例值
// DAC8568_WriteAndUpdate(BROADCAST, dac_value);
// 释放信号量
osSemaphoreRelease(dac_semaphoreHandle);
}
// 500ms更新周期
osDelay(500);
}
/* USER CODE END start_dac_control_task */
}
// UART接收完成回调函数
static void UART6_RxCpltCallback(void)
{
uart6_rx_data = uart6_rx_buffer[0];
uart6_rx_flag = 1;
// 重新启动接收
HAL_UART_Receive_IT(&huart6, uart6_rx_buffer, 1);
}
//HART1 串口测试任务
void start_usart6_test_task(void const *argument)
{
/* USER CODE BEGIN start_usart6_test_task */
err_t err;
uint32_t current_time;
// 确保UART6已正确初始化
if (huart6.Instance == NULL) {
Error_Handler();
}
// 重新初始化UART6
HAL_UART_DeInit(&huart6);
huart6.Init.BaudRate = 1200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
// 清除所有标志位
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_RXNE);
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_PE);
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_FE);
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_ORE);
if (HAL_UART_Init(&huart6) != HAL_OK) {
Error_Handler();
}
// 初始化缓冲区
uart6_buffer_index = 0;
uart6_last_rx_time = 0;
/* Infinite loop */
for(;;)
{
current_time = HAL_GetTick();
// 直接检查接收标志
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_RXNE))
{
// 读取数据寄存器的原始值
uart6_dr_raw = huart6.Instance->DR;
// 解析数据寄存器的各个位
uart6_data_bits = (uint8_t)(uart6_dr_raw & 0xFF); // 低8位是数据位
uart6_parity_bit = (uint8_t)((uart6_dr_raw >> 8) & 0x1); // 第9位是校验位
uart6_stop_bits = (uint8_t)((uart6_dr_raw >> 9) & 0x3); // 第10-11位是停止位
// 存储错误标志
uart6_error_flags = 0;
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_PE)) uart6_error_flags |= 0x01;
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_FE)) uart6_error_flags |= 0x02;
if (__HAL_UART_GET_FLAG(&huart6, UART_FLAG_ORE)) uart6_error_flags |= 0x04;
// 检查是否有接收错误
if (uart6_error_flags == 0)
{
// 将数据添加到缓冲区
if (uart6_buffer_index < UART6_BUFFER_SIZE)
{
uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits;
uart6_last_rx_time = current_time; // 更新最后接收时间
}
else
{
// 缓冲区满,强制发送
if (server_pcb_control != NULL && tcp_echo_flags_control == 1 && uart6_buffer_index > 0)
{
err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1);
if (err == ERR_OK)
{
tcp_output(server_pcb_control);
}
}
// 重置缓冲区
uart6_buffer_index = 0;
uart6_data_buffer[uart6_buffer_index++] = uart6_data_bits;
uart6_last_rx_time = current_time;
}
}
else
{
// 清除错误标志
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_PE);
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_FE);
__HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_ORE);
}
}
// 检查超时,如果超时且有数据则发送
if (uart6_buffer_index > 0 &&
uart6_last_rx_time > 0 &&
(current_time - uart6_last_rx_time) >= UART6_TIMEOUT_MS)
{
// 检查TCP连接状态并发送缓冲区数据
if (server_pcb_control != NULL && tcp_echo_flags_control == 1)
{
err = tcp_write(server_pcb_control, uart6_data_buffer, uart6_buffer_index, 1);
if (err == ERR_OK)
{
err = tcp_output(server_pcb_control);
if (err != ERR_OK)
{
// TCP输出失败关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
}
else if (err == ERR_MEM)
{
// 内存不足,等待一段时间后重试
vTaskDelay(10);
continue; // 不清除缓冲区,下次重试
}
else
{
// 其他错误(如连接已关闭),关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
}
// 重置缓冲区
uart6_buffer_index = 0;
uart6_last_rx_time = 0;
}
vTaskDelay(5); // 给其他任务执行的机会
}
/* USER CODE END start_usart6_test_task */
}
void test_tca6416_task(void const *argument)
{
/* USER CODE BEGIN test_tca6416_task */
uint8_t ret = 0;
uint8_t addr_scan_result[8] = {0};
// 等待系统稳定
osDelay(100);
// 步骤0: I2C地址扫描
tca6416_test_step = 0;
for(uint8_t addr = 0x20; addr <= 0x27; addr++)
{
I2C_Start();
ret = I2C_SendByte(addr << 1);
I2C_Stop();
addr_scan_result[addr - 0x20] = ret; // 0=ACK, 1=NACK
osDelay(10);
}
// 步骤1: 初始化第一个TCA6416芯片
tca6416_test_step = 1;
tca6416_init_result = TCA6416_Init();
// 步骤2: 初始化第二个TCA6416芯片地址0x21
tca6416_test_step = 2;
tca6416_init2_result = TCA6416_Init2();
// 步骤3: 初始化第三个TCA6416芯片地址0x20第二条总线
tca6416_test_step = 3;
tca6416_init3_result = TCA6416_Init3();
// 设置第一个芯片Port0和Port1为输出0=输出1=输入)
// 注意输出状态由tcpecho_recv_control控制这里只设置方向
ret = TCA6416_SetPortDirection(0, 0x00); // Port0全部设为输出
osDelay(10);
ret = TCA6416_SetPortDirection(1, 0x00); // Port1全部设为输出
osDelay(10);
// 步骤5: 配置第二、三个芯片所有IO为输入模式
tca6416_test_step = 5;
// 第二个芯片设为输入
if(tca6416_init2_result == 0)
{
TCA6416_SetPortDirection2(0, 0xFF); // Port0全部设为输入
osDelay(10);
TCA6416_SetPortDirection2(1, 0xFF); // Port1全部设为输入
osDelay(10);
}
// 第三个芯片设为输入
if(tca6416_init3_result == 0)
{
TCA6416_SetPortDirection3(0, 0xFF); // Port0全部设为输入
osDelay(10);
TCA6416_SetPortDirection3(1, 0xFF); // Port1全部设为输入
osDelay(10);
}
// 步骤6: 循环检测所有芯片状态 - 优化扫描周期
tca6416_test_step = 6;
for(;;)
{
// 获取信号量
if(osSemaphoreWait(tca6416_semaphoreHandle, 100) == osOK)
{
// 读取第一个芯片状态
if(TCA6416_ReadPort(0, &tca6416_read_data) == 0)
{
tca6416_port0_status = tca6416_read_data;
}
if(TCA6416_ReadPort(1, &tca6416_read_data) == 0)
{
tca6416_port1_status = tca6416_read_data;
}
// 读取第二个芯片状态
if(tca6416_init2_result == 0)
{
if(TCA6416_ReadPort2(0, &tca6416_read_data) == 0)
{
tca6416_port2_status = tca6416_read_data;
}
if(TCA6416_ReadPort2(1, &tca6416_read_data) == 0)
{
tca6416_port3_status = tca6416_read_data;
}
}
// 读取第三个芯片状态
if(tca6416_init3_result == 0)
{
if(TCA6416_ReadPort3(0, &tca6416_read_data) == 0)
{
tca6416_port4_status = tca6416_read_data;
}
if(TCA6416_ReadPort3(1, &tca6416_read_data) == 0)
{
tca6416_port5_status = tca6416_read_data;
}
}
// 释放信号量
osSemaphoreRelease(tca6416_semaphoreHandle);
}
// 缩短扫描周期到200ms
osDelay(200);
}
/* USER CODE END test_tca6416_task */
}
/* USER CODE BEGIN Header_start_dac161s997_test_task */
/**
* @brief Function implementing the dac161s997_test_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_dac161s997_test_task */
void start_dac161s997_test_task(void const *argument)
{
// 等待系统稳定
osDelay(1000); // 启动延时1秒等待系统稳定
// 初始化DAC161S997
dac161s997_init();
/* DAC161必须脉冲输出*/
for (;;)
{
dac161s997_output(DAC161S997, current_buff[0]); // 输出当前电流值
osDelay(100); // 延时100ms
}
/* USER CODE END start_dac161s997_test_task */
}
/* USER CODE BEGIN Header_start_dac8568_test_task */
/**
* @brief Function implementing the dac8568_test_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_dac8568_test_task */
void start_dac8568_test_task(void const *argument)
{
// 初始化DAC8568
DAC8568_Init(&hspi3); // 使用SPI3
HAL_Delay(10);
// 启用静态内部参考(2.5V)
DAC8568_EnableStaticInternalRef();
while(1)
{
//uint16_t i = 65535;
//DAC8568_WriteAndUpdate(CHANNEL_A, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_B, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_C, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_D, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_E, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_F, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_G, (uint16_t)i);
//DAC8568_WriteAndUpdate(CHANNEL_H, (uint16_t)i);
// for (int i = 65535; i >= 0; i = i - 4096) // 从65535到0步长4096
// {
// // 写入并更新所有通道的值
// DAC8568_WriteAndUpdate(BROADCAST, (uint16_t)i);
// // 计算电压值 (假设Vref=2.5V16位分辨率2倍增益)
// float voltage = 2.5f * 2.0f * i / 65536.0f;
// 延时2秒
osDelay(1000);
//}
}
}
/* USER CODE BEGIN Header_start_dma_test_task */
/**
* @brief Function implementing the dma_test_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_dma_test_task */
void start_dma_test_task(void const *argument)
{
/* USER CODE BEGIN start_dma_test_task */
HAL_StatusTypeDef status;
// 等待系统稳定
osDelay(1000);
// 初始化DMA
// 1. 配置UART6 DMA
__HAL_RCC_DMA2_CLK_ENABLE(); // 使能DMA2时钟
// 配置UART6接收DMA
hdma_uart6_rx.Instance = DMA2_Stream1;
hdma_uart6_rx.Init.Channel = DMA_CHANNEL_5;
hdma_uart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart6_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart6_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart6_rx.Init.Mode = DMA_CIRCULAR; // 循环模式
hdma_uart6_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_uart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
status = HAL_DMA_Init(&hdma_uart6_rx);
if (status != HAL_OK) {
dma_uart_rx_errors++;
Error_Handler();
}
// 配置UART6发送DMA
hdma_uart6_tx.Instance = DMA2_Stream6;
hdma_uart6_tx.Init.Channel = DMA_CHANNEL_5;
hdma_uart6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart6_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart6_tx.Init.Mode = DMA_NORMAL; // 正常模式
hdma_uart6_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_uart6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
status = HAL_DMA_Init(&hdma_uart6_tx);
if (status != HAL_OK) {
dma_uart_tx_errors++;
Error_Handler();
}
// 关联DMA到UART6
__HAL_LINKDMA(&huart6, hdmarx, hdma_uart6_rx);
__HAL_LINKDMA(&huart6, hdmatx, hdma_uart6_tx);
// 启动UART6 DMA接收
status = HAL_UART_Receive_DMA(&huart6, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE);
if (status != HAL_OK) {
dma_uart_rx_errors++;
Error_Handler();
}
/* Infinite loop */
for(;;)
{
// 检查DMA传输状态
if (dma_uart_rx_complete) {
// 处理接收到的数据
dma_uart_rx_count++;
dma_uart_rx_complete = 0;
// 这里可以添加数据处理逻辑
// 例如将接收到的数据通过TCP发送出去
if (server_pcb_control != NULL && tcp_echo_flags_control == 1) {
err_t err = tcp_write(server_pcb_control, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE, 1);
if (err == ERR_OK) {
tcp_output(server_pcb_control);
}
}
}
// 测试DMA发送
if (dma_uart_tx_complete) {
dma_uart_tx_count++;
dma_uart_tx_complete = 0;
// 准备新的测试数据
for (int i = 0; i < DMA_UART_TX_BUFFER_SIZE; i++) {
dma_uart_tx_buffer[i] = 'A' + (i % 26); // 简单的测试数据
}
// 启动新的DMA发送
status = HAL_UART_Transmit_DMA(&huart6, dma_uart_tx_buffer, DMA_UART_TX_BUFFER_SIZE);
if (status != HAL_OK) {
dma_uart_tx_errors++;
}
}
// 每100ms检查一次状态
osDelay(100);
}
/* USER CODE END start_dma_test_task */
}