/** ****************************************************************************** * 版 本 :V1.0.0 * 作 者 :zhaodecheng,liuyanbin * 版权所有,盗版必究。 * Copyright(C) All rights reserved ****************************************************************************** * 历史记录 * 序号 版本 变更内容 作者 日期 * 1 V0.0.1 实现协议封装代码 刘艳斌 2023/12/23 * 2 V1.0.0 优化协议封装代码 赵得逞 2024/1/5 * ****************************************************************************** */ #include "stm32f10x.h" #include #include #include "Pump_Dicts_Util.h" #include "CONFIG.h" static 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) { if(Length <= 0) { return; } 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 PUMPDICTS_ProtocolEncode(struct PUMPDICTS_ParamsStruct * 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(1,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params->userId & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( ( pump_params->userId & 0x00ff ) ); // 网络类型 setPumpOption(2,1,pump_data,&length); pump_data[length++] = pump_params->networkType; #ifdef SEND_SIM_FLAG // sim卡号 setPumpOption(4,strlen(pump_params->sim),pump_data,&length); for(int i = 0; i < strlen(pump_params->sim); i++) { pump_data[length++] = pump_params->sim[i]; } #endif // 基站位置区号 setPumpOption(5,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(6,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(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,8,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0xff00000000000000 ) >> 56 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x00ff000000000000 ) >> 48 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x0000ff0000000000 ) >> 40 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x000000ff00000000 ) >> 32 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x00000000ff000000 ) >> 24 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x0000000000ff0000 ) >> 16 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x000000000000ff00 ) >> 8 ); pump_data[length++] = (uint8_t)( ( pump_params->patientCode & 0x00000000000000ff ) ); // 持续量 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(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; //病区 setPumpOption(124,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params->ward & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params->ward & 0x00ff ); //床号 setPumpOption(125,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params->bedNo & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params->bedNo & 0x00ff ); //版本号 setPumpOption(136,2,pump_data,&length); pump_data[length++] = (uint8_t)( ( pump_params->version & 0xff00 ) >> 8 ); pump_data[length++] = (uint8_t)( pump_params->version & 0x00ff ); *pump_data_length = length; } /** * 协议解码 * 输出<< * pump_data 编码后的二进制数据。 * pump_data_length 编码后的二进制数据的长度。 * 输出>> * pump_params 泵参数。 **/ void PUMPDICTS_ProtocolDecode(struct PUMPDICTS_ParamsStruct * pump_params, uint8_t * pump_data, uint16_t * pump_data_length) { }