/*-------------------------------------------------------------------------------------- * @file pump_dicts.c * @author ZhaoDecheng * @version base on stm32f0x * @date 2024.01.03 * @brief 协议封装 ---------------------------------------------------------------------------------------*/ #include "stm32f10x.h" #include #include "AT.h" #include "pump_dicts.h" uint16_t LastIDNumber = 0; //上一个编号 void computeOptionDelta(uint32_t OptionNumber,uint8_t *OptionDelta,uint16_t *ExOptionDelta) { if(OptionNumber <= 12) { *OptionDelta = OptionNumber; *ExOptionDelta = 0; //Log_Printf("发送成功:%d\r\n", *OptionDelta); } else if(OptionNumber >= 13 && OptionNumber <= 268) { *OptionDelta = 13; *ExOptionDelta = OptionNumber - 13; } else if(OptionNumber >= 269 && OptionNumber <= 655349) { *OptionDelta = 14; *ExOptionDelta = OptionNumber - 255; } } void computeOptionLength(uint32_t Length,uint8_t *OptionLength,uint16_t *ExOptionLength) { if(Length <= 12) { *OptionLength = Length; *ExOptionLength = 0; //Log_Printf("发送成功:%d\r\n", *OptionLength); } else if(Length >= 13 && Length <= 268) { *OptionLength = 13; *ExOptionLength = Length - 13; } else if(Length >= 269 && Length <= 655349) { *OptionLength = 14; *ExOptionLength = Length - 255; } } void setPumpOption(uint16_t IDNumber,uint16_t Length,uint8_t * pump_data, uint16_t * pump_data_length) { uint16_t OptionNumber = 0; uint16_t ExOptionDelta = 0; uint16_t ExOptionLength = 0; uint8_t OptionDelta = 0; uint8_t OptionLength = 0; uint16_t length = * pump_data_length; OptionNumber = IDNumber - LastIDNumber; //计算联合偏移量 LastIDNumber = IDNumber; computeOptionDelta(OptionNumber,&OptionDelta,&ExOptionDelta); //计算OptionDelta和ExOptionDelta computeOptionLength(Length,&OptionLength,&ExOptionLength); //计算OptionLength和ExOptionLength pump_data[length++] = OptionDelta << 4 | (OptionLength & 0x0f); //设置ExOptionDelta if(OptionDelta >= 13) { pump_data[length++] = (uint8_t)(ExOptionDelta & 0x00ff); } if(OptionDelta == 14) { pump_data[length++] = (uint8_t)(ExOptionDelta & 0xff00) >> 8; } //设置ExOptionLength if(OptionLength >= 13) { pump_data[length++] = (uint8_t)(ExOptionLength & 0x00ff); } if(OptionLength == 14) { pump_data[length++] = (uint8_t)(ExOptionLength & 0xff00) >> 8; } *pump_data_length = length; } /** * 协议编码 * 输入<< * pump_params 泵参数。 * 输出>> * pump_data 编码后的二进制数据。 * pump_data_length 编码后的二进制数据的长度。 **/ void business_protocol_encode(struct Pump_Params pump_params, uint8_t * pump_data, uint16_t * pump_data_length) { uint16_t length = 0; LastIDNumber = 0; pump_data[length++] = 0x54; //大写字母“T”。“驼”字的首字母。 pump_data[length++] = 0x52; //大写字母“R”。“人”字的首字母。 pump_data[length++] = 0x01; //协议版本。 pump_data[length++] = 0x01; //数据类型。 //泵类型 setPumpOption(101,1,pump_data,&length); pump_data[length++] = pump_params.pumpType; //输注编号 setPumpOption(103,4,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.infusionId & 0xff000000 ) >> 24 ); pump_data[length++] = (uint8_t)( ( pump_params.infusionId & 0x00ff0000 ) >> 16 ); pump_data[length++] = (uint8_t)( ( pump_params.infusionId & 0x0000ff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params.infusionId & 0x000000ff ); //数据编号 setPumpOption(104,4,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.dataNumber & 0xff000000 ) >> 24 ); pump_data[length++] = (uint8_t)( ( pump_params.dataNumber & 0x00ff0000 ) >> 16 ); pump_data[length++] = (uint8_t)( ( pump_params.dataNumber & 0x0000ff00) >> 8 ); pump_data[length++] = (uint8_t)( pump_params.dataNumber & 0x000000ff ); //住院号 setPumpOption(105,4,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.patientCode & 0xff000000 ) >> 24 ); pump_data[length++] = (uint8_t)( ( pump_params.patientCode & 0x00ff0000 ) >> 16 ); pump_data[length++] = (uint8_t)( ( pump_params.patientCode & 0x0000ff00 ) >> 8 ); pump_data[length++] = (uint8_t)( ( pump_params.patientCode & 0x000000ff ) ); //持续量 setPumpOption(106,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.continueDose & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( ( pump_params.continueDose & 0x00ff ) ); //锁定时间 setPumpOption(107,1,pump_data,&length); pump_data[length++] = pump_params.lockTime; //极限量 setPumpOption(108,1,pump_data,&length); pump_data[length++] = pump_params.ultimateDose; //首次量 setPumpOption(109,1,pump_data,&length); pump_data[length++] = pump_params.firstDose; //追加量 setPumpOption(110,1,pump_data,&length); pump_data[length++] = pump_params.appendDose; //总量 setPumpOption(111,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.totalDose & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params.totalDose & 0x00ff ); //已输注量 setPumpOption(112,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.finishDose & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params.finishDose & 0x00ff ); //有效追加次数 setPumpOption(113,1,pump_data,&length); pump_data[length++] = pump_params.validTimes; //无效追加次数 setPumpOption(114,1,pump_data,&length); pump_data[length++] = pump_params.invalidTimes; //报警 if(pump_params.alarm_BubbleOrAneroid == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 1; //气泡或无液报警 } if(pump_params.alarm_Blocked == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 2; //堵塞报警 } if(pump_params.alarm_Total == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 3; //输入总量报警 } if(pump_params.alarm_Ultimate == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 4; //极限量报警 } if(pump_params.alarm_LowPower == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 5; //电量耗尽报警 } if(pump_params.alarm_Finished == 1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 6; //输液结束报警 } if(pump_params.alarm_MotorOutofcontrol ==1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 7; //电机失控报警 } if(pump_params.alarm_MechanicalBreakdown ==1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 8; //机械故障报警 } if(pump_params.alarm_UnfilledPillBox ==1) { setPumpOption(115,1,pump_data,&length); pump_data[length++] = 9; //未装药盒报警 } //预报 if(pump_params.forcast_WillFinished ==1) { setPumpOption(116,1,pump_data,&length); pump_data[length++] = 1; //输液将结束 } if(pump_params.forcast_InsufficientAnalgesia ==1) { setPumpOption(116,1,pump_data,&length); pump_data[length++] = 2; //镇痛不足 } if(pump_params.forcast_LowPowerForecast ==1) { setPumpOption(116,1,pump_data,&length); pump_data[length++] = 3; //电量偏低 } //运行状态 setPumpOption(117,1,pump_data,&length); if( pump_params.runStatus == 0 )pump_data[length++] = 0; //关机 if( pump_params.runStatus == 1 )pump_data[length++] = 1; //开机 if( pump_params.runStatus == 2 )pump_data[length++] = 2; //运行 if( pump_params.runStatus == 3 )pump_data[length++] = 3; //暂停 if( pump_params.runStatus == 4 )pump_data[length++] = 4; //待机 //电量 setPumpOption(118,1,pump_data,&length); pump_data[length++] = pump_params.electricity; // 基站位置区号 setPumpOption(119,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.lac & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params.lac & 0x00ff ); // 基站小区ID setPumpOption(120,4,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params.ci & 0xff000000 ) >> 24 ); pump_data[length++] = (uint8_t)( ( pump_params.ci & 0x00ff0000 ) >> 16 ); pump_data[length++] = (uint8_t)( ( pump_params.ci & 0x0000ff00 ) >> 8 ); pump_data[length++] = (uint8_t)( ( pump_params.ci & 0x000000ff ) ); //脉冲量锁时 setPumpOption(121,1,pump_data,&length); pump_data[length++] = pump_params.pulseLockTime; //脉冲首次锁时 setPumpOption(122,1,pump_data,&length); pump_data[length++] = pump_params.firstLockTime; //脉冲量 setPumpOption(123,1,pump_data,&length); pump_data[length++] = pump_params.pulseDose; *pump_data_length = length; Log_Printf("发送成功:%s\r\n", length); } /** * 协议解码 * 输出<< * pump_data 编码后的二进制数据。 * pump_data_length 编码后的二进制数据的长度。 * 输出>> * pump_params 泵参数。 **/ struct Pump_Params business_protocol_decode(uint8_t * pump_data, uint16_t * pump_data_length) { struct Pump_Params pump_params; return pump_params; }