refactor(freertos): 重构 FreeRTOS 任务并优化网络处理逻辑

DAC161S的功能OK

- 修改任务优先级和堆栈大小
- 优化网络状态检测和处理逻辑
- 重构 DAC 控制任务,移除初始化冗余步骤
- 简化 DAC161S997 测试任务
- 设置电流缓冲区初始值为 12mA
This commit is contained in:
qiuxin 2025-06-03 10:56:49 +08:00
parent c63d3c4d79
commit e4f4929e01
4 changed files with 189 additions and 3909 deletions

View File

@ -46,6 +46,7 @@
#include "ht1200m.h"
#include "TCA6416.h" // 添加TCA6416头文件
#include "DAC8568.h"
#include "dma.h" // 添加DMA头文件
// 声明外部变量
extern ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX];
@ -158,6 +159,13 @@ 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 -----------------------------------------------*/
@ -177,6 +185,12 @@ 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);
@ -184,6 +198,7 @@ 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) */
@ -226,6 +241,10 @@ void MX_FREERTOS_Init(void)
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);
@ -240,16 +259,16 @@ void MX_FREERTOS_Init(void)
adc_taskHandle = osThreadCreate(osThread(adc_task), NULL);
/* IO控制任务 - 合并TCA6416和GPIO控制 */
osThreadDef(io_control_task, start_io_control_task, osPriorityNormal, 0, 384);
osThreadDef(io_control_task, start_io_control_task, osPriorityNormal, 0, 256);
io_control_taskHandle = osThreadCreate(osThread(io_control_task), NULL);
/* DAC控制任务 - 合并DAC161S997和DAC8568控制 */
osThreadDef(dac_control_task, start_dac_control_task, osPriorityBelowNormal, 0, 384);
osThreadDef(dac_control_task, start_dac_control_task, osPriorityBelowNormal, 0, 256);
dac_control_taskHandle = osThreadCreate(osThread(dac_control_task), NULL);
/* DMA测试任务 - 使用较高优先级以确保及时处理DMA事件 */
osThreadDef(dma_test_task, start_dma_test_task, osPriorityAboveNormal, 0, 384);
dma_test_taskHandle = osThreadCreate(osThread(dma_test_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 */
}
@ -265,64 +284,105 @@ 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);
if (((phyreg >> 2) & 0x1) != 0x1)
uint8_t current_network_state = ((phyreg >> 2) & 0x1);
// 网络状态发生变化
if (current_network_state != last_network_state)
{
/* When the netif link is down this function must be called */
netif_set_link_down(&gnetif);
netif_set_down(&gnetif); // 热插拔下线时调用
if (tcp_echo_flags_hart1 == 1)
if (current_network_state == 0) // 网络断开
{
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;
}
/* 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;
}
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_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;
}
}
if (tcp_echo_flags_control == 1)
else // 网络恢复
{
tcp_abort(server_pcb_control); // 热插拔下线时调用
tcp_echo_flags_control = 0;
/* 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;
}
else
// 网络断开超过5秒尝试重新初始化
else if (current_network_state == 0 && (HAL_GetTick() - network_down_time) > 5000)
{
/* When the netif is fully configured this function must be called */
netif_set_link_up(&gnetif);
netif_set_up(&gnetif); // 热插拔上线时调用
// if (tcp_echo_flags_ble1 == 2)
// {
// tcp_echo_init(); // 热插拔上线时调用
// // uart_lcd_draw_ipaddr(); // 初始化显示IP地址信息
// tcp_echo_flags_ble1 = 0;
// }
// 尝试重新初始化网络
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);
// osThreadTerminate(NULL);
}
/* USER CODE END start_tcp_task */
}
@ -499,14 +559,7 @@ void start_dac_control_task(void const *argument)
// 等待系统稳定
osDelay(1000);
// 初始化DAC161S997
dac161s997_init();
uint16_t init_status = dac161s997_read_status(DAC161S997);
if(init_status == 0xFFFF || init_status == 0x0000) {
osDelay(100);
dac161s997_init();
}
// 初始化DAC8568
DAC8568_Init(&hspi3);
HAL_Delay(10);
@ -536,9 +589,6 @@ void start_dac_control_task(void const *argument)
/* USER CODE END start_dac_control_task */
}
// 添加UART接收回调函数声明
static void UART6_RxCpltCallback(void);
// UART接收完成回调函数
static void UART6_RxCpltCallback(void)
{
@ -815,36 +865,18 @@ void test_tca6416_task(void const *argument)
/* USER CODE END Header_start_dac161s997_test_task */
void start_dac161s997_test_task(void const *argument)
{
/* USER CODE BEGIN start_dac161s997_test_task */
// 等待系统稳定
osDelay(1000); // 启动延时1秒等待系统稳定
// 初始化DAC
dac161s997_init();
// 读取初始状态
uint16_t init_status = dac161s997_read_status(DAC161S997);
if(init_status == 0xFFFF || init_status == 0x0000) {
// SPI通信有问题重新初始化
osDelay(100);
dac161s997_init();
}
/* Infinite loop */
// 初始化DAC161S997
dac161s997_init();
/* DAC161必须脉冲输出*/
for (;;)
{
// 设置输出电流为10mA
//current_buff[0] = 12.0f;
//dac161s997_output(DAC161S997, current_buff[0]);
// // 读取状态确认写入成功
// uint16_t status = dac161s997_read_status(DAC161S997);
// if(status == 0xFFFF || status == 0x0000) {
// // 如果通信失败,重试写入
// osDelay(10);
// dac161s997_output(DAC161S997, current_buff[0]);
// }
dac161s997_output(DAC161S997, current_buff[0]); // 输出当前电流值
osDelay(100); // 延时100ms
}
/* USER CODE END start_dac161s997_test_task */
@ -1000,28 +1032,4 @@ void start_dma_test_task(void const *argument)
osDelay(100);
}
/* USER CODE END start_dma_test_task */
}
// DMA回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART6) {
dma_uart_rx_complete = 1;
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART6) {
dma_uart_tx_complete = 1;
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART6) {
dma_uart_rx_errors++;
// 重新启动DMA接收
HAL_UART_Receive_DMA(&huart6, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE);
}
}

