diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index 244a967..b941219 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -567,63 +567,19 @@ void test_tca6416_task(void const *argument) tca6416_test_step = 1; tca6416_init_result = TCA6416_Init(); - if(tca6416_init_result != 0) - { - // 初始化失败,停留在此步骤 - tca6416_error_count++; - while(1) - { - osDelay(1000); - } - } - // 步骤2: 初始化第二个TCA6416芯片(地址0x21) tca6416_test_step = 2; tca6416_init2_result = TCA6416_Init2(); - if(tca6416_init2_result != 0) - { - tca6416_error_count++; - // 继续执行,不阻塞 - } - // 步骤3: 初始化第三个TCA6416芯片(地址0x20,第二条总线) tca6416_test_step = 3; tca6416_init3_result = TCA6416_Init3(); - if(tca6416_init3_result != 0) - { - tca6416_error_count++; - // 继续执行,不阻塞 - } - - // 步骤4: 配置第一个芯片所有IO为输出模式并置高电平 - tca6416_test_step = 4; - - // 设置Port0和Port1为输出(0=输出,1=输入) + // 设置第一个芯片Port0和Port1为输出(0=输出,1=输入) + // 注意:输出状态由tcpecho_recv_control控制,这里只设置方向 ret = TCA6416_SetPortDirection(0, 0x00); // Port0全部设为输出 - if(ret != 0) - { - tca6416_error_count++; - tca6416_i2c_ack_status = ret; - } osDelay(10); - ret = TCA6416_SetPortDirection(1, 0x00); // Port1全部设为输出 - if(ret != 0) - { - tca6416_error_count++; - tca6416_i2c_ack_status = ret; - } - osDelay(10); - - // 将第一个芯片所有IO置为高电平 - ret = TCA6416_WritePort(0, 0xFF); - if(ret == 0) tca6416_port0_status = 0xFF; - osDelay(10); - - ret = TCA6416_WritePort(1, 0xFF); - if(ret == 0) tca6416_port1_status = 0xFF; osDelay(10); // 步骤5: 配置第二、三个芯片所有IO为输入模式 @@ -652,13 +608,7 @@ void test_tca6416_task(void const *argument) for(;;) { - // 刷新第一个芯片的输出状态 - TCA6416_WritePort(0, 0xFF); - osDelay(10); - TCA6416_WritePort(1, 0xFF); - osDelay(10); - - // 读取第一个芯片状态 + // 读取第一个芯片状态(由tcpecho_recv_control控制输出) if(TCA6416_ReadPort(0, &tca6416_read_data) == 0) { tca6416_port0_status = tca6416_read_data; diff --git a/Public/PCBA测试需求说明书 V1.1.docx b/Public/PCBA测试需求说明书 V1.1.docx index f5ab83c..03c2000 100644 Binary files a/Public/PCBA测试需求说明书 V1.1.docx and b/Public/PCBA测试需求说明书 V1.1.docx differ diff --git a/Public/~WRL3372.tmp b/Public/~WRL3372.tmp new file mode 100644 index 0000000..f5ab83c Binary files /dev/null and b/Public/~WRL3372.tmp differ diff --git a/User/application/inc/TCA6416.h b/User/application/inc/TCA6416.h index 7ea8028..2aa8f2d 100644 --- a/User/application/inc/TCA6416.h +++ b/User/application/inc/TCA6416.h @@ -5,18 +5,21 @@ #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) -#define TCA6416_ADDR2 0x21 // 第二个芯片地址 (A0=1, A1=A2=GND) +#define TCA6416_ADDR 0x20 // 第一个芯片地址 (A0=A1=A2=GND)单独总线,SDA PE3 SCL PE4 +#define TCA6416_ADDR2 0x21 // 第二个芯片地址 (A0=1, A1=A2=GND)与TCA6416_ADDR3共用总线,SDA PE4 SCL PE5 #define TCA6416_ADDR3 0x20 // 第三个芯片地址 (与第二个芯片共用总线,地址0x20) @@ -66,7 +69,7 @@ #define SDA_READ2() HAL_GPIO_ReadPin(TCA6416_SDA_PORT2, TCA6416_SDA_PIN2) /* 函数声明 */ -void TCA6416_GPIO_Init(void); + uint8_t TCA6416_Init(void); uint8_t TCA6416_Init2(void); // 第二个芯片的初始化函数 uint8_t TCA6416_Init3(void); // 第三个芯片的初始化函数 @@ -100,5 +103,7 @@ uint8_t I2C_SendByte(uint8_t byte); // 修正返回值类型 void I2C_SendByte2(uint8_t byte); // 第二个芯片的发送字节 uint8_t I2C_ReadByte(void); uint8_t I2C_ReadByte2(void); // 第二个芯片的读取字节 +void TCA6416_GPIO_Init(void); +void TCA6416_GPIO_Init2(void); // 第二个芯片的I2C初始化 #endif /* __TCA6416_H */ diff --git a/User/application/src/TCA6416.c b/User/application/src/TCA6416.c index 17d245e..ba9232a 100644 --- a/User/application/src/TCA6416.c +++ b/User/application/src/TCA6416.c @@ -5,6 +5,7 @@ /** * @brief 初始化TCA6416的GPIO */ +//第一条IIC总线初始化 void TCA6416_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -12,20 +13,34 @@ void TCA6416_GPIO_Init(void) // 使能GPIOE时钟 __HAL_RCC_GPIOE_CLK_ENABLE(); - // 配置第一个芯片的SCL和SDA引脚为开漏输出 + //两个芯片挂一条总线上SDA PE3 SCL PE2 GPIO_InitStruct.Pin = TCA6416_SCL_PIN | TCA6416_SDA_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出 GPIO_InitStruct.Pull = GPIO_NOPULL; // 无内部上拉,依赖外部上拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - HAL_GPIO_Init(TCA6416_SCL_PORT, &GPIO_InitStruct); - - // 配置第二个芯片的SCL和SDA引脚为开漏输出 - GPIO_InitStruct.Pin = TCA6416_SCL_PIN2 | TCA6416_SDA_PIN2; - HAL_GPIO_Init(TCA6416_SCL_PORT2, &GPIO_InitStruct); + HAL_GPIO_Init(TCA6416_SDA_PORT, &GPIO_InitStruct); // 初始状态设为高电平(实际由外部上拉电阻拉高) SCL_HIGH(); SDA_HIGH(); + +} +//第二条IIC总线初始化 +void TCA6416_GPIO_Init2(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // 使能GPIOE时钟 + __HAL_RCC_GPIOE_CLK_ENABLE(); + + //两个芯片挂一条总线上SDA PE4 SCL PE5 + GPIO_InitStruct.Pin = TCA6416_SCL_PIN2 | TCA6416_SDA_PIN2; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出 + GPIO_InitStruct.Pull = GPIO_NOPULL; // 无内部上拉,依赖外部上拉 + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(TCA6416_SDA_PORT2, &GPIO_InitStruct); + + // 初始状态设为高电平(实际由外部上拉电阻拉高) SCL_HIGH2(); SDA_HIGH2(); } @@ -421,7 +436,7 @@ uint8_t I2C_ReadByte2(void) uint8_t TCA6416_Init2(void) { // 初始化GPIO - TCA6416_GPIO_Init(); + TCA6416_GPIO_Init2(); // 增加延时以确保设备稳定 HAL_Delay(10); diff --git a/User/application/src/tcpserverc.c b/User/application/src/tcpserverc.c index a2ad95e..fb8c36a 100644 --- a/User/application/src/tcpserverc.c +++ b/User/application/src/tcpserverc.c @@ -19,6 +19,9 @@ #include "tim.h" #include "ad7124.h" #include "tca6416_status.h" // 添加TCA6416状态头文件 +#include "DAC8568.h" // 添加DAC8568头文件 +#include "dac161s997.h" // 添加DAC161S997头文件 +#include "TCA6416.h" // 添加TCA6416头文件 // 添加test_adc_read_data变量定义 uint8_t test_adc_read_data[74] = {0}; // 74字节的测试数据缓冲区 @@ -349,7 +352,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 + 22 + 2; // 帧头+帧长+源+目标+类型+22字节输出读取+校验 +uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 24 + 2; // 帧头+帧长+源+目标+类型+24字节输出读取+校验 // 帧头 tx[0] = head_00; @@ -371,11 +374,11 @@ uint16_t total_len = 2 + 2 + 2 + 2 + 1 + 22 + 2; // 帧头+帧长+源+目标+类 tx[8] = reply_type; // 7字节使能状态(直接复制 body 到 tx[9]~tx[15]) - memcpy(&tx[9], body, 22); // 确保 body 是22字节 + memcpy(&tx[9], body, 24); // 确保 body 是24字节 // 校验和 uint16_t checksum = 0; - for (int i = 4; i < 32; ++i) // 4~31(源地址+目标地址+类型+22字节) + for (int i = 4; i < 28; ++i) // 4~27(源地址+目标地址+类型+24字节) { checksum += tx[i]; } @@ -647,8 +650,8 @@ static err_t tcpecho_recv_ble2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, static err_t tcpecho_recv_control(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { - uint8_t tcp_rx_data[128] = {0}; - uint8_t tcp_tx_data[128] = {0}; + uint8_t tcp_rx_data[256] = {0}; + uint8_t tcp_tx_data[256] = {0}; uint8_t rx_data_len = 0; uint8_t tx_data_len = 0; @@ -722,7 +725,63 @@ static err_t tcpecho_recv_control(void *arg, struct tcp_pcb *tpcb, struct pbuf * break; case 0x86://设置配置参数 { - uint16_t body_len = 22; //22个字节表示的是设置的参数 + 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; + + // 处理DAC8568的8个通道输出 + // 通道A (CH0) + dac_value = (tcp_rx_data[9] << 8) | tcp_rx_data[10]; + DAC8568_WriteAndUpdate(CHANNEL_A, dac_value); + + // 通道B (CH4) + dac_value = (tcp_rx_data[11] << 8) | tcp_rx_data[12]; + DAC8568_WriteAndUpdate(CHANNEL_B, dac_value); + + // 通道C (CH1) + dac_value = (tcp_rx_data[13] << 8) | tcp_rx_data[14]; + DAC8568_WriteAndUpdate(CHANNEL_C, dac_value); + + // 通道D (CH5) + dac_value = (tcp_rx_data[15] << 8) | tcp_rx_data[16]; + DAC8568_WriteAndUpdate(CHANNEL_D, dac_value); + + // 通道E (CH2) + dac_value = (tcp_rx_data[17] << 8) | tcp_rx_data[18]; + DAC8568_WriteAndUpdate(CHANNEL_E, dac_value); + + // 通道F (CH6) + dac_value = (tcp_rx_data[19] << 8) | tcp_rx_data[20]; + DAC8568_WriteAndUpdate(CHANNEL_F, dac_value); + + // 通道G (CH3) + dac_value = (tcp_rx_data[21] << 8) | tcp_rx_data[22]; + DAC8568_WriteAndUpdate(CHANNEL_G, dac_value); + + // 通道H (CH7) + dac_value = (tcp_rx_data[23] << 8) | tcp_rx_data[24]; + DAC8568_WriteAndUpdate(CHANNEL_H, dac_value); + + //HART电流输出 + dac161s_value = (tcp_rx_data[25] << 8) | tcp_rx_data[26]; + dac161s997_output(DAC161S997, dac161s_value); + + //比例阀 + //tcp_rx_data[27] + //tcp_rx_data[28] + //tcp_rx_data[29] + //tcp_rx_data[30] + + // 数字量输出刷新第一个芯片的输出状态 + TCA6416_WritePort(0, tcp_rx_data[31]); // 直接写入Port0的值8-15 + osDelay(10); + TCA6416_WritePort(1, tcp_rx_data[32]); // 写入Port1的值0-7 + osDelay(10); + + // 保存设置的数据到adc_set_data数组 + memcpy(adc_set_data, tcp_rx_data + 9, body_len); + reply_type = tcp_rx_data[8]; tx_data_len = handle_type_86(adc_set_data, body_len, tcp_tx_data); }