You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.5 KiB

#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;
}
}
}