View File

@ -74,7 +74,7 @@ uart_t ble2_uart3 = {0};
uart_t hart2_uart2 = {0};
uart_t hart1_uart5 = {0};
uart_t usb_uart1 = {0};
float current_buff[2] = {0, 0};
float current_buff[2] = {12.0f, 0};//设置初始电流为12ma
uint8_t tcp_echo_flags_hart1 = 0;
uint8_t tcp_echo_flags_hart2 = 0;

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,9 @@
#include "DAC8568.h" // 添加DAC8568头文件
#include "dac161s997.h" // 添加DAC161S997头文件
#include "TCA6416.h" // 添加TCA6416头文件
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
// 添加test_adc_read_data变量定义
uint8_t test_adc_read_data[74] = {0}; // 74字节的测试数据缓冲区
@ -47,6 +50,7 @@ extern uint8_t tcp_echo_flags_ble1;
extern uint8_t tcp_echo_flags_ble2;
extern uint8_t tcp_echo_flags_control;
extern uint8_t send_data_flag_cmd;
extern float current_buff[2]; // 只声明,不初始化
extern uint8_t uart_echo_flags_hart1;
extern uint8_t uart_echo_flags_hart2;
@ -352,7 +356,7 @@ uint16_t handle_type_85(const uint8_t *body, uint16_t body_len, uint8_t *tx)
}
uint16_t handle_type_86(const uint8_t *body, uint16_t body_len, uint8_t *tx)
{
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 24 + 2; // 帧头+帧长+源+目标+类型+24字节输出读取+校验
uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 24 + 2; // 帧头+帧长+源+目标+类型+24字节输出读取+校验
// 帧头
tx[0] = head_00;
@ -728,83 +732,87 @@ static err_t tcpecho_recv_control(void *arg, struct tcp_pcb *tpcb, struct pbuf *
uint16_t body_len = 24; //24个字节表示的是设置的参数8个通道每个通道2字节HART电流2字节比例阀4字节0-15数字量输出2字节
uint16_t dac_value;
uint16_t dac161s_value;
uint16_t digital_value;
float voltage;
uint32_t dac_out;
const float SCALE_FACTOR = 1000.0f; // 新的比例系数输入值除以1000得到实际电压值
const float MAX_VOLTAGE = 2.5f; // 最大允许电压
const uint16_t MAX_DAC_VALUE = 0x8000; // 最大DAC值限制为32768
// 处理DAC8568的8个通道输出
// 通道A (CH0)
dac_value = (tcp_rx_data[9] << 8) | tcp_rx_data[10];
voltage = dac_value / SCALE_FACTOR; // 转换为实际电压值
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f); // 2.5V参考电压
if(dac_out > 65535) dac_out = 65535; // 限制最大值
DAC8568_WriteAndUpdate(CHANNEL_A, (uint16_t)dac_out);
// 通道B (CH4)
dac_value = (tcp_rx_data[11] << 8) | tcp_rx_data[12];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_B, (uint16_t)dac_out);
// 通道C (CH1)
dac_value = (tcp_rx_data[13] << 8) | tcp_rx_data[14];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_C, (uint16_t)dac_out);
// 通道D (CH5)
dac_value = (tcp_rx_data[15] << 8) | tcp_rx_data[16];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_D, (uint16_t)dac_out);
// 通道E (CH2)
dac_value = (tcp_rx_data[17] << 8) | tcp_rx_data[18];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_E, (uint16_t)dac_out);
// 通道F (CH6)
dac_value = (tcp_rx_data[19] << 8) | tcp_rx_data[20];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_F, (uint16_t)dac_out);
// 通道G (CH3)
dac_value = (tcp_rx_data[21] << 8) | tcp_rx_data[22];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_G, (uint16_t)dac_out);
// 通道H (CH7)
dac_value = (tcp_rx_data[23] << 8) | tcp_rx_data[24];
voltage = dac_value / SCALE_FACTOR;
dac_out = (uint32_t)((voltage / 2.5f) * 65535.0f);
if(dac_out > 65535) dac_out = 65535;
DAC8568_WriteAndUpdate(CHANNEL_H, (uint16_t)dac_out);
// 恢复合理的延时保护
static uint32_t last_dac_update_time = 0;
uint32_t current_time = HAL_GetTick();
if(current_time - last_dac_update_time < 50) { // 恢复到50ms
osDelay(50);
}
last_dac_update_time = current_time;
//HART电流输出
// 确保DAC8568已初始化
static uint8_t dac_initialized = 0;
if (!dac_initialized) {
DAC8568_Init(&hspi3);
HAL_Delay(10);
DAC8568_EnableStaticInternalRef();
dac_initialized = 1;
}
// 处理DAC8568的8个通道输出增加稳定性
for(int i = 0; i < 8; i++) {
uint8_t base_idx = 9 + i * 2;
dac_value = (tcp_rx_data[base_idx] << 8) | tcp_rx_data[base_idx + 1];
// 限制输入值范围并添加调试保护
if(dac_value > MAX_DAC_VALUE) {
dac_value = MAX_DAC_VALUE;
}
// 修改电压计算方式,确保正确的比例
voltage = (float)dac_value / SCALE_FACTOR;
if(voltage > MAX_VOLTAGE) {
voltage = MAX_VOLTAGE;
}
// 修改DAC输出值计算方式
dac_out = (uint32_t)((voltage / MAX_VOLTAGE) * 65535.0f); // 使用32768作为满量程
if(dac_out > 65535) dac_out = 65535;
// 根据通道号选择对应的通道
uint8_t channel;
switch(i) {
case 0: channel = CHANNEL_A; break;
case 1: channel = CHANNEL_C; break;
case 2: channel = CHANNEL_E; break;
case 3: channel = CHANNEL_G; break;
case 4: channel = CHANNEL_B; break;
case 5: channel = CHANNEL_D; break;
case 6: channel = CHANNEL_F; break;
case 7: channel = CHANNEL_H; break;
default: continue;
}
// 写入DAC增加稳定性
DAC8568_WriteAndUpdate(channel, (uint16_t)dac_out);
osDelay(5); // 恢复到5ms延时
}
//HART电流输出增加稳定性
dac161s_value = (tcp_rx_data[25] << 8) | tcp_rx_data[26];
dac161s997_output(DAC161S997, dac161s_value);
if(dac161s_value > 0x4e20) // 限制最大值为20000
{
dac161s_value = 0x4e20;
}
// 输入值除以1000得到实际电流值
current_buff [0] = (float)dac161s_value / 1000.0f;
//比例阀
//tcp_rx_data[27]
//tcp_rx_data[28]
//tcp_rx_data[29]
//tcp_rx_data[30]
// 数字量输出刷新第一个芯片的输出状态
TCA6416_WritePort(0, tcp_rx_data[27]); // 直接写入Port0的值8-15
osDelay(10);
TCA6416_WritePort(1, tcp_rx_data[28]); // 写入Port1的值0-7
osDelay(10);
if(tcp_rx_data[27] != 0xFF || tcp_rx_data[28] != 0xFF) { // 只在值变化时更新
TCA6416_WritePort(0, tcp_rx_data[27]); // 直接写入Port0的值8-15
osDelay(5);
TCA6416_WritePort(1, tcp_rx_data[28]); // 写入Port1的值0-7
osDelay(5);
}
// 保存设置的数据到adc_set_data数组
memcpy(adc_set_data, tcp_rx_data + 9, body_len);