TerminalSlave485_jt808.c 25 KB

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