controller-pcba/Core/Src/freertos.c

807 lines
24 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 "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头文件
// 声明外部变量
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 dac_taskHandle;
osThreadId adc_taskHandle;
osThreadId gpio_di_do_taskHandle;
osThreadId ec11_taskHandle;
osThreadId ad7124_test_taskHandle;
osThreadId usart6_test_taskHandle; // 添加USART6测试任务句柄
osThreadId tca6416_taskHandle; // 添加TCA6416任务句柄
// 添加调试变量
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状态
// 添加TCA6416测试相关的调试变量
volatile uint8_t tca6416_test_step = 0; // 当前测试步骤
volatile uint8_t tca6416_init_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应答状态
/* USER CODE END Variables */
/* 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);
void start_usart6_test_task(void const *argument); // 添加USART6测试任务函数声明
void start_tca6416_task(void const *argument); // 添加TCA6416任务函数声明
void test_tca6416_task(void const *argument); // 添加TCA6416测试任务函数声明
/* 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);
void test_cs_pin(void);
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);
/* HART测试任务 */
osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityNormal, 0, 128);
usart6_test_taskHandle = osThreadCreate(osThread(usart6_test_task), NULL);
/* TCA6416任务 */
//osThreadDef(tca6416_task, start_tca6416_task, osPriorityNormal, 0, 128);
// tca6416_taskHandle = osThreadCreate(osThread(tca6416_task), NULL);
/* TCA6416测试任务 */
osThreadDef(tca6416_task, test_tca6416_task, osPriorityNormal, 0, 128);
tca6416_taskHandle = osThreadCreate(osThread(tca6416_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 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_setup();
/* Infinite loop */
for (;;)
{
uint8_t ch = 0;
for (ch = AD7124_AIN0; ch < AD7124_CHANNEL_EN_MAX; ch++)
{
ad7124_get_analog(ch);
}
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 */
}
/**
* @brief Initialize AD7124 with multiple channels
* @param sample_rate: Sample rate selection (2Hz to 1kHz)
* @retval None
*/
/* USER CODE END Application */
/**
* @brief 测试CS引脚的功能
*
* 这个函数将不断地尝试拉低和拉高CS引脚并读取其状态。
* 它主要用于测试硬件连接和引脚操作的正确性。
*
* @return 无返回值
*/
void test_cs_pin(void)
{
while (1) {
ad7124_cs_on(); // 尝试拉低
GPIO_PinState state = HAL_GPIO_ReadPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin);
// 打印或观察state值应该是GPIO_PIN_RESET
HAL_Delay(100);
ad7124_cs_off(); // 尝试拉高
state = HAL_GPIO_ReadPin(SPI2_CS_GPIO_Port, SPI2_CS_Pin);
// 打印或观察state值应该是GPIO_PIN_SET
HAL_Delay(100);
}
}
/* USER CODE BEGIN Header_start_usart6_test_task */
/**
* @brief Function implementing the usart6_test_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_usart6_test_task */
// 添加UART接收回调函数声明
static void UART6_RxCpltCallback(void);
// 添加接收缓冲区
static uint8_t uart6_rx_buffer[1];
static volatile uint8_t uart6_rx_data = 0;
static volatile uint8_t uart6_rx_flag = 0;
// 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);
}
void start_usart6_test_task(void const *argument)
{
/* USER CODE BEGIN start_usart6_test_task */
uint8_t rx_buffer[1]; // 接收缓冲区
err_t err;
// 确保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();
}
/* Infinite loop */
for(;;)
{
// 直接检查接收标志
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;
// 使用数据位作为接收数据
rx_buffer[0] = uart6_data_bits;
// 检查是否有接收错误
if (uart6_error_flags == 0)
{
// 检查TCP连接状态
if (server_pcb_control != NULL && tcp_echo_flags_control == 1)
{
// 尝试发送数据
err = tcp_write(server_pcb_control, rx_buffer, 1, 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);
}
else
{
// 其他错误,关闭连接
tcp_abort(server_pcb_control);
server_pcb_control = NULL;
tcp_echo_flags_control = 0;
}
}
}
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);
}
}
vTaskDelay(1); // 给其他任务执行的机会
}
/* USER CODE END start_usart6_test_task */
}
void start_usart6_dma_test_task(void const *argument)
{
}
/* USER CODE BEGIN Header_start_tca6416_task */
/**
* @brief Function implementing the tca6416_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_start_tca6416_task */
void start_tca6416_task(void const *argument)
{
/* USER CODE BEGIN start_tca6416_task */
uint8_t port0_data, port1_data;
// 初始化第一个TCA6416
if(TCA6416_Init() != 0)
{
Error_Handler();
}
// 初始化第二个TCA6416
if(TCA6416_Init2() != 0)
{
Error_Handler();
}
// 设置两个芯片的所有端口为输入
if(TCA6416_SetPortDirection(0, 0xFF) != 0) Error_Handler();
if(TCA6416_SetPortDirection(1, 0xFF) != 0) Error_Handler();
if(TCA6416_SetPortDirection2(0, 0xFF) != 0) Error_Handler();
if(TCA6416_SetPortDirection2(1, 0xFF) != 0) Error_Handler();
for(;;)
{
// 读取第一个芯片的输入状态
if(TCA6416_ReadPort(0, &port0_data) == 0)
{
tca6416_port0_status = port0_data;
}
if(TCA6416_ReadPort(1, &port1_data) == 0)
{
tca6416_port1_status = port1_data;
}
// 读取第二个芯片的输入状态
if(TCA6416_ReadPort2(0, &port0_data) == 0)
{
tca6416_port2_status = port0_data;
}
if(TCA6416_ReadPort2(1, &port1_data) == 0)
{
tca6416_port3_status = port1_data;
}
osDelay(100); // 100ms读取一次
}
/* USER CODE END start_tca6416_task */
}
void test_tca6416_task(void const *argument)
{
/* USER CODE BEGIN test_tca6416_task */
uint8_t ret = 0;
uint8_t test_patterns[] = {0x00, 0xFF, 0xAA, 0x55, 0x0F, 0xF0, 0x5A, 0xA5};
uint8_t pattern_index = 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();
if(tca6416_init_result != 0)
{
// 初始化失败,停留在此步骤
tca6416_error_count++;
while(1)
{
osDelay(1000);
}
}
// 初始化成功,继续测试
osDelay(50);
for(;;)
{
// 步骤2: 设置Port0为输出Port1为输入
tca6416_test_step = 2;
tca6416_port0_dir = 0x00; // 0=输出
tca6416_port1_dir = 0xFF; // 1=输入
ret = TCA6416_SetPortDirection(0, tca6416_port0_dir);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
ret = TCA6416_SetPortDirection(1, tca6416_port1_dir);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
// 步骤3: 写入测试模式到Port0
tca6416_test_step = 3;
tca6416_test_pattern = test_patterns[pattern_index];
tca6416_write_data = tca6416_test_pattern;
ret = TCA6416_WritePort(0, tca6416_write_data);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
// 步骤4: 读取Port0的值验证写入
tca6416_test_step = 4;
ret = TCA6416_ReadPort(0, &tca6416_read_data);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
else
{
// 更新状态变量
tca6416_port0_status = tca6416_read_data;
}
osDelay(10);
// 步骤5: 读取Port1的输入状态
tca6416_test_step = 5;
ret = TCA6416_ReadPort(1, &tca6416_read_data);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
else
{
// 更新状态变量
tca6416_port1_status = tca6416_read_data;
}
osDelay(10);
// 步骤6: 测试单个引脚操作
tca6416_test_step = 6;
for(uint8_t pin = 0; pin < 8; pin++)
{
// 设置单个引脚为高
ret = TCA6416_WritePin(0, pin, 1);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(5);
// 读取验证
uint8_t pin_state = 0;
ret = TCA6416_ReadPin(0, pin, &pin_state);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(5);
// 设置单个引脚为低
ret = TCA6416_WritePin(0, pin, 0);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(5);
}
// 步骤7: 测试极性反转功能
tca6416_test_step = 7;
ret = TCA6416_SetPortPolarity(0, 0xFF); // 反转所有位
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
// 读取并验证极性反转效果
ret = TCA6416_ReadPort(0, &tca6416_read_data);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
// 恢复正常极性
ret = TCA6416_SetPortPolarity(0, 0x00);
if(ret != 0)
{
tca6416_error_count++;
tca6416_i2c_ack_status = ret;
}
osDelay(10);
// 切换到下一个测试模式
pattern_index = (pattern_index + 1) % (sizeof(test_patterns) / sizeof(test_patterns[0]));
// 延时后继续下一轮测试
osDelay(500);
}
/* USER CODE END test_tca6416_task */
}