controller-pcba/Core/Src/freertos.c

464 lines
14 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"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#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 "uart_lcd.h"
#include "user_gpio.h"
#include "linear_encoder.h"
#include "lan8742.h"
#include "ad7124_test.h"
// 声明外部变量
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 */
/* USER CODE END Variables */
osThreadId lwip_taskHandle;
osThreadId led_taskHandle;
osThreadId dac_taskHandle;
osThreadId adc_taskHandle;
osThreadId gpio_di_do_taskHandle;
osThreadId ec11_taskHandle;
osThreadId ad7124_test_taskHandle;
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
extern float current_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);
/* USER CODE END FunctionPrototypes */
void start_tcp_task(void const *argument);
void start_led_toggle_task(void const *argument);
void start_dac_task(void const *argument);
void start_adc_task(void const *argument);
void start_gpio_di_do_task(void const *argument);
void start_ec11_task(void const *argument);
void start_ad7124_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 */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* 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 lwip_task */
osThreadDef(lwip_task, start_tcp_task, osPriorityHigh, 0, 512);
lwip_taskHandle = osThreadCreate(osThread(lwip_task), NULL);
/* definition and creation of led_task */
// osThreadDef(led_task, start_led_toggle_task, osPriorityLow, 0, 128);
// led_taskHandle = osThreadCreate(osThread(led_task), NULL);
/* definition and creation of dac_task */
// osThreadDef(dac_task, start_dac_task, osPriorityNormal, 0, 512);
// dac_taskHandle = osThreadCreate(osThread(dac_task), NULL);
/* definition and creation of adc_task */
// osThreadDef(adc_task, start_adc_task, osPriorityBelowNormal, 0, 128);
// adc_taskHandle = osThreadCreate(osThread(adc_task), NULL);
/* definition and creation of gpio_di_do_task */
// osThreadDef(gpio_di_do_task, start_gpio_di_do_task, osPriorityNormal, 0, 128);
// gpio_di_do_taskHandle = osThreadCreate(osThread(gpio_di_do_task), NULL);
/* definition and creation of ec11_task */
// osThreadDef(ec11_task, start_ec11_task, osPriorityNormal, 0, 512);
// ec11_taskHandle = osThreadCreate(osThread(ec11_task), NULL);
/* definition and creation of ad7124_test_task */
osThreadDef(ad7124_test_task, start_ad7124_test_task, osPriorityNormal, 0, 512);
ad7124_test_taskHandle = osThreadCreate(osThread(ad7124_test_task), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* 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 */
tcp_echo_init();
uart_lcd_draw_ipaddr(); // 初始化显示IP地址信息
/* Infinite loop */
for (;;)
{
uint32_t phyreg = 0;
HAL_ETH_ReadPHYRegister(&heth, 0x00, PHY_BSR, &phyreg);
if (((phyreg >> 2) & 0x1) != 0x1)
{
/* 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)
{
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); // 热插拔上线时调用
// if (tcp_echo_flags_ble1 == 2)
// {
// tcp_echo_init(); // 热插拔上线时调用
// // uart_lcd_draw_ipaddr(); // 初始化显示IP地址信息
// tcp_echo_flags_ble1 = 0;
// }
}
vTaskDelay(1000);
// osThreadTerminate(NULL);
}
/* 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_dac_task */
/**
* @brief Function implementing the dac_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_dac_task */
void start_dac_task(void const *argument)
{
/* USER CODE BEGIN start_dac_task */
dac161s997_init();
/* Infinite loop */
for (;;)
{
osThreadSuspend(adc_taskHandle); // 暂停ADC任务防止DAC采集时产生干????????,因为ADC和DAC采用的是同一路SPI但是时序不????????
dac161s997_output(DAC161S997_1, current_buff[0]);
dac161s997_output(DAC161S997_2, current_buff[1]);
osThreadResume(adc_taskHandle);
vTaskDelay(100);
}
/* USER CODE END start_dac_task */
}
/* USER CODE BEGIN Header_start_adc_task */
/**
* @brief Function implementing the adc_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_adc_task */
void start_adc_task(void const *argument)
{
/* USER CODE BEGIN start_adc_task */
ad7124_setup();
/* Infinite loop */
for (;;)
{
osThreadSuspend(dac_taskHandle); // 暂停DAC任务防止ADC采集时产生干????????,因为ADC和DAC采用的是同一路SPI但是时序不????????
uint8_t ch = 0;
for (ch = STOP_NC_ADC; ch < AD7124_CHANNEL_EN_MAX; ch++)
{
ad7124_get_analog(ch);
}
communication_reset_hart();
osThreadResume(dac_taskHandle);
vTaskDelay(10);
}
/* USER CODE END start_adc_task */
}
/* USER CODE BEGIN Header_start_gpio_di_do_task */
/**
* @brief Function implementing the gpio_di_do_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_gpio_di_do_task */
void start_gpio_di_do_task(void const *argument)
{
/* USER CODE BEGIN start_gpio_di_do_task */
/* Infinite loop */
for (;;)
{
user_gpio_trigger();
vTaskDelay(100);
}
/* USER CODE END start_gpio_di_do_task */
}
/* USER CODE BEGIN Header_start_ec11_task */
/**
* @brief Function implementing the ec11_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_ec11_task */
void start_ec11_task(void const *argument)
{
/* USER CODE BEGIN start_ec11_task */
/* Infinite loop */
for (;;)
{
linear_encoder_get_data();
uart_lcd_ec11_control_current();
uart_forwarding_tcp();
vTaskDelay(10);
}
/* USER CODE END start_ec11_task */
}
/* USER CODE BEGIN Header_start_ad7124_test_task */
/**
* @brief Function implementing the ad7124_test_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_ad7124_test_task */
// 添加全局变量用于Watch窗口观察
volatile int32_t g_adc_data = 0;
volatile int32_t g_adc_error = 0;
volatile uint8_t g_adc_state = 0; // 0:初始化 1:配置通道 2:等待转换 3:读取数据 4:组包 5:发送
volatile uint16_t g_channel_config = 0; // 用于观察通道配置值
volatile uint16_t g_channel_status = 0; // 用于观察通道状态
volatile uint16_t g_adc_control = 0; // 用于观察ADC控制寄存器
volatile uint16_t g_config_0 = 0; // 用于观察配置寄存器0
volatile uint32_t g_filter_0 = 0; // 用于观察滤波器配置
extern int32_t g_ad7124_id;
void start_ad7124_test_task(const void *argument)
{
int32_t ret;
// 等待系统稳定
vTaskDelay(1000);
g_adc_state = 0;
// 初始化AD7124
ret = ad7124_setup();
// 读取关键寄存器值
ret = ad7124_read_register(&ad7124_regs[AD7124_ADC_CONTROL]);
if (ret >= 0) {
g_adc_control = ad7124_regs[AD7124_ADC_CONTROL].value;
}
ret = ad7124_read_register(&ad7124_regs[AD7124_CONFIG_0]);
if (ret >= 0) {
g_config_0 = ad7124_regs[AD7124_CONFIG_0].value;
}
ret = ad7124_read_register(&ad7124_regs[AD7124_FILTER_0]);
if (ret >= 0) {
g_filter_0 = ad7124_regs[AD7124_FILTER_0].value;
}
// 只测试通道1
uint8_t ch = 0; // 假设通道1索引为0如有不同请调整
while(1)
{
// 配置通道1
g_adc_state = 1;
g_channel_config = ad7124_channel_regs[ch].value; // 记录通道配置值
ad7124_regs[AD7124_CHANNEL_0].value = ad7124_channel_regs[ch].value;
ret = ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
if (ret < 0) {
g_adc_error = ret;
vTaskDelay(500);
continue;
}
// 读取通道状态寄存器
ret = ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
if (ret >= 0) {
g_channel_status = ad7124_regs[AD7124_STATUS].value;
}
// 等待转换完成,设置较短的超时时间
g_adc_state = 2;
ret = ad7124_wait_for_conv_ready(100); // 100ms超时
if (ret < 0) {
g_adc_error = ret;
vTaskDelay(500);
continue;
}
// 读取数据
g_adc_state = 3;
g_adc_data = ad7124_read_data();
g_adc_error = 0; // 清除错误标志
g_adc_state = 4;
// 组包4字节大端
uint8_t tx_buf[4];
tx_buf[0] = (g_adc_data >> 24) & 0xFF;
tx_buf[1] = (g_adc_data >> 16) & 0xFF;
tx_buf[2] = (g_adc_data >> 8) & 0xFF;
tx_buf[3] = g_adc_data & 0xFF;
g_adc_state = 5;
// 发送数据
//user_send_data_control(tx_buf, 4);
// 固定延时
vTaskDelay(500);
}
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */