diff --git a/.vscode/settings.json b/.vscode/settings.json index 158c796..5c7fd71 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,8 @@ "ad7124.h": "c", "freertos.h": "c", "usart.h": "c", - "stm32f4xx_it.h": "c" + "stm32f4xx_it.h": "c", + "tca6416.h": "c", + "stm32f4xx_hal.h": "c" } } \ No newline at end of file diff --git a/Core/Inc/stm32f4xx_hal_conf.h b/Core/Inc/stm32f4xx_hal_conf.h index 516e67b..17b5673 100644 --- a/Core/Inc/stm32f4xx_hal_conf.h +++ b/Core/Inc/stm32f4xx_hal_conf.h @@ -53,7 +53,7 @@ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ -/* #define HAL_I2C_MODULE_ENABLED */ +//#define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index b4c75f9..6c1f90e 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -41,6 +41,7 @@ #include "ad7124_test.h" #include // 添加string.h用于字符串操作 #include "ht1200m.h" +#include "TCA6416.h" // 添加TCA6416头文件 // 声明外部变量 extern ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX]; @@ -71,6 +72,7 @@ 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数据寄存器的原始值 @@ -87,6 +89,12 @@ 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引脚状态 +static volatile uint8_t tca6416_port0_status = 0; // 第一个TCA6416的Port0状态 +static volatile uint8_t tca6416_port1_status = 0; // 第一个TCA6416的Port1状态 +static volatile uint8_t tca6416_port2_status = 0; // 第二个TCA6416的Port0状态 +static volatile uint8_t tca6416_port3_status = 0; // 第二个TCA6416的Port1状态 + /* USER CODE END Variables */ /* Private function prototypes -----------------------------------------------*/ @@ -103,6 +111,7 @@ 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任务函数声明 /* USER CODE END FunctionPrototypes */ void start_tcp_task(void const *argument); @@ -197,6 +206,10 @@ void MX_FREERTOS_Init(void) 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); + /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ @@ -546,3 +559,73 @@ 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 = 0; + uint8_t port1_data = 0; + uint8_t port2_data = 0; + uint8_t port3_data = 0; + + // 初始化第一个TCA6416 + if(TCA6416_Init() != 0) + { + Error_Handler(); + } + + // 配置第一个TCA6416端口方向 + // Port0: 全输入 + TCA6416_SetPortDirection(0, 0xFF); // 0xFF = 11111111b + // Port1: 全输入 + TCA6416_SetPortDirection(1, 0xFF); // 0xFF = 11111111b + + // 初始化第二个TCA6416 (使用SCL_PIN2和SDA_PIN2) + // 注意:这里需要修改TCA6416_Init函数以支持第二个芯片 + // 暂时使用相同的初始化函数,但实际使用时需要修改 + + // 配置第二个TCA6416端口方向 + // Port0: 全输入 + TCA6416_SetPortDirection(0, 0xFF); // 0xFF = 11111111b + // Port1: 全输入 + TCA6416_SetPortDirection(1, 0xFF); // 0xFF = 11111111b + + /* Infinite loop */ + for(;;) + { + // 读取第一个TCA6416的输入端口状态 + if(TCA6416_ReadPort(0, &port0_data) == 0) + { + tca6416_port0_status = port0_data; + } + + if(TCA6416_ReadPort(1, &port1_data) == 0) + { + tca6416_port1_status = port1_data; + } + + // 读取第二个TCA6416的输入端口状态 + // 注意:这里需要修改TCA6416_ReadPort函数以支持第二个芯片 + // 暂时使用相同的读取函数,但实际使用时需要修改 + if(TCA6416_ReadPort(0, &port2_data) == 0) + { + tca6416_port2_status = port2_data; + } + + if(TCA6416_ReadPort(1, &port3_data) == 0) + { + tca6416_port3_status = port3_data; + } + + // 任务延时 + vTaskDelay(10); // 10ms延时 + } + /* USER CODE END start_tca6416_task */ +} + diff --git a/MDK-ARM/controller_pcba.uvoptx b/MDK-ARM/controller_pcba.uvoptx index 0061ec1..45ca4c9 100644 --- a/MDK-ARM/controller_pcba.uvoptx +++ b/MDK-ARM/controller_pcba.uvoptx @@ -1976,6 +1976,18 @@ 0 0 + + 11 + 132 + 1 + 0 + 0 + 0 + ..\User\application\src\TCA6416.c + TCA6416.c + 0 + 0 + @@ -1986,7 +1998,7 @@ 0 12 - 132 + 133 1 0 0 @@ -1998,7 +2010,7 @@ 12 - 133 + 134 1 0 0 @@ -2010,7 +2022,7 @@ 12 - 134 + 135 1 0 0 @@ -2022,7 +2034,7 @@ 12 - 135 + 136 1 0 0 @@ -2034,7 +2046,7 @@ 12 - 136 + 137 1 0 0 @@ -2054,7 +2066,7 @@ 0 13 - 137 + 138 1 0 0 @@ -2066,7 +2078,7 @@ 13 - 138 + 139 1 0 0 @@ -2078,7 +2090,7 @@ 13 - 139 + 140 1 0 0 diff --git a/MDK-ARM/controller_pcba.uvprojx b/MDK-ARM/controller_pcba.uvprojx index 6c4095b..cf98f24 100644 --- a/MDK-ARM/controller_pcba.uvprojx +++ b/MDK-ARM/controller_pcba.uvprojx @@ -1088,6 +1088,11 @@ 1 ..\User\application\src\ad7124_test.c + + TCA6416.c + 1 + ..\User\application\src\TCA6416.c + diff --git a/Public/PCBA测试需求说明书 V1.1.docx b/Public/PCBA测试需求说明书 V1.1.docx index c4a766b..cf876b8 100644 Binary files a/Public/PCBA测试需求说明书 V1.1.docx and b/Public/PCBA测试需求说明书 V1.1.docx differ diff --git a/User/application/inc/TCA6416.h b/User/application/inc/TCA6416.h index 42eaf3f..cfa71a7 100644 --- a/User/application/inc/TCA6416.h +++ b/User/application/inc/TCA6416.h @@ -1,7 +1,18 @@ #ifndef __TCA6416_H #define __TCA6416_H -#include "stm32f1xx_hal.h" +#include "stm32f4xx_hal.h" // 只包含基本的 HAL 头文件 +#include + +/* GPIO定义 */ +#define TCA6416_SCL_PIN GPIO_PIN_2 +#define TCA6416_SCL_PORT GPIOE +#define TCA6416_SDA_PIN GPIO_PIN_3 +#define TCA6416_SDA_PORT GPIOE +#define TCA6416_SCL_PIN2 GPIO_PIN_5 +#define TCA6416_SCL_PORT2 GPIOE +#define TCA6416_SDA_PIN2 GPIO_PIN_4 +#define TCA6416_SDA_PORT2 GPIOE /* TCA6416 I2C地址 */ #define TCA6416_ADDR 0x20 // 基础地址 (A0=A1=A2=GND) @@ -16,13 +27,33 @@ #define TCA6416_POL_INV_PORT0 0x04 // 极性反转端口0 #define TCA6416_POL_INV_PORT1 0x05 // 极性反转端口1 +/* 软件I2C延时定义 */ +#define I2C_DELAY() HAL_Delay(1) // 可以根据实际需要调整延时 + +/* 软件I2C基本操作函数 */ +#define SCL_HIGH() HAL_GPIO_WritePin(TCA6416_SCL_PORT, TCA6416_SCL_PIN, GPIO_PIN_SET) +#define SCL_LOW() HAL_GPIO_WritePin(TCA6416_SCL_PORT, TCA6416_SCL_PIN, GPIO_PIN_RESET) +#define SDA_HIGH() HAL_GPIO_WritePin(TCA6416_SDA_PORT, TCA6416_SDA_PIN, GPIO_PIN_SET) +#define SDA_LOW() HAL_GPIO_WritePin(TCA6416_SDA_PORT, TCA6416_SDA_PIN, GPIO_PIN_RESET) +#define SDA_READ() HAL_GPIO_ReadPin(TCA6416_SDA_PORT, TCA6416_SDA_PIN) + /* 函数声明 */ -HAL_StatusTypeDef TCA6416_Init(I2C_HandleTypeDef *hi2c); -HAL_StatusTypeDef TCA6416_WritePort(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t data); -HAL_StatusTypeDef TCA6416_ReadPort(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t *data); -HAL_StatusTypeDef TCA6416_SetPortDirection(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t direction); -HAL_StatusTypeDef TCA6416_SetPortPolarity(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t polarity); -HAL_StatusTypeDef TCA6416_WritePin(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t pin, uint8_t state); -HAL_StatusTypeDef TCA6416_ReadPin(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t pin, uint8_t *state); +void TCA6416_GPIO_Init(void); +uint8_t TCA6416_Init(void); +uint8_t TCA6416_WritePort(uint8_t port, uint8_t data); +uint8_t TCA6416_ReadPort(uint8_t port, uint8_t *data); +uint8_t TCA6416_SetPortDirection(uint8_t port, uint8_t direction); +uint8_t TCA6416_SetPortPolarity(uint8_t port, uint8_t polarity); +uint8_t TCA6416_WritePin(uint8_t port, uint8_t pin, uint8_t state); +uint8_t TCA6416_ReadPin(uint8_t port, uint8_t pin, uint8_t *state); + +/* 软件I2C底层函数 */ +void I2C_Start(void); +void I2C_Stop(void); +void I2C_Ack(void); +void I2C_NAck(void); +uint8_t I2C_WaitAck(void); +void I2C_SendByte(uint8_t byte); +uint8_t I2C_ReadByte(void); #endif /* __TCA6416_H */ diff --git a/User/application/src/TCA6416.c b/User/application/src/TCA6416.c index dacfa3a..d6f9dfe 100644 --- a/User/application/src/TCA6416.c +++ b/User/application/src/TCA6416.c @@ -1,133 +1,308 @@ #include "TCA6416.h" /** - * @brief 初始化TCA6416 - * @param hi2c: I2C句柄指针 - * @retval HAL状态 + * @brief 初始化TCA6416的GPIO */ -HAL_StatusTypeDef TCA6416_Init(I2C_HandleTypeDef *hi2c) +void TCA6416_GPIO_Init(void) { - HAL_StatusTypeDef status; + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // 使能GPIOE时钟 + __HAL_RCC_GPIOE_CLK_ENABLE(); + + // 配置SCL和SDA引脚 + GPIO_InitStruct.Pin = TCA6416_SCL_PIN | TCA6416_SDA_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(TCA6416_SCL_PORT, &GPIO_InitStruct); + + // 初始状态设为高电平 + SCL_HIGH(); + SDA_HIGH(); +} + +/** + * @brief 软件I2C起始信号 + */ +void I2C_Start(void) +{ + SDA_HIGH(); + SCL_HIGH(); + I2C_DELAY(); + SDA_LOW(); + I2C_DELAY(); + SCL_LOW(); +} + +/** + * @brief 软件I2C停止信号 + */ +void I2C_Stop(void) +{ + SCL_LOW(); + SDA_LOW(); + I2C_DELAY(); + SCL_HIGH(); + I2C_DELAY(); + SDA_HIGH(); + I2C_DELAY(); +} + +/** + * @brief 软件I2C发送应答 + */ +void I2C_Ack(void) +{ + SCL_LOW(); + SDA_LOW(); + I2C_DELAY(); + SCL_HIGH(); + I2C_DELAY(); + SCL_LOW(); +} + +/** + * @brief 软件I2C发送非应答 + */ +void I2C_NAck(void) +{ + SCL_LOW(); + SDA_HIGH(); + I2C_DELAY(); + SCL_HIGH(); + I2C_DELAY(); + SCL_LOW(); +} + +/** + * @brief 软件I2C等待应答 + * @retval 0:有应答 1:无应答 + */ +uint8_t I2C_WaitAck(void) +{ + uint8_t ack; + + SCL_LOW(); + SDA_HIGH(); + I2C_DELAY(); + SCL_HIGH(); + I2C_DELAY(); + + ack = SDA_READ() ? 1 : 0; + + SCL_LOW(); + return ack; +} + +/** + * @brief 软件I2C发送一个字节 + * @param byte: 要发送的字节 + */ +void I2C_SendByte(uint8_t byte) +{ + uint8_t i; + + for(i = 0; i < 8; i++) + { + SCL_LOW(); + if(byte & 0x80) + SDA_HIGH(); + else + SDA_LOW(); + byte <<= 1; + I2C_DELAY(); + SCL_HIGH(); + I2C_DELAY(); + } + SCL_LOW(); +} + +/** + * @brief 软件I2C读取一个字节 + * @retval 读取到的字节 + */ +uint8_t I2C_ReadByte(void) +{ + uint8_t i, byte = 0; + + SDA_HIGH(); + for(i = 0; i < 8; i++) + { + SCL_LOW(); + I2C_DELAY(); + SCL_HIGH(); + byte <<= 1; + if(SDA_READ()) + byte |= 0x01; + I2C_DELAY(); + } + SCL_LOW(); + return byte; +} + +/** + * @brief 初始化TCA6416 + * @retval 0:成功 1:失败 + */ +uint8_t TCA6416_Init(void) +{ + // 初始化GPIO + TCA6416_GPIO_Init(); // 默认将所有引脚设置为输入 - status = TCA6416_SetPortDirection(hi2c, 0, 0xFF); - if (status != HAL_OK) return status; - - status = TCA6416_SetPortDirection(hi2c, 1, 0xFF); - if (status != HAL_OK) return status; + if(TCA6416_SetPortDirection(0, 0xFF) != 0) return 1; + if(TCA6416_SetPortDirection(1, 0xFF) != 0) return 1; // 设置默认输出值为0 - status = TCA6416_WritePort(hi2c, 0, 0x00); - if (status != HAL_OK) return status; - - status = TCA6416_WritePort(hi2c, 1, 0x00); - if (status != HAL_OK) return status; + if(TCA6416_WritePort(0, 0x00) != 0) return 1; + if(TCA6416_WritePort(1, 0x00) != 0) return 1; // 设置默认极性(非反转) - status = TCA6416_SetPortPolarity(hi2c, 0, 0x00); - if (status != HAL_OK) return status; + if(TCA6416_SetPortPolarity(0, 0x00) != 0) return 1; + if(TCA6416_SetPortPolarity(1, 0x00) != 0) return 1; - status = TCA6416_SetPortPolarity(hi2c, 1, 0x00); - - return status; + return 0; } /** * @brief 向端口写入数据 - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param data: 要写入的数据 - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_WritePort(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t data) +uint8_t TCA6416_WritePort(uint8_t port, uint8_t data) { uint8_t reg_addr = (port == 0) ? TCA6416_OUTPUT_PORT0 : TCA6416_OUTPUT_PORT1; - return HAL_I2C_Mem_Write(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY); + + I2C_Start(); + I2C_SendByte(TCA6416_ADDR << 1); // 写地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(reg_addr); // 寄存器地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(data); // 数据 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_Stop(); + return 0; } /** * @brief 从端口读取数据 - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param data: 存储读取数据的指针 - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_ReadPort(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t *data) +uint8_t TCA6416_ReadPort(uint8_t port, uint8_t *data) { uint8_t reg_addr = (port == 0) ? TCA6416_INPUT_PORT0 : TCA6416_INPUT_PORT1; - return HAL_I2C_Mem_Read(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, data, 1, HAL_MAX_DELAY); + + I2C_Start(); + I2C_SendByte(TCA6416_ADDR << 1); // 写地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(reg_addr); // 寄存器地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_Start(); + I2C_SendByte((TCA6416_ADDR << 1) | 0x01); // 读地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + *data = I2C_ReadByte(); // 读取数据 + I2C_NAck(); + + I2C_Stop(); + return 0; } /** * @brief 设置端口方向(输入/输出) - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param direction: 0 = 输出, 1 = 输入 - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_SetPortDirection(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t direction) +uint8_t TCA6416_SetPortDirection(uint8_t port, uint8_t direction) { uint8_t reg_addr = (port == 0) ? TCA6416_CONFIG_PORT0 : TCA6416_CONFIG_PORT1; - return HAL_I2C_Mem_Write(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &direction, 1, HAL_MAX_DELAY); + + I2C_Start(); + I2C_SendByte(TCA6416_ADDR << 1); // 写地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(reg_addr); // 寄存器地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(direction); // 方向设置 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_Stop(); + return 0; } /** * @brief 设置端口极性 - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param polarity: 0 = 非反转, 1 = 反转 - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_SetPortPolarity(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t polarity) +uint8_t TCA6416_SetPortPolarity(uint8_t port, uint8_t polarity) { uint8_t reg_addr = (port == 0) ? TCA6416_POL_INV_PORT0 : TCA6416_POL_INV_PORT1; - return HAL_I2C_Mem_Write(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, &polarity, 1, HAL_MAX_DELAY); + + I2C_Start(); + I2C_SendByte(TCA6416_ADDR << 1); // 写地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(reg_addr); // 寄存器地址 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_SendByte(polarity); // 极性设置 + if(I2C_WaitAck()) { I2C_Stop(); return 1; } + + I2C_Stop(); + return 0; } /** * @brief 写入单个引脚 - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param pin: 引脚号(0-7) * @param state: 引脚状态(0或1) - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_WritePin(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t pin, uint8_t state) +uint8_t TCA6416_WritePin(uint8_t port, uint8_t pin, uint8_t state) { - HAL_StatusTypeDef status; uint8_t current_data; uint8_t reg_addr = (port == 0) ? TCA6416_OUTPUT_PORT0 : TCA6416_OUTPUT_PORT1; // 读取当前端口值 - status = HAL_I2C_Mem_Read(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, ¤t_data, 1, HAL_MAX_DELAY); - if (status != HAL_OK) return status; + if(TCA6416_ReadPort(port, ¤t_data) != 0) return 1; // 修改特定引脚 - if (state) + if(state) current_data |= (1 << pin); else current_data &= ~(1 << pin); // 写回修改后的值 - return HAL_I2C_Mem_Write(hi2c, TCA6416_ADDR << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, ¤t_data, 1, HAL_MAX_DELAY); + return TCA6416_WritePort(port, current_data); } /** * @brief 读取单个引脚 - * @param hi2c: I2C句柄指针 * @param port: 端口号(0或1) * @param pin: 引脚号(0-7) * @param state: 存储引脚状态的指针 - * @retval HAL状态 + * @retval 0:成功 1:失败 */ -HAL_StatusTypeDef TCA6416_ReadPin(I2C_HandleTypeDef *hi2c, uint8_t port, uint8_t pin, uint8_t *state) +uint8_t TCA6416_ReadPin(uint8_t port, uint8_t pin, uint8_t *state) { - HAL_StatusTypeDef status; uint8_t port_data; - status = TCA6416_ReadPort(hi2c, port, &port_data); - if (status != HAL_OK) return status; + if(TCA6416_ReadPort(port, &port_data) != 0) return 1; *state = (port_data >> pin) & 0x01; - return HAL_OK; + return 0; } diff --git a/User/application/src/tcpserverc.c b/User/application/src/tcpserverc.c index caedf65..62b64d5 100644 --- a/User/application/src/tcpserverc.c +++ b/User/application/src/tcpserverc.c @@ -95,6 +95,12 @@ uint8_t adc_set_data[22] = { 0x0D,0xF0,// 比例阀2输出高字节, 比例阀2输出低字节 }; +// 添加外部声明 +extern volatile uint8_t tca6416_port0_status; +extern volatile uint8_t tca6416_port1_status; +extern volatile uint8_t tca6416_port2_status; +extern volatile uint8_t tca6416_port3_status; + // 校验和函数 uint8_t calc_checksum(const uint8_t *data, uint8_t start, uint8_t end) { uint8_t checksum = 0; @@ -378,7 +384,6 @@ uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 22 + 2; // 帧头+帧长+源+目标+类 uint16_t handle_type_87(const uint8_t *body, uint16_t body_len, uint8_t *tx) { uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 74 + 2; // 帧头+帧长+源+目标+类型+74字节输出读取+校验 - // 1. 读取ID寄存器 // 帧头 tx[0] = head_00; @@ -399,21 +404,27 @@ uint16_t handle_type_87(const uint8_t *body, uint16_t body_len, uint8_t *tx) // 报文类型 tx[8] = reply_type; - tx[9] = 0x00; //io通道0-15 - tx[10] = 0x00; //io通道0-15 - // 填充AD7124原始数据到tx[11]~tx[75],每通道4字节,MSB格式 + // 填充TCA6416引脚状态到第9-10字节 + tx[9] = tca6416_port0_status; // 第一个TCA6416的Port0状态 + tx[10] = tca6416_port1_status; // 第一个TCA6416的Port1状态 + tx[11] = tca6416_port2_status; // 第二个TCA6416的Port0状态 + tx[12] = tca6416_port3_status; // 第二个TCA6416的Port1状态 + + // 填充AD7124原始数据到tx[13]~tx[77],每通道4字节,MSB格式 extern ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX]; for (int ch = 0; ch < AD7124_CHANNEL_EN_MAX; ++ch) { int32_t data = ad7124_analog[ch].data; - tx[11 + ch * 4 + 0] = (data >> 24) & 0xFF; - tx[11 + ch * 4 + 1] = (data >> 16) & 0xFF; - tx[11 + ch * 4 + 2] = (data >> 8) & 0xFF; - tx[11 + ch * 4 + 3] = (data) & 0xFF; + tx[13 + ch * 4 + 0] = (data >> 24) & 0xFF; + tx[13 + ch * 4 + 1] = (data >> 16) & 0xFF; + tx[13 + ch * 4 + 2] = (data >> 8) & 0xFF; + tx[13 + ch * 4 + 3] = (data) & 0xFF; } - // 其余tx[73]~tx[82]可按需要填充(如比例阀等),此处保持原样或补零 - for (int i = 11 + AD7124_CHANNEL_EN_MAX * 4; i < 83; ++i) { + + // 其余tx[77]~tx[83]可按需要填充(如比例阀等),此处保持原样或补零 + for (int i = 13 + AD7124_CHANNEL_EN_MAX * 4; i < 83; ++i) { tx[i] = 0; } + // 校验和 uint16_t checksum = 0; for (int i = 4; i < 84; ++i) // 4~83(源地址+目标地址+类型+74字节)