/* * Protocol.c * * Created on: 2022年03月12日 * Author: User */ #include void Analysis(UART_t *UART); //协议处理 void Send(uint8_t func); //数据发送 uint8_t Sum_Check(uint8_t *arr, uint8_t Len); //求和校验 Protocol_t xdata Protocol = { Analysis, Send}; /* 协议长度为10 头帧 0A 第二帧 功能位 第三帧 有效数据长度位 中间6位为有效数据位 尾帧为和校验位 功能位01为读寄存器 02为写寄存器 中间六位有效数据位前三位为通道1 第一位为状态位,0x00代表关闭 0x01代表打开正在加热 0x02代表加热温度达到 第二三位为温度位 ,后三位为通道2 状态位以及温度位 例子:0A 01 06 00 00 00 00 00 00 66 */ /* * @name Analysis * @brief 串口协议解析函数 * @param UART_t * @retval None */ void Analysis(UART_t *UART) { UART_t *const com = UART; uint8_t sum_check = 0, Data_Len = 0; if (UART1.ucRec_Flag == TRUE) //证明接收到数据 { sum_check = Sum_Check(UART1.pucRec_Buffer, Protocol_Len); //求和校验的值 Data_Len = UART1.pucRec_Buffer[2]; //获取数据长度 if ((UART1.pucRec_Buffer[0] == 0x0A) && (UART1.pucRec_Buffer[Data_Len + 3] == sum_check)) //校验协议 { if (UART1.pucRec_Buffer[1] == Register_Read) //读寄存器返回值 { Send(Register_Read); //发送返回数据 } else if (UART1.pucRec_Buffer[1] == Register_Write) //写寄存器的返回值 { Public.Channel1_StatusFlag = UART1.pucRec_Buffer[3]; //提取通道1设置状态 PWM.Heating_Flag1 = Public.Channel1_StatusFlag; Public.Setting_Temp1 = UART1.pucRec_Buffer[4]; //提取通道1设置温度 Public.Setting_Temp1 = Public.Setting_Temp1 << 8; Public.Setting_Temp1 |= UART1.pucRec_Buffer[5]; //提取通道1设置温度 Public.Channel2_StatusFlag = UART1.pucRec_Buffer[6]; //提取通道2设置状态 PWM.Heating_Flag2 = Public.Channel2_StatusFlag; Public.Setting_Temp2 = UART1.pucRec_Buffer[7]; //提取通道2设置温度 Public.Setting_Temp2 = Public.Setting_Temp2 << 8; Public.Setting_Temp2 |= UART1.pucRec_Buffer[8]; //提取通道2设置温度 IAP.Save_TempValue(); //将温度保存到EEPROM内 Send(Register_Write); //发送返回数据 } else if (UART1.pucRec_Buffer[1] == Setting_Reg_Read) //读取保存的设置温度值 { Send(Setting_Reg_Read); } } Public.Memory_Clr(UART1.pucRec_Buffer, Protocol_Len); //清除缓存 UART1.ucRec_Flag = FALSE; //关闭串口接收完成标志位 } } /* * @name Send * @brief 串口发送数据函数 * @param func * @retval None */ void Send(uint8_t func) { UART1.pucSend_Buffer[0] = 0x0A; //头帧 UART1.pucSend_Buffer[1] = func; //功能位 UART1.pucSend_Buffer[2] = 0x06; //有效数据位长度 if (func == Register_Read) { UART1.pucSend_Buffer[3] = PWM.Heating_Flag1; //通道1的标识 UART1.pucSend_Buffer[4] = (ADC.Display_Temp1_Value >> 8) & 0xFF; //返回通道1实时的温度 UART1.pucSend_Buffer[5] = ADC.Display_Temp1_Value & 0xFF; UART1.pucSend_Buffer[6] = PWM.Heating_Flag2; //通道2的状态 UART1.pucSend_Buffer[7] = (ADC.Display_Temp2_Value >> 8) & 0xFF; //返回通道2实时的温度 UART1.pucSend_Buffer[8] = ADC.Display_Temp2_Value & 0xFF; } else { UART1.pucSend_Buffer[3] = Public.Channel1_StatusFlag;; //通道1的标识 UART1.pucSend_Buffer[4] = (Public.Setting_Temp1 >> 8) & 0xFF; //返回通道1实时的温度 UART1.pucSend_Buffer[5] = Public.Setting_Temp1 & 0xFF; UART1.pucSend_Buffer[6] = Public.Channel2_StatusFlag; //通道2的状态 UART1.pucSend_Buffer[7] = (Public.Setting_Temp2 >> 8) & 0xFF; //返回通道2实时的温度 UART1.pucSend_Buffer[8] = Public.Setting_Temp2 & 0xFF; } UART1.pucSend_Buffer[9] = Sum_Check(UART1.pucSend_Buffer, Protocol_Len); //求前9位和检验的值 UART1.UART_SendArray(UART1.pucSend_Buffer, Protocol_Len); //发送返回值 } /* * @name Sum_Check * @brief 和校验函数 * @param *arr Len * @retval None * 累加和checksum校验算法,不同领域可能采用不同算法,算法存在细微差别 * 本函数采用简便累加和计算方法,对十进制串按8位进行分割,对各8位值进行累加,即得校验和; * 如果校验和的数值超过十六进制的FF,也就是255,就要求其补码作为校验和 */ uint8_t Sum_Check(uint8_t *arr, uint8_t Len) //求和校验函数 { uint8_t i = 0; uint16_t Sum = 0; for (i = 0; i < (Len - 1); i++) { Sum += *(arr + i); } if (Sum > 0xFF) //超过255 求补码 { Sum = (~(Sum & 0xFF)) + 1; } return Sum & 0xFF; }