controller-pcba/Core/Src/freertos.c

526 lines
17 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);
void ad7124_multi_channel_init(uint8_t sample_rate);
void start_adc_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);
osThreadDef(adc_task, start_adc_task, osPriorityBelowNormal, 0, 128);
adc_taskHandle = osThreadCreate(osThread(adc_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 = AI_IN0_ADC; ch < AD7124_CHANNEL_EN_MAX; ch++)
{
ad7124_get_analog(ch);
}
//communication_reset_hart();
//osThreadResume(dac_taskHandle);
vTaskDelay(100);
}
/* 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)
// {
// vTaskDelay(1000);
// // 初始化AD7124
// ad7124_setup();
// vTaskDelay(100);
// while(1)
// {
// // 遍历所有启用的通道
// for(uint8_t ch = STOP_NC_ADC; ch < AD7124_CHANNEL_EN_MAX; ch++)
// {
// // 1. 将ADC设置为掉电模式
// ad7124_regs[AD7124_ADC_CONTROL].value = 0x0600; // Power-down mode
// ad7124_write_register(&ad7124_regs[AD7124_ADC_CONTROL]);
// vTaskDelay(1);
// // 2. 配置当前通道
// ad7124_regs[AD7124_CHANNEL_0].value = ad7124_channel_regs[ch].value;
// ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0]);
// // 3. 读取并保存通道配置状态
// ad7124_read_register(&ad7124_regs[AD7124_CHANNEL_0]);
// g_channel_config = ad7124_regs[AD7124_CHANNEL_0].value;
// // 4. 设置为单次转换模式并启动转换
// ad7124_regs[AD7124_ADC_CONTROL].value = 0x0684; // Single conversion mode
// ad7124_write_register(&ad7124_regs[AD7124_ADC_CONTROL]);
// // 5. 立即读取状态寄存器确认转换开始
// ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
// g_channel_status = ad7124_regs[AD7124_STATUS].value;
// // 6. 等待转换完成
// uint16_t timeout = 1000;
// while(timeout--) {
// int32_t ret = ad7124_read_register(&ad7124_regs[AD7124_STATUS]);
// if(ret >= 0) {
// g_channel_status = ad7124_regs[AD7124_STATUS].value;
// if(!(g_channel_status & AD7124_STATUS_REG_RDY)) {
// // 转换完成,立即读取数据
// g_adc_data = ad7124_read_data();
// break;
// }
// }
// vTaskDelay(1);
// }
// // 7. 读取错误寄存器检查是否有错误
// ad7124_read_register(&ad7124_regs[AD7124_ERROR]);
// g_adc_error = ad7124_regs[AD7124_ERROR].value;
// // 8. 保存最终的控制寄存器状态
// ad7124_read_register(&ad7124_regs[AD7124_ADC_CONTROL]);
// g_adc_control = ad7124_regs[AD7124_ADC_CONTROL].value;
// // 9. 如果发生错误重置ADC
// if(g_adc_error != 0) {
// ad7124_reset();
// vTaskDelay(100);
// ad7124_setup();
// vTaskDelay(10);
// }
// // 10. 如果超时或出错,增加延时方便调试
// if(timeout == 0 || g_adc_error != 0) {
// vTaskDelay(100);
// }
// }
// vTaskDelay(pdMS_TO_TICKS(10));
// }
// }
/**
* @brief Initialize AD7124 with multiple channels
* @param sample_rate: Sample rate selection (2Hz to 1kHz)
* @retval None
*/
// void ad7124_multi_channel_init(uint8_t sample_rate)
// {
// // Reset AD7124
// ad7124_reset();
// vTaskDelay(pdMS_TO_TICKS(100)); // 复位后延时
// // 配置ADC控制寄存器
// ad7124_regs[AD7124_ADC_CONTROL].value =
// AD7124_ADC_CTRL_REG_DATA_STATUS | // Enable status register
// AD7124_ADC_CTRL_REG_CS_EN | // Enable chip select
// AD7124_ADC_CTRL_REG_REF_EN | // Enable internal reference
// AD7124_ADC_CTRL_REG_POWER_MODE(3); // Full power mode
// ad7124_write_register(&ad7124_regs[AD7124_ADC_CONTROL]);
// // 配置Setup 0
// ad7124_regs[AD7124_CONFIG_0].value =
// AD7124_CFG_REG_BIPOLAR | // Bipolar mode
// AD7124_CFG_REG_BURNOUT(0) | // Burnout current source off
// AD7124_CFG_REG_REF_BUFP | // Reference buffer positive enabled
// AD7124_CFG_REG_REF_BUFM | // Reference buffer negative enabled
// AD7124_CFG_REG_AIN_BUFP | // Enable positive input buffer
// AD7124_CFG_REG_AINN_BUFM | // Enable negative input buffer
// AD7124_CFG_REG_REF_SEL(2) | // Use internal reference
// AD7124_CFG_REG_PGA(0); // Gain = 1
// ad7124_write_register(&ad7124_regs[AD7124_CONFIG_0]);
// // 初始禁用所有通道
// for(uint8_t ch = 0; ch < AD7124_CHANNEL_EN_MAX; ch++) {
// ad7124_regs[AD7124_CHANNEL_0 + ch].value = 0;
// ad7124_write_register(&ad7124_regs[AD7124_CHANNEL_0 + ch]);
// }
// // 配置滤波器
// ad7124_regs[AD7124_FILTER_0].value =
// AD7124_FILT_REG_FILTER(0) | // SINC4 filter
// AD7124_FILT_REG_REJ60 | // Enable 60Hz rejection
// AD7124_FILT_REG_POST_FILTER(3) | // Post filter enabled
// AD7124_FILT_REG_FS(1); // Output data rate
// ad7124_write_register(&ad7124_regs[AD7124_FILTER_0]);
// }
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
// void start_adc_task(void const *argument)
// {
// /* USER CODE BEGIN start_adc_task */
// ad7124_setup();
// /* Infinite loop */
// for (;;)
// {
// osThreadSuspend(dac_taskHandle); // 暂停DAC任务防止ADC采集时产生干<E7949F>????????,因为ADC和DAC采用的是同一路SPI但是时序不<E5BA8F>????????
// 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 END Application */