#include "kcd_hp100.h" #include "sw_timer.h" #include "usart11_rs485.h" #define STX 0x03 #define ETX 0x04 #define DEFAULT_DEVICE_ID 31 #define MEASUREMENT_DATA_SIZE 26 #define PACKET_RX_TIMEOUT 300 typedef enum { PACK_INDEX_STX = 0, PACK_INDEX_SLAVE_ID = 1, PACK_INDEX_SIZE = 2, PACK_INDEX_CHECKSUM = 24, PACK_INDEX_ETX = 25, }PACKET_INDEX; typedef enum { CMD_GET_MEASUREMENT_RESULT = 0x0A, CMD_SET_DEVICE_ID = 0x3A, CMD_SET_OUTPUT = 0x3B, CMD_SET_BAUDRATE = 0x3C, }KCD_HP100_CMD; #pragma pack(push, 1) typedef union _kcd_hp100_rx_info { struct { uint8_t Stx; uint8_t Slave_ID; uint8_t PacketSize; uint8_t Command; uint8_t System_Classification_Code; uint8_t System_Name[10]; uint16_t Co2; uint16_t Temperature; uint16_t Humidity; uint16_t VOC; uint8_t Firmware_Version; uint8_t CheckSum; uint8_t Etx; }Measurement; uint8_t Rxbuff[26]; }KCD_HP100_RX_INFO; #pragma pack(pop) static uint8_t KCD_HP100_DeviceID; static uint8_t KCD_HP100_TxCommand; static uint8_t KCD_HP100_RxIndex; static uint8_t KCD_HP100_CheckSum; static uint32_t KCD_HP100_TimeoutCount; static KCD_HP100_STATE KCD_HP100_State; static KCD_HP100_RX_INFO KCD_HP100_Result; static uint8_t KCD_HP_Calc_Checksum(uint8_t* pChecksumData, uint8_t DataSize); static void KCD_HP_Rx_PacketRecv_Process(void); void KCD_HP100_Initialization(void) { KCD_HP100_DeviceID = DEFAULT_DEVICE_ID; KCD_HP100_State = KCD_HP100_IDLE; SW_Timer_Callback_Register(SW_TIMER_RUN_CONTINUE, 0, KCD_HP_Rx_PacketRecv_Process); } void KCD_HP100_Tx_Get_MeasurmentData(void) { uint8_t TxIndex = 0; uint8_t TxBuff[10]; uint8_t CheckSum; KCD_HP100_State = KCD_HP100_TRANSMIT; KCD_HP100_TimeoutCount = millis(); KCD_HP100_TxCommand = CMD_GET_MEASUREMENT_RESULT; KCD_HP100_RxIndex = 0; TxBuff[TxIndex++] = STX; TxBuff[TxIndex++] = KCD_HP100_DeviceID; TxBuff[TxIndex++] = 0x06; TxBuff[TxIndex++] = KCD_HP100_TxCommand; CheckSum = KCD_HP_Calc_Checksum(TxBuff, TxIndex); TxBuff[TxIndex++] = CheckSum; TxBuff[TxIndex++] = ETX; Usart11_TransmitData(TxBuff, TxIndex); } KCD_HP100_STATE KCD_HP100_GetState(void) { return KCD_HP100_State; } bool KCD_HP100_Get_Co2(uint16_t* pGetCo2) { if(KCD_HP100_State != KCD_HP100_SUCCESS) return false; *pGetCo2 = KCD_HP100_Result.Measurement.Co2; return true; } static uint8_t KCD_HP_Calc_Checksum(uint8_t* pChecksumData, uint8_t DataSize) { uint8_t i; uint8_t checksum = 0; for(i = 0 ; i < DataSize ; i++) { checksum += pChecksumData[i]; } return checksum; } static void KCD_HP_Rx_PacketRecv_Process(void) { if(Usart11_Get_RecvDataCount() != 0) { uint8_t rxData = Usart11_Get_RecvData(); if(KCD_HP100_RxIndex == PACK_INDEX_STX && rxData == STX){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; KCD_HP100_CheckSum = rxData; } else if(KCD_HP100_RxIndex == PACK_INDEX_SLAVE_ID && rxData == KCD_HP100_DeviceID){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; KCD_HP100_CheckSum += rxData; } else if(KCD_HP100_RxIndex == PACK_INDEX_SIZE && rxData == MEASUREMENT_DATA_SIZE){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; KCD_HP100_CheckSum += rxData; } else if(KCD_HP100_RxIndex < PACK_INDEX_CHECKSUM){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; KCD_HP100_CheckSum += rxData; } else if(KCD_HP100_RxIndex == PACK_INDEX_CHECKSUM && rxData == KCD_HP100_CheckSum){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; } else if(KCD_HP100_RxIndex == PACK_INDEX_ETX && rxData == ETX){ KCD_HP100_Result.Rxbuff[KCD_HP100_RxIndex++] = rxData; KCD_HP100_RxIndex = 0; //dbg_printf("co2 = %d\r\n", KCD_HP100_Result.Measurement.Co2); KCD_HP100_State = KCD_HP100_SUCCESS; } else { KCD_HP100_RxIndex = 0; } } if(KCD_HP100_State == KCD_HP100_TRANSMIT) { if((millis() - KCD_HP100_TimeoutCount) >= PACKET_RX_TIMEOUT) { KCD_HP100_State = KCD_HP100_ERROR_TIMEOUT; } } }