TerminalSlave485_jt808.c 24 KB

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