TerminalSlave485_jt808.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. /*********************************************************
  2. //file :hd_dev_gpio.c
  3. //author :boly
  4. //date :2021/10/21
  5. //version :V1.0
  6. //brief :GSP HARD层GPIO接口C文件
  7. *********************************************************/
  8. /* Includes-----------------------------------------------------------------------------------*/
  9. #define APP_TERMINALSLAVE485_JT808_USE
  10. #define JT808_FRAM_HEAD_ID 0xA2
  11. #ifdef APP_TERMINALSLAVE485_JT808_USE
  12. /* Includes-----------------------------------------------------------------------------------*/
  13. #include "TerminalSlave485.h"
  14. #include "TerminalSlave485_jt808.h"
  15. #include "CollectMaster485.h"
  16. #include "ScreenMaster485.h"
  17. #include "KeySlave485.h"
  18. #include "Elec_Seal.h"
  19. #include "usart.h"
  20. #include "Data_deal.h"
  21. #include "Randomcode.h"
  22. #include "spi.h"
  23. #include "Dwin.h"
  24. #include "DS1302.h"
  25. #include "leaf_ota.h"
  26. #include "md5c.h"
  27. #include "cmsis_os.h"
  28. #include "func_ram_record.h"
  29. #include "func_queue_record.h"
  30. /* Private macro------------------------------------------------------------------------------*/
  31. /* Private typedef----------------------------------------------------------------------------*/
  32. #pragma pack(1)
  33. typedef struct SEND_DATA_UNIT_STC
  34. {
  35. uint32_t flowID; //发送数据ID
  36. uint32_t lenth; //发送数据长度
  37. uint32_t send_cnt; //发送计数器
  38. uint8_t buf[DATA_UNIT_SIZE - sizeof(uint32_t)*3]; //发送数据缓冲区
  39. }SEND_DATA_UNIT_STC;
  40. typedef struct JT808_DATA_OBJ
  41. {
  42. uint32_t flowID; //Y为32Bit的流水号-高位在前,此流水号来源于控制板主动上报的传感器数据包内,如A1封装
  43. uint32_t back_cnt; //接收超时计数
  44. uint32_t link_cnt; //连接计数器
  45. uint32_t link_ok; //连接标志位
  46. SEND_DATA_UNIT_STC send_data;
  47. }JT808_DATA_OBJ;
  48. #pragma pack()
  49. /* Private define-----------------------------------------------------------------------------*/
  50. /* Private variables--------------------------------------------------------------------------*/
  51. Pass41SensorScanParam_TypeDef Pass41SensorScanParam;
  52. JT808_DATA_OBJ jt808_obj = {
  53. .flowID = 1,
  54. .back_cnt = 0, //接收超时计数
  55. .link_cnt = 0,
  56. .link_ok = 0,
  57. .send_data.flowID = 0,
  58. .send_data.lenth = 0,
  59. .send_data.buf = {0},
  60. };
  61. Struct_Cang cang_data_tbak[8];
  62. Struct_Tank tank_data_tbak;
  63. extern uint8_t Cang_IO_tbak[4][64];
  64. extern uint32_t overflow_cnt_bak;
  65. extern unsigned char overflow_flag_bak;
  66. extern uint8_t Cang01_IO[64];
  67. extern uint8_t Cang02_IO[64];
  68. extern uint8_t Cang03_IO[64];
  69. extern uint8_t Cang04_IO[64];
  70. extern uint8_t Cang05_IO[64];
  71. extern uint8_t Cang06_IO[64];
  72. extern uint8_t Cang07_IO[64];
  73. extern uint8_t Cang08_IO[64];
  74. extern uint32_t overflow_cnt;
  75. /* Private function prototypes----------------------------------------------------------------*/
  76. int jt808_Build_0x02_TimeCmd(uint8_t *pBuf);
  77. int jt808_Build_0x01_flowID(uint8_t *pBuf, uint32_t flow_id);
  78. int jt808_Build_0x61_ManHole_Big_SW(uint8_t *pBuf);
  79. int jt808_Build_0x62_ManHole_Small_SW(uint8_t *pBuf);
  80. int jt808_Build_0x63_Dump_info(uint8_t *pBuf);
  81. int jt808_Build_0x64_HaiDiFa(uint8_t *pBuf);
  82. int jt808_Build_0x6d_Cang_info(uint8_t *pBuf);
  83. int jt808_Build_0x70_Sealing(uint8_t *pBuf);
  84. int jt808_Build_0x71_DumpBox_info(uint8_t *pBuf);
  85. int jt808_Build_0x72_ManHole_Box_info(uint8_t *pBuf);
  86. void jt808_update_0x40_data(void);
  87. int jt808_BuildSealTxCmd(uint8_t *pBuf, uint8_t *pEmergencyflag); // 40命令
  88. void mem_swap(uint8_t *des,int len)
  89. {
  90. int i,tlen;
  91. uint8_t dat;
  92. tlen = (len>>1);
  93. len--;
  94. for(i=0;i<tlen;i++)
  95. {
  96. dat = des[i];
  97. des[i] = des[len-i];
  98. des[len-i]=dat;
  99. }
  100. return;
  101. }
  102. /**
  103. ***************************************
  104. * 构建A1命令数据 -- hex制式
  105. * 输入:
  106. * pBuf-构建数据的存放首地址
  107. * pEmergy,如果是数据有变动,表示紧急上报,将标记存于此地址
  108. * flowID, 流水id值
  109. * 返回: 构建数据的字节总数
  110. ***************************************
  111. */
  112. int jt808_Build_Ax_Cmd(uint8_t *pBuf, uint32_t flowID, uint8_t *pEmergencyflag)
  113. {
  114. int send_pos=0;
  115. unsigned char emergencyflag=0;
  116. unsigned char Lrc_temp;
  117. unsigned char overflow_flag=0;
  118. unsigned char temp_i = 0x00;
  119. uint8_t cang_id = 0;
  120. UNUSED(Lrc_temp);
  121. UNUSED(temp_i);
  122. jt808_update_0x40_data();
  123. //标识头 总长度 紧急上报位 数据状态 仓数
  124. pBuf[send_pos++] = JT808_FRAM_HEAD_ID;
  125. pBuf[send_pos++] = 120;
  126. if(StoreNumber>0)
  127. {
  128. if(memcmp(Cang_IO_tbak[0],Cang01_IO,64))
  129. {
  130. emergencyflag=0x80;
  131. }
  132. memcpy(Cang_IO_tbak[0],Cang01_IO,64);
  133. }
  134. if(StoreNumber>1)
  135. {
  136. if(memcmp(Cang_IO_tbak[1],Cang02_IO,64))
  137. {
  138. emergencyflag=0x80;
  139. }
  140. memcpy(Cang_IO_tbak[1],Cang02_IO,64);
  141. }
  142. if(StoreNumber>2)
  143. {
  144. if(memcmp(Cang_IO_tbak[2],Cang03_IO,64))
  145. {
  146. emergencyflag=0x80;
  147. }
  148. memcpy(Cang_IO_tbak[2],Cang03_IO,64);
  149. }
  150. if(StoreNumber>3)
  151. {
  152. if(memcmp(Cang_IO_tbak[3],Cang04_IO,64))
  153. {
  154. emergencyflag=0x80;
  155. }
  156. memcpy(Cang_IO_tbak[3],Cang04_IO,64);
  157. }
  158. if(StoreNumber>4)
  159. {
  160. if(memcmp(Cang_IO_tbak[4],Cang05_IO,64))
  161. {
  162. emergencyflag=0x80;
  163. }
  164. memcpy(Cang_IO_tbak[4],Cang05_IO,64);
  165. }
  166. if(StoreNumber > 5)
  167. {
  168. StoreNumber = 5;
  169. }
  170. //add for showtable
  171. for(cang_id = 0; cang_id < StoreNumber; cang_id++){
  172. if(memcmp(&cang_data_tbak[cang_id], &cang_data[cang_id], sizeof(Struct_Cang)))
  173. {
  174. emergencyflag=0x80;
  175. }
  176. memcpy(&cang_data_tbak[cang_id],&cang_data[cang_id],sizeof(Struct_Cang));
  177. }
  178. //if(memcmp(&tank_data_tbak, &tank_data, sizeof(Struct_Tank))){
  179. // emergencyflag=0x80;
  180. //}
  181. //memcpy(&tank_data_tbak, &tank_data, sizeof(Struct_Tank));
  182. if((overflow_cnt==0) && (overflow_cnt==overflow_cnt_bak))
  183. {
  184. overflow_flag=0;
  185. }
  186. else
  187. {
  188. overflow_flag=1;
  189. }
  190. overflow_cnt_bak=overflow_cnt;
  191. if(overflow_flag_bak!=overflow_flag)
  192. {
  193. emergencyflag=0x80;
  194. }
  195. overflow_flag_bak=overflow_flag;
  196. pBuf[send_pos++] = emergencyflag; //紧急上报位
  197. pBuf[send_pos++] = 0x00; //数据状态:00正常;01未收到数据;02乱码
  198. pBuf[send_pos++] = StoreNumber;
  199. //防溢流插座
  200. pBuf[send_pos++] = 0x22;
  201. pBuf[send_pos++] = overflow_flag;
  202. #if 0
  203. //门磁
  204. pBuf[send_pos++] = 0x21;
  205. pBuf[send_pos++] = 0x01;
  206. pBuf[send_pos++] = tank_data_tbak.Door_State;
  207. //人脸授权
  208. pBuf[send_pos++] = 0x23;
  209. pBuf[send_pos++] = tank_data_tbak.Facial_Auth;
  210. #endif
  211. //61 人孔大盖 开关
  212. send_pos += jt808_Build_0x61_ManHole_Big_SW((uint8_t *)pBuf+send_pos);
  213. //62 人孔小盖 开关
  214. send_pos += jt808_Build_0x62_ManHole_Small_SW((uint8_t *)pBuf+send_pos);
  215. //63 卸油阀 开关
  216. send_pos += jt808_Build_0x63_Dump_info((uint8_t *)pBuf+send_pos);
  217. //64 底阀 开关
  218. send_pos += jt808_Build_0x64_HaiDiFa((uint8_t *)pBuf+send_pos);
  219. //65 温度
  220. send_pos += jt808_Build_0x65_Temperature((uint8_t *)pBuf+send_pos);
  221. //6B 压力
  222. send_pos += jt808_Build_0x6B_Pressure((uint8_t *)pBuf+send_pos);
  223. //6C 液位
  224. //send_pos += jt808_Build_0x6C_Level((uint8_t *)pBuf+send_pos);
  225. //6D 仓状态
  226. send_pos += jt808_Build_0x6d_Cang_info((uint8_t *)pBuf+send_pos);
  227. //70 铅封状态
  228. send_pos += jt808_Build_0x70_Sealing((uint8_t *)pBuf+send_pos);
  229. //71 卸油箱门 开关
  230. send_pos += jt808_Build_0x71_DumpBox_info((uint8_t *)pBuf+send_pos);
  231. //72 人孔箱护罩 开关
  232. send_pos += jt808_Build_0x72_ManHole_Box_info((uint8_t *)pBuf+send_pos);
  233. //01 流水号 4字节 整数
  234. send_pos += jt808_Build_0x01_flowID((uint8_t *)pBuf+send_pos, flowID);
  235. //02 时间戳 6字节 字符串 BCD[6] YY-MM-DD-hh-mm-ss(GMT+8 时间,本标准中之后涉及的时间均采用此时区)
  236. send_pos += jt808_Build_0x02_TimeCmd((uint8_t *)pBuf+send_pos);
  237. //数据帧长度
  238. pBuf[1] = send_pos-2;
  239. #if 0
  240. while (send_pos<(120+2))
  241. {
  242. pBuf[send_pos++] = 0;
  243. };
  244. #endif
  245. if (pEmergencyflag) *pEmergencyflag = emergencyflag;
  246. return send_pos;
  247. }
  248. /**
  249. ***************************************
  250. * 更新老协议0x40系统状态
  251. * 输入:void
  252. * 返回: void
  253. ***************************************
  254. */
  255. uint8_t JT808_0x40_buf[256]={0};//大小+1 136
  256. uint8_t JT808_0x40_len = 0;
  257. void jt808_update_0x40_data(void)
  258. {
  259. uint8_t JT808_emergencyflag = 0;
  260. JT808_0x40_len = jt808_BuildSealTxCmd(JT808_0x40_buf, &JT808_emergencyflag);
  261. return;
  262. }
  263. /**
  264. ***************************************
  265. * 构建6D 仓状态
  266. * 输入:pBuf-构建数据的存放首地址
  267. * 返回: 构建数据的字节总数
  268. ***************************************
  269. */
  270. int jt808_Build_0x6d_Cang_info(uint8_t *pBuf)
  271. {
  272. int idx=0;
  273. int i = 0;
  274. pBuf[idx++] = 0x6D; //类型
  275. for (i = 0; i < StoreNumber; i++)
  276. {
  277. //pBuf[idx++] = 1; //每仓数量
  278. //Sealing_Data.Sealing_state_oiltype[i] :仓状态与油品:
  279. //Sealing_Data.Sealing_state_oiltype[i] = (Byte_high<<4)|Byte_low;
  280. //高4位值1:装油,2:有油,3:卸油,4:空仓(无油),低4位代表油品,高四位非等于4(空仓)值默认1,否则为0;
  281. pBuf[idx++] = (Sealing_Data.Sealing_state_oiltype[i] &0xf0)>> 4;
  282. }
  283. return idx;
  284. }
  285. /**
  286. ***************************************
  287. * 构建61 人孔大盖 开关状态
  288. * 输入:pBuf-构建数据的存放首地址
  289. * 返回: 构建数据的字节总数
  290. ***************************************
  291. */
  292. int jt808_Build_0x61_ManHole_Big_SW(uint8_t *pBuf)
  293. {
  294. int idx=0;
  295. int i,j;
  296. if(((Config_info_all.ManHole_Big_info/StoreNumber) == 0)
  297. ||((Config_info_all.ManHole_Big_info&0x80)==0x80))
  298. {
  299. return 0;
  300. }
  301. pBuf[idx++] = 0x61;
  302. for (i = 0; i < StoreNumber; i++)
  303. {
  304. pBuf[idx++] = Config_info_all.ManHole_Big_info/StoreNumber;
  305. for(j=0;j<Config_info_all.ManHole_Big_info/StoreNumber;++j)
  306. {
  307. pBuf[idx++] = Cang_IO_tbak[i][indexDaGai01+10*j];
  308. }
  309. }
  310. return idx;
  311. }
  312. /**
  313. ***************************************
  314. * 构建62 人孔小盖 开关状态
  315. * 输入:pBuf-构建数据的存放首地址
  316. * 返回: 构建数据的字节总数
  317. ***************************************
  318. */
  319. int jt808_Build_0x62_ManHole_Small_SW(uint8_t *pBuf)
  320. {
  321. int idx=0;
  322. int i,j;
  323. if(((Config_info_all.ManHole_small_info/StoreNumber) == 0)
  324. ||((Config_info_all.ManHole_small_info&0x80)==0x80))
  325. {
  326. return 0;
  327. }
  328. pBuf[idx++] = 0x62;
  329. for (i = 0; i < StoreNumber; i++)
  330. {
  331. pBuf[idx++] = Config_info_all.ManHole_small_info/StoreNumber;
  332. for(j=0;j<Config_info_all.ManHole_small_info/StoreNumber;++j)
  333. {
  334. pBuf[idx++] = Cang_IO_tbak[i][indexXiaoGai01+10*j];
  335. }
  336. }
  337. return idx;
  338. }
  339. /**
  340. ***************************************
  341. * 构建63 卸油阀 开关
  342. * 输入:pBuf-构建数据的存放首地址
  343. * 返回: 构建数据的字节总数
  344. ***************************************
  345. */
  346. int jt808_Build_0x63_Dump_info(uint8_t *pBuf)
  347. {
  348. int idx=0;
  349. int i,j;
  350. if(((Config_info_all.Dump_info/StoreNumber) == 0)
  351. ||((Config_info_all.Dump_info&0x80)==0x80))
  352. {
  353. return 0;
  354. }
  355. pBuf[idx++] = 0x63;
  356. for (i = 0; i < StoreNumber; i++)
  357. {
  358. pBuf[idx++] = Config_info_all.Dump_info/StoreNumber;
  359. for(j=0;j<Config_info_all.Dump_info/StoreNumber;++j)
  360. {
  361. pBuf[idx++] = Cang_IO_tbak[i][indexXieYouFa01+10*j];
  362. }
  363. }
  364. return idx;
  365. }
  366. /**
  367. ***************************************
  368. * 构建72 人孔箱护罩 开关
  369. * 输入:pBuf-构建数据的存放首地址
  370. * 返回: 构建数据的字节总数
  371. ***************************************
  372. */
  373. int jt808_Build_0x72_ManHole_Box_info(uint8_t *pBuf)
  374. {
  375. int idx=0;
  376. int i,j;
  377. if(((Config_info_all.ManHole_Big_info/StoreNumber) == 0)
  378. ||((Config_info_all.ManHole_Big_info&0x80)==0x80))
  379. {
  380. return 0;
  381. }
  382. pBuf[idx++] = 0x72;
  383. for (i = 0; i < StoreNumber; i++)
  384. {
  385. pBuf[idx++] = Config_info_all.ManHole_Big_info/StoreNumber;
  386. for(j=0;j<Config_info_all.ManHole_Big_info/StoreNumber;++j)
  387. {
  388. pBuf[idx++] = Cang_IO_tbak[i][indexDaGai01+10*j];
  389. }
  390. }
  391. return idx;
  392. }
  393. /**
  394. ***************************************
  395. * 构建71 卸油箱门 开关
  396. * 输入:pBuf-构建数据的存放首地址
  397. * 返回: 构建数据的字节总数
  398. ***************************************
  399. */
  400. int jt808_Build_0x71_DumpBox_info(uint8_t *pBuf)
  401. {
  402. int idx=0;
  403. int i,j;
  404. if(((Config_info_all.Dump_info/StoreNumber) == 0)
  405. ||((Config_info_all.Dump_info&0x80)==0x80))
  406. {
  407. return 0;
  408. }
  409. pBuf[idx++] = 0x71;
  410. for (i = 0; i < StoreNumber; i++)
  411. {
  412. pBuf[idx++] = Config_info_all.Dump_info/StoreNumber;
  413. for(j=0;j<Config_info_all.Dump_info/StoreNumber;++j)
  414. {
  415. pBuf[idx++] = Cang_IO_tbak[i][indexXieYouFa01+10*j];
  416. }
  417. }
  418. return idx;
  419. }
  420. /**
  421. ***************************************
  422. * 构建64 底阀 开关
  423. * 输入:pBuf-构建数据的存放首地址
  424. * 返回: 构建数据的字节总数
  425. ***************************************
  426. */
  427. int jt808_Build_0x64_HaiDiFa(uint8_t *pBuf)
  428. {
  429. int idx=0;
  430. int i,j;
  431. if(((Config_info_all.HaiDiFa_info/StoreNumber) == 0)
  432. ||((Config_info_all.HaiDiFa_info&0x80)==0x80))
  433. {
  434. return 0;
  435. }
  436. pBuf[idx++] = 0x64;
  437. for (i = 0; i < StoreNumber; i++)
  438. {
  439. pBuf[idx++] = Config_info_all.HaiDiFa_info/StoreNumber;
  440. for(j=0;j<Config_info_all.HaiDiFa_info/StoreNumber;++j)
  441. {
  442. pBuf[idx++] = Cang_IO_tbak[i][indexHaiDiFa01+10*j];
  443. }
  444. }
  445. return idx;
  446. }
  447. /**
  448. ***************************************
  449. * 构建65 温度1
  450. * 输入:pBuf-构建数据的存放首地址
  451. * 返回: 构建数据的字节总数
  452. ***************************************
  453. */
  454. int jt808_Build_0x65_Temperature(uint8_t *pBuf)
  455. {
  456. int idx=0;
  457. int i;
  458. uni_float uni;
  459. pBuf[idx++] = 0x65;
  460. for (i = 0; i < StoreNumber; i++)
  461. {
  462. uni.flo_Data = cang_data_tbak[i].temperature;
  463. if((uni.array_u8[0]== 0xAB) && (uni.array_u8[1] == 0xAB) && (uni.array_u8[2] == 0xAB) && (uni.array_u8[3] == 0xAB)){
  464. pBuf[idx++] = 0x01;
  465. }else{
  466. pBuf[idx++] = 0x00;
  467. }
  468. pBuf[idx++] = uni.array_u8[3];
  469. pBuf[idx++] = uni.array_u8[2];
  470. pBuf[idx++] = uni.array_u8[1];
  471. pBuf[idx++] = uni.array_u8[0];
  472. }
  473. return idx;
  474. }
  475. /**
  476. ***************************************
  477. * 构建6B 压力
  478. * 输入:pBuf-构建数据的存放首地址
  479. * 返回: 构建数据的字节总数
  480. ***************************************
  481. */
  482. int jt808_Build_0x6B_Pressure(uint8_t *pBuf)
  483. {
  484. int idx=0;
  485. int i;
  486. uni_float uni;
  487. pBuf[idx++] = 0x6B;
  488. for (i = 0; i < StoreNumber; i++)
  489. {
  490. uni.flo_Data = cang_data_tbak[i].pressure;
  491. if((uni.array_u8[0]== 0xAC) && (uni.array_u8[1] == 0xAC) && (uni.array_u8[2] == 0xAC) && (uni.array_u8[3] == 0xAC)){
  492. pBuf[idx++] = 0x01;
  493. }else{
  494. pBuf[idx++] = 0x00;
  495. }
  496. pBuf[idx++] = uni.array_u8[3];
  497. pBuf[idx++] = uni.array_u8[2];
  498. pBuf[idx++] = uni.array_u8[1];
  499. pBuf[idx++] = uni.array_u8[0];
  500. }
  501. return idx;
  502. }
  503. /**
  504. ***************************************
  505. * 构建6C 液位
  506. * 输入:pBuf-构建数据的存放首地址
  507. * 返回: 构建数据的字节总数
  508. ***************************************
  509. */
  510. int jt808_Build_0x6C_Level(uint8_t *pBuf)
  511. {
  512. int idx=0;
  513. int i;
  514. uni_float uni;
  515. pBuf[idx++] = 0x6C;
  516. for (i = 0; i < StoreNumber; i++)
  517. {
  518. uni.flo_Data = cang_data_tbak[i].level;
  519. if((uni.array_u8[0]== 0xAA) && (uni.array_u8[1] == 0xAA) && (uni.array_u8[2] == 0xAA) && (uni.array_u8[3] == 0xAA)){
  520. pBuf[idx++] = 0x01;
  521. }else{
  522. pBuf[idx++] = 0x00;
  523. }
  524. pBuf[idx++] = uni.array_u8[3];
  525. pBuf[idx++] = uni.array_u8[2];
  526. pBuf[idx++] = uni.array_u8[1];
  527. pBuf[idx++] = uni.array_u8[0];
  528. }
  529. return idx;
  530. }
  531. /**
  532. ***************************************
  533. * 构建70 铅封状态
  534. * 输入:pBuf-构建数据的存放首地址
  535. * 返回: 构建数据的字节总数
  536. ***************************************
  537. */
  538. int jt808_Build_0x70_Sealing(uint8_t *pBuf)
  539. {
  540. int idx=0;
  541. int i = 0;
  542. pBuf[idx++] = 0x70; //类型
  543. for (i = 0; i < StoreNumber; i++)
  544. {
  545. //pBuf[idx++] = 1; //每仓数量
  546. //Sealing_Data.Sealing_Mode[i] :仓状态与油品:
  547. //1仓铅封状态/装油模式:高4位值1: 施封状态,值2:解封状态,值3:破封状态,值4:施封并输入密码超限,值5:非法破封;
  548. // 低4位(装油情况下)值1:上装,值2:下装;
  549. pBuf[idx++] = (Sealing_Data.Sealing_Mode[i] &0xf0)>> 4;
  550. }
  551. return idx;
  552. }
  553. /**
  554. ***************************************
  555. * 构建01 流水号 4字节 整数
  556. * 输入:pBuf-构建数据的存放首地址
  557. * 返回: 构建数据的字节总数
  558. ***************************************
  559. */
  560. int jt808_Build_0x01_flowID(uint8_t *pBuf,uint32_t flow_id)
  561. {
  562. int idx=0;
  563. // 2022-8-25, 新增加的子命令
  564. // 01, 流水号
  565. // 02, 时间戳
  566. do {
  567. pBuf[idx++] = 0x01;
  568. pBuf[idx++] = (flow_id>>24) & 0xff;
  569. pBuf[idx++] = (flow_id>>16) & 0xff;
  570. pBuf[idx++] = (flow_id>>8) & 0xff;
  571. pBuf[idx++] = (flow_id>>0) & 0xff;
  572. }while(0);
  573. return idx;
  574. }
  575. /**
  576. ***************************************
  577. * 构建20命令数据 时间戳 -- hex制式
  578. * 输入:pBuf-构建数据的存放首地址
  579. * 返回: 构建数据的字节总数
  580. ***************************************
  581. */
  582. extern SDateTime m_datetime;
  583. int jt808_Build_0x02_TimeCmd(uint8_t *pBuf)
  584. {
  585. int send_pos=0;
  586. //02 时间戳 6字节 字符串 BCD[6] YY-MM-DD-hh-mm-ss(GMT+8 时间,本标准中之后涉及的时间均采用此时区)
  587. pBuf[send_pos++] = 0x02;
  588. pBuf[send_pos++] = HEXtoBCD(m_datetime.year);
  589. pBuf[send_pos++] = HEXtoBCD(m_datetime.month);
  590. pBuf[send_pos++] = HEXtoBCD(m_datetime.day);
  591. pBuf[send_pos++] = HEXtoBCD(m_datetime.hour);
  592. pBuf[send_pos++] = HEXtoBCD(m_datetime.min);
  593. pBuf[send_pos++] = HEXtoBCD(m_datetime.sec);
  594. return send_pos;
  595. }
  596. /**
  597. ***************************************
  598. * 构建40命令数据 电子铅封 -- hex制式
  599. * 输入:pBuf-构建数据的存放首地址
  600. * 返回: 构建数据的字节总数
  601. ***************************************
  602. */
  603. int jt808_BuildSealTxCmd(uint8_t *pBuf, uint8_t *pEmergencyflag) // 40命令
  604. {
  605. Return_data *ret;
  606. int n = 0;
  607. uint8_t emergencyflag = 0;
  608. *pBuf++ = 0x40;
  609. ret = Seal_Tx_Readvalue(0,0);
  610. *pBuf++ = ret->length/2; // 调用返回的数据是asii制式的,所以真实的hex数是其一半
  611. for(n=0; n < ret->length/2 && n < 100; n++) {
  612. pBuf[n] = MODBUS_ASCII_AsciiToHex(ret->data + 2*n);
  613. }
  614. emergencyflag = pBuf[0];
  615. if(pEmergencyflag) *pEmergencyflag = emergencyflag;
  616. return n+2;
  617. }
  618. /**
  619. ***************************************
  620. * 构建91命令数据 IO状态 -- hex制式
  621. * 输入:pBuf-构建数据的存放首地址
  622. * 返回: 构建数据的字节总数
  623. ***************************************
  624. */
  625. int jt808_Build91Cmd(uint8_t *pBuf, uint8_t *pEmergencyflag)
  626. {
  627. Return_data *ret;
  628. int n = 0;
  629. uint8_t emergencyflag = 0;
  630. *pBuf++ = 0x91;
  631. ret = IO_Tx_Readvalue(0,0);
  632. *pBuf++ = ret->length/2; // 调用返回的数据是asii制式的,所以真实的hex数是其一半
  633. for(n=0; n < ret->length/2 && n < 100; n++) {
  634. pBuf[n] = MODBUS_ASCII_AsciiToHex(ret->data + 2*n);
  635. }
  636. emergencyflag = pBuf[0];
  637. if(pEmergencyflag) *pEmergencyflag = emergencyflag;
  638. return n+2;
  639. }
  640. /**
  641. ***************************************
  642. * 检测当前连接状态
  643. * 输入:无
  644. * 返回: 无
  645. ***************************************
  646. */
  647. void jt808_link_check(void)
  648. {
  649. if(jt808_obj.back_cnt < (Pass41SensorScanParam.nstep*Pass41SensorScanParam.step))
  650. {
  651. jt808_obj.link_cnt++;
  652. }
  653. else
  654. {
  655. jt808_obj.link_cnt = 0;
  656. }
  657. if(jt808_obj.link_cnt > 0)
  658. {
  659. jt808_obj.link_ok = true;
  660. }
  661. else
  662. {
  663. jt808_obj.link_ok = false;
  664. }
  665. return;
  666. }
  667. /**
  668. ***************************************
  669. * 将缓冲区数据帧内容,放入串口发送数据缓冲区
  670. * 输入:无
  671. * 返回: 无
  672. ***************************************
  673. */
  674. void jt808_send_buf_data(void)
  675. {
  676. if(jt808_obj.send_data.lenth == 0)
  677. {
  678. return;
  679. }
  680. //将缓冲区数据帧内容,放入串口发送数据缓冲区
  681. memcpy(USART1_TX_BUF,jt808_obj.send_data.buf,jt808_obj.send_data.lenth);
  682. //发送次数进行累加
  683. jt808_obj.send_data.send_cnt++;
  684. //打上补发标记
  685. USART1_TX_BUF[3] |= 0x80;
  686. //通过串口将数据发送出去
  687. TerminalSlave485_Send_Data(USART1_TX_BUF,jt808_obj.send_data.lenth);
  688. return;
  689. }
  690. /**
  691. ***************************************
  692. * 处理接收到的返回数据帧
  693. * 输入:无
  694. * 返回: 无
  695. ***************************************
  696. */
  697. JT808_DataBack_DATA jt808_data_back = {0};
  698. void jt808_recv_func_DataBack(uint8_t * buf ,uint8_t len)
  699. {
  700. uint32_t read_len = 0;
  701. jt808_obj.back_cnt = 0;
  702. memcpy(&jt808_data_back, buf ,sizeof(jt808_data_back));
  703. mem_swap((uint8_t *)&(jt808_data_back.flowID),sizeof(jt808_data_back.flowID));
  704. if(jt808_data_back.flowID == jt808_obj.send_data.flowID)
  705. {
  706. //清除发送缓冲区数据
  707. memset((void *)&(jt808_obj.send_data), 0x00, sizeof(jt808_obj.send_data));
  708. #if USE_QUEUE_RECORD==1
  709. if(func_record_queue_flash_get() == true)
  710. {
  711. read_len = func_record_queue_read((void *)&(jt808_obj.send_data), (uint32_t)DATA_UNIT_SIZE);
  712. }
  713. else
  714. #endif
  715. #if USE_RAM_RECORD==1
  716. {
  717. //从内存数据栈中读取缓冲数据
  718. read_len = func_ram_record_delete((void *)&(jt808_obj.send_data), DATA_UNIT_SIZE);
  719. }
  720. #else
  721. {
  722. ;
  723. }
  724. #endif
  725. if( read_len != DATA_UNIT_SIZE)
  726. {
  727. memset((void *)&(jt808_obj.send_data), 0x00, sizeof(jt808_obj.send_data));
  728. }
  729. else if( jt808_obj.send_data.buf[0] != JT808_FRAM_HEAD_ID)
  730. {
  731. memset((void *)&(jt808_obj.send_data), 0x00, sizeof(jt808_obj.send_data));
  732. }
  733. //如果本帧数据重发次数大于5,则清除本帧数据
  734. if(jt808_obj.send_data.send_cnt > 5)
  735. {
  736. memset((void *)&(jt808_obj.send_data), 0x00, sizeof(jt808_obj.send_data));
  737. }
  738. }
  739. return;
  740. }
  741. /**
  742. ***************************************
  743. * 将发送序列ID放入FRAM
  744. * 输入:当前发送序列号
  745. * 返回: 无
  746. ***************************************
  747. */
  748. void jt808_save_Scan_flowID(uint32_t flowID)
  749. {
  750. FM25L16B_Write_N_Bytes(FRAM_ADDR_Scan_flowID, (uint8_t *)&flowID, sizeof(flowID));
  751. return;
  752. }
  753. /**
  754. ***************************************
  755. * 初始化数据帧序列ID
  756. * 输入:发送序列号指针地址
  757. * 返回: 无
  758. ***************************************
  759. */
  760. void jt808_read_Scan_flowID(uint32_t * flowID)
  761. {
  762. FM25L16B_Read_N_Bytes(FRAM_ADDR_Scan_flowID, (uint8_t *)flowID, sizeof(flowID));
  763. return;
  764. }
  765. /**
  766. ***************************************
  767. * 将发送缓冲区中的数据,放入RAM,并将当前
  768. * 产生的数据放入缓冲区
  769. * 输入:无
  770. * 返回: 无
  771. ***************************************
  772. */
  773. void jt808_save_send_data(uint8_t * buf ,uint16_t len)
  774. {
  775. if(jt808_obj.send_data.flowID != 0)
  776. {
  777. #if USE_QUEUE_RECORD==1
  778. if(func_record_queue_flash_get() == true)
  779. {
  780. func_record_queue_write((uint8_t *)&(jt808_obj.send_data) , DATA_UNIT_SIZE);
  781. }
  782. else
  783. #endif
  784. #if USE_RAM_RECORD==1
  785. {
  786. func_ram_record_write((uint8_t *)&(jt808_obj.send_data) , DATA_UNIT_SIZE);
  787. }
  788. #else
  789. {
  790. ;
  791. }
  792. #endif
  793. memset((void *)&(jt808_obj.send_data), 0x00, sizeof(jt808_obj.send_data));
  794. }
  795. jt808_obj.send_data.flowID = jt808_obj.flowID;
  796. jt808_obj.send_data.lenth = len;
  797. if(len > sizeof(jt808_obj.send_data.buf))
  798. {
  799. len = sizeof(jt808_obj.send_data.buf);
  800. }
  801. memset(jt808_obj.send_data.buf, 0x00, sizeof(jt808_obj.send_data.buf));
  802. memcpy(jt808_obj.send_data.buf, buf, len);
  803. return;
  804. }
  805. /**
  806. ***************************************
  807. * xy,新透传,41串口透传,模拟F3轮询传感器
  808. * 按照周期1构建数据,按照周期2发送数据
  809. * 输入:无
  810. * 返回: 无
  811. * 发送区的格式为:
  812. * 数据负载类别,1Byte
  813. * 传感器命令数据包数,1Byte
  814. * 具体的各个命令数据包,NByte
  815. ***************************************
  816. */
  817. void jt808_DoInternalSensorScanAndPost(void)
  818. {
  819. int xlen=0, ylen=0;
  820. uint8_t emergencyflag=0;
  821. uint8_t *pSendBuf = USART1_TX_BUF;
  822. static int step = 0;
  823. static int nstep = 0;
  824. if(++step % Pass41SensorScanParam.step == 0)
  825. {
  826. for(int n=0; n<Pass41SensorScanParam.cmd_num; n++) {
  827. switch (Pass41SensorScanParam.cmd_arr[n]){
  828. case 0x40:
  829. xlen = jt808_BuildSealTxCmd(pSendBuf, emergencyflag?NULL:&emergencyflag);
  830. pSendBuf += xlen;
  831. ylen += xlen;
  832. break;
  833. case 0x91:
  834. xlen = jt808_Build91Cmd(pSendBuf, emergencyflag?NULL:&emergencyflag);
  835. pSendBuf += xlen;
  836. ylen += xlen;
  837. break;
  838. case JT808_FRAM_HEAD_ID:
  839. xlen = jt808_Build_Ax_Cmd(pSendBuf, jt808_obj.flowID, emergencyflag?NULL:&emergencyflag);
  840. pSendBuf += xlen;
  841. ylen += xlen;
  842. break;
  843. default:
  844. break;
  845. }
  846. }
  847. if(emergencyflag)
  848. {
  849. TerminalSlave485_Send_Data(USART1_TX_BUF, ylen);
  850. //保存发送数据
  851. jt808_save_send_data(USART1_TX_BUF, ylen);
  852. nstep = 0;
  853. emergencyflag = 0;
  854. jt808_obj.flowID++;
  855. jt808_save_Scan_flowID(jt808_obj.flowID);
  856. }
  857. else
  858. {
  859. if(++nstep % Pass41SensorScanParam.nstep == 0)
  860. {
  861. TerminalSlave485_Send_Data(USART1_TX_BUF,ylen);
  862. //保存发送数据
  863. jt808_save_send_data(USART1_TX_BUF,ylen);
  864. //检测当前连接状态,每一大循环执行一次
  865. jt808_link_check();
  866. jt808_obj.flowID++;
  867. jt808_save_Scan_flowID(jt808_obj.flowID);
  868. }
  869. else if(nstep % Pass41SensorScanParam.nstep == (Pass41SensorScanParam.nstep/2))
  870. {
  871. //重发缓冲区数据
  872. if(jt808_obj.link_ok == true) //如果连接正常,则重发数据;
  873. {
  874. jt808_send_buf_data();
  875. }
  876. }
  877. }
  878. }
  879. jt808_obj.back_cnt++;
  880. return;
  881. }
  882. /**
  883. ***************************************
  884. * 初始化发送配置参数
  885. * 输入:无
  886. * 返回: 无
  887. ***************************************
  888. */
  889. void jt808_InitSensorScanParam(void)
  890. {
  891. uint8_t data[16];
  892. FM25L16B_Read_N_Bytes(FRAM_ADDR_Scan_Param, data, 16);
  893. if(data[0] == 0x5A){
  894. uint8_t *buf = data+1;
  895. Pass41SensorScanParam.enable = 1;
  896. if(buf[0] > 1 && buf[1] > 0){
  897. Pass41SensorScanParam.step = buf[0];
  898. Pass41SensorScanParam.nstep = buf[1];
  899. if(buf[2] > 0 && buf[2] <= 8){
  900. Pass41SensorScanParam.cmd_num = buf[2];
  901. for (int n = 0; n < Pass41SensorScanParam.cmd_num; n++){
  902. Pass41SensorScanParam.cmd_arr[n] = buf[3+n];
  903. }
  904. }else{
  905. Pass41SensorScanParam.cmd_num = 2;
  906. Pass41SensorScanParam.cmd_arr[0] = 0x40;
  907. Pass41SensorScanParam.cmd_arr[1] = 0x91;
  908. }
  909. }else{
  910. Pass41SensorScanParam.step = 5;
  911. Pass41SensorScanParam.nstep = 6;
  912. Pass41SensorScanParam.cmd_num = 2;
  913. Pass41SensorScanParam.cmd_arr[0] = 0x40;
  914. Pass41SensorScanParam.cmd_arr[1] = 0x91;
  915. }
  916. }else{
  917. Pass41SensorScanParam.enable = 0;
  918. Pass41SensorScanParam.step = 5;
  919. Pass41SensorScanParam.nstep = 6;
  920. Pass41SensorScanParam.cmd_num = 1;
  921. Pass41SensorScanParam.cmd_arr[0] = JT808_FRAM_HEAD_ID;
  922. }
  923. //初始化发送序列ID
  924. jt808_read_Scan_flowID(&(jt808_obj.flowID));
  925. }
  926. /**
  927. ***************************************
  928. * 初始化发送配置参数
  929. * 输入:无
  930. * 返回: 无
  931. ***************************************
  932. */
  933. uint8_t jt808_Build_Read_WorkSt(uint8_t * PayLoad)
  934. {
  935. uint8_t idx = 0;
  936. PayLoad[idx++] = func_record_queue_flash_get();
  937. PayLoad[idx++] = jt808_obj.link_ok;
  938. uint32_t msg_num = 0;
  939. if(PayLoad[0] == true)
  940. {
  941. msg_num = func_record_queue_obj_cnt();
  942. }
  943. else
  944. {
  945. msg_num = func_ram_obj_num(DATA_UNIT_SIZE);
  946. }
  947. PayLoad[idx++] = (msg_num>>24)&0xff;
  948. PayLoad[idx++] = (msg_num>>16)&0xff;
  949. PayLoad[idx++] = (msg_num>>8)&0xff;
  950. PayLoad[idx++] = (msg_num)&0xff;
  951. return idx;
  952. }
  953. #endif /*************APP_TERMINALSLAVE485_JT808_USE*******************/