dotled.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807
  1. #define LOG_TAG "dotled" // 该模块对应的标签。不定义时,默认:NO_TAG
  2. #define LOG_LVL LOG_LVL_DBG // LOG_LVL_DBG // 该模块对应的日志输出级别。不
  3. #include <ulog.h> // 必须在 LOG_TAG 与 LOG_LVL 下面
  4. #include "dotled.h"
  5. #include <easyflash.h>
  6. #include "sys_config.h"
  7. extern uint32_t month;
  8. extern uint32_t day;
  9. extern uint32_t year;
  10. extern uint32_t hour;
  11. extern uint32_t min;
  12. extern uint32_t sec;
  13. extern uint8_t week;
  14. extern led_t *SENSORLED;
  15. extern led_t *COMMLED;
  16. extern led_t *DOTLED;
  17. #define RS485_DOTLED_EN GET_PIN(D, 1)
  18. #ifndef dot_mod
  19. #define DOTLED_UART_NAME "uart3" /* 串口设备名称 */
  20. #else
  21. #define DOTLED_UART_NAME "uart6" /* 串口设备名称 */
  22. #endif
  23. /* 串口设备句柄 */
  24. static rt_device_t dotled;
  25. #define timed_events_TITLE (1 << 0) //标题刷新计时
  26. #define timed_events_MAIN (1 << 1) //内容刷新计时
  27. #define timed_events_RTC (1 << 2) //时间显示刷新计时
  28. #define timed_events_MAIN1 (1 << 3) //内容刷新计时
  29. #define timed_events_onoff (1 << 4) //
  30. /* 定时事件控制块 */
  31. static struct rt_event timed_events;
  32. /* 定时器的控制块 */
  33. static rt_timer_t dotled_timed_task;
  34. #define dis_buff_len 40 * qxz.Param.Num_sensors
  35. /*1米*0.5米屏幕点阵为 96*48 */
  36. /*1米* 1米屏幕点阵为 96*96 */
  37. /*2米* 1米屏幕点阵为192*96 */
  38. static char dotledtitle[60]; // LED显示屏抬头,最大显示30个汉字
  39. static char dotledtitle_down[60]; // LED显示屏下发抬头内容,最大显示30个汉字
  40. static uint32_t title_timeout = 0; // 下发后抬头显示超时失效时间。
  41. static uint16_t main_keeptime = 16; //主显示区单页面显示时长,0.5s步进
  42. /*屏幕显示行数 1 * 0.5米为96*48点阵,显示3行
  43. *屏幕显示行数 1 * 1米为96*96点阵, 显示6行
  44. *屏幕显示行数 2 * 1米为192*96点阵, 显示5行
  45. */
  46. static uint16_t screen_line = 12;
  47. //点阵屏尺寸规格区分标志位
  48. //static uint8_t dotled_size = 0;
  49. static char *green = "\\C2";
  50. static char *red = "\\C1";
  51. /*发送显示数据使用缓存指针*/
  52. static uint8_t *Dis_Comm = RT_NULL;
  53. //static uint8_t *dis_buff = RT_NULL;
  54. //转义字符,输入:待转义字符指针,长度
  55. uint16_t Escape_character(uint8_t *buff, uint16_t len);
  56. void Time2BCD(char *bcd_buf);
  57. static uint8_t frame[8] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5}; //包头
  58. static uint8_t header[12] = {0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02}; //帧头,5K1,5K2屏幕区分
  59. //十进制转ASCII码
  60. #define KB2ASC(x) (u8)(0x30 + x)
  61. //ASCII码转十进制
  62. #define ASC2KB(x) (u8)(x % (0x30))
  63. #define PLOY 0xa001 //0x8005 反转
  64. uint8_t crc16(uint8_t *data, uint8_t size);
  65. //获取字符串长度
  66. uint8_t sizeof_s(char *str);
  67. //把str1的内容copy到str2
  68. //*str1:字符串1指针
  69. //*str2:字符串2指针
  70. void strcopy(char *str1, char *str2);
  71. /* 定时器超时函数 */
  72. static void dotled_timed(void *parameter)
  73. {
  74. static rt_uint32_t cnt = 0;
  75. cnt++;
  76. rt_uint8_t temp;
  77. if (cnt % ((rt_uint32_t)parameter * main_keeptime * ((qxz.Param.Num_sensors / screen_line) + 3)) == 0)
  78. {
  79. rt_event_send(&timed_events, timed_events_TITLE); //定时时间到,发送事件
  80. }
  81. if (qxz.Param.Num_sensors % screen_line != 0)
  82. {
  83. temp = qxz.Param.Num_sensors / screen_line + 1;
  84. }
  85. else
  86. temp = qxz.Param.Num_sensors / screen_line;
  87. if (cnt % ((rt_uint32_t)parameter * (uint16_t)(main_keeptime) * (temp + 0)) == 0) //
  88. {
  89. rt_event_send(&timed_events, timed_events_MAIN); //定时时间到,发送事件
  90. rt_event_send(&timed_events, timed_events_MAIN1); //定时时间到,发送事件
  91. }
  92. if (cnt % 3600 == 0) //1小时刷新1次
  93. {
  94. rt_event_send(&timed_events, timed_events_RTC); //定时时间到,发送事件
  95. }
  96. }
  97. //参数结构变量赋初值
  98. static bx_5k_area_header bx_5k = {
  99. .Frame = frame, //帧头 8 bytes (A5)
  100. .Header = header, //包头 12 bytes (01 00 00 80 00 00 00 00 00 00 FE 02)
  101. .Len = {0, 0}, //整个发送数据除去帧头,包头,CRC校验后的长度 2 bytes
  102. .Cmd_dis = {0xa3, 0x06}, //发送实时显示信息命令 A3 06
  103. .Reply_f = 0x00, //控制器回复标志 01
  104. .Reserved0 = {0x00, 0x00}, //2D 00→保留字节(此值未使用)
  105. .Areadealnum = 0, //00→要删除的区域个数
  106. .AreaNum = 0x01, //区域个数,默认为 0x01,1 bytes
  107. .AreaLen = {0, 0}, //动态区域0数据长度,2 bytes
  108. .AreaType = 0x00, //设置区域类型,默认为 0x00 1 bytes
  109. .AreaX = {0x00, 0}, //设置 X 坐标 2 bytes
  110. .AreaY = {0x00, 0}, //设置 Y 坐标 2 bytes
  111. .AreaWidth = {0x80, 0}, //设置屏宽度 2 bytes
  112. .AreaHeight = {0x34, 0}, //设置屏高度 2 bytes
  113. .DynamicAreaLoc = 1, //设置动态区编号 1 bytes
  114. .Lines_sizes = 0, //行间距
  115. .RunMode = 0, //动态区数据循环模式 1 bytes
  116. .Timeout = {0x05, 0x00}, //设置超时时间 2 bytes
  117. .Reserved1 = {0, 0, 0}, //保留 3 bytes
  118. .SingleLine = 0x02, //设置是否单行显示 1 bytes
  119. .NewLine = 0x02, //设置是否自动换行 1 bytes
  120. .DisplayMode = 0x02, //设置显示方式 1 bytes 01静止显示
  121. .ExitMode = 0x00, //设置退出方式 1 bytes
  122. .Speed = 0x02, //设置运行速度 1 bytes
  123. .StayTime = 0x05, //设置停留时间 1 bytes
  124. .DataLen = {0, 0, 0, 0}, //要显示内容的个数 4 bytes
  125. .dis_buff = 0, //显示内容
  126. .crc_data = {0, 0}, //CRC
  127. };
  128. #define CN 0
  129. #define EN 1
  130. #define W_dic_Lang CN
  131. /*刷新风向传感器数据*/
  132. char *Display_Data_wind_direction360(uint16_t direction)
  133. {
  134. uint8_t temp;
  135. direction = direction % 360;
  136. #ifdef saitong_sensor
  137. temp = (uint8_t)(direction / 10 / 22.5);
  138. #else
  139. temp = (uint8_t)(direction / 22.5);
  140. #endif
  141. #if 0
  142. /*21101073A单色1*0.5屏幕定制*/
  143. temp = (uint8_t)(direction/10/22.5);
  144. #endif
  145. static char direction_op[10];
  146. rt_memset(direction_op, '\0', 10);
  147. switch (temp)
  148. {
  149. case 0:
  150. if (W_dic_Lang == EN)
  151. {
  152. sprintf(direction_op, "%s", " N ");
  153. }
  154. else
  155. {
  156. sprintf(direction_op, "%s", "北风 ");
  157. }
  158. break;
  159. case 1:
  160. if (W_dic_Lang == EN)
  161. {
  162. sprintf(direction_op, "%s", " NE ");
  163. }
  164. else
  165. {
  166. sprintf(direction_op, "%s", "东北风");
  167. }
  168. break;
  169. case 2:
  170. if (W_dic_Lang == EN)
  171. {
  172. sprintf(direction_op, "%s", " NE ");
  173. }
  174. else
  175. {
  176. sprintf(direction_op, "%s", "东北风");
  177. }
  178. break;
  179. case 3:
  180. if (W_dic_Lang == EN)
  181. {
  182. sprintf(direction_op, "%s", " E ");
  183. }
  184. else
  185. {
  186. sprintf(direction_op, "%s", "东风 ");
  187. }
  188. break;
  189. case 4:
  190. if (W_dic_Lang == EN)
  191. {
  192. sprintf(direction_op, "%s", " E ");
  193. }
  194. else
  195. {
  196. sprintf(direction_op, "%s", "东风 ");
  197. }
  198. break;
  199. case 5:
  200. if (W_dic_Lang == EN)
  201. {
  202. sprintf(direction_op, "%s", " ES ");
  203. }
  204. else
  205. {
  206. sprintf(direction_op, "%s", "东南风");
  207. }
  208. break;
  209. case 6:
  210. if (W_dic_Lang == EN)
  211. {
  212. sprintf(direction_op, "%s", " ES ");
  213. }
  214. else
  215. {
  216. sprintf(direction_op, "%s", "东南风");
  217. }
  218. break;
  219. case 7:
  220. if (W_dic_Lang == EN)
  221. {
  222. sprintf(direction_op, "%s", " S ");
  223. }
  224. else
  225. {
  226. sprintf(direction_op, "%s", "南风 ");
  227. }
  228. break;
  229. case 8:
  230. if (W_dic_Lang == EN)
  231. {
  232. sprintf(direction_op, "%s", " S ");
  233. }
  234. else
  235. {
  236. sprintf(direction_op, "%s", "南风 ");
  237. }
  238. break;
  239. case 9:
  240. if (W_dic_Lang == EN)
  241. {
  242. sprintf(direction_op, "%s", " SW ");
  243. }
  244. else
  245. {
  246. sprintf(direction_op, "%s", "西南风");
  247. }
  248. break;
  249. case 10:
  250. if (W_dic_Lang == EN)
  251. {
  252. sprintf(direction_op, "%s", " SW ");
  253. }
  254. else
  255. {
  256. sprintf(direction_op, "%s", "西南风");
  257. }
  258. break;
  259. case 11:
  260. if (W_dic_Lang == EN)
  261. {
  262. sprintf(direction_op, "%s", " W ");
  263. }
  264. else
  265. {
  266. sprintf(direction_op, "%s", "西风 ");
  267. }
  268. break;
  269. case 12:
  270. if (W_dic_Lang == EN)
  271. {
  272. sprintf(direction_op, "%s", " W ");
  273. }
  274. else
  275. {
  276. sprintf(direction_op, "%s", "西风 ");
  277. }
  278. break;
  279. case 13:
  280. if (W_dic_Lang == EN)
  281. {
  282. sprintf(direction_op, "%s", " NW ");
  283. }
  284. else
  285. {
  286. sprintf(direction_op, "%s", "西北风");
  287. }
  288. break;
  289. case 14:
  290. if (W_dic_Lang == EN)
  291. {
  292. sprintf(direction_op, "%s", " NW ");
  293. }
  294. else
  295. {
  296. sprintf(direction_op, "%s", "西北风");
  297. }
  298. break;
  299. case 15:
  300. if (W_dic_Lang == EN)
  301. {
  302. sprintf(direction_op, "%s", " N ");
  303. }
  304. else
  305. {
  306. sprintf(direction_op, "%s", "北风 ");
  307. }
  308. break;
  309. default:
  310. break;
  311. }
  312. //rt_kprintf("direction_op %s\n" , direction_op);
  313. return direction_op;
  314. }
  315. //区域1显示数据格式化,返回长度
  316. uint16_t Area1_dis_format(uint8_t *buff)
  317. {
  318. uint16_t i = 0;
  319. char sensor_value[50] = {0};
  320. uint16_t total = 0; /* 记录当前数据长度 */
  321. // char sensor_nop[4] = {0};
  322. for (i = 0; i < qxz.Param.Num_sensors; i++)
  323. {
  324. rt_memset(sensor_value, 0, 50); //判断是否传感器未接或故障,如果是则显示为空
  325. if (strcmp(sensor[i].eName, "\0") != 0) /*传感器eName不能为空*/
  326. {
  327. if (strstr(sensor[i].eValue, "-99.99") == NULL)
  328. {
  329. if ((strstr(sensor[i].eName, "WindDirection") != RT_NULL) || (strstr(sensor[i].eName, "360TO_") != RT_NULL))
  330. strcpy(sensor_value, Display_Data_wind_direction360(sensor[i].value)); //如果是风向则角度转为汉字
  331. else if (strcmp(sensor[i].eName, "RainSnow") == 0)
  332. {
  333. if (sensor[i].value == 0)
  334. strcpy(sensor_value, " 无 ");
  335. else if (sensor[i].value == 1)
  336. strcpy(sensor_value, " 有 ");
  337. }
  338. else
  339. strcpy(sensor_value, sensor[i].eValue);
  340. }
  341. if (qxz.Param.Dotled_Option > 1) //大于1,显示双色
  342. //total += rt_sprintf((char *)(buff + total),sensor[i].dotled_s, green, green, sensor_value);//2.7.8版本
  343. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, red, green, sensor_value);
  344. else
  345. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, red, red, sensor_value);
  346. }
  347. }
  348. return total; /* 返回前数据长度 */
  349. }
  350. uint16_t Area1_dis_format_PART(uint8_t *buff, uint8_t start, uint8_t len)
  351. {
  352. uint16_t i = 0;
  353. char sensor_value[50] = {0};
  354. uint16_t total = 0; /* 记录当前数据长度 */
  355. // char sensor_nop[4] = {0};
  356. //rt_kprintf("Area1_dis_format_PART > ");
  357. for (i = start; i < start + len; i++)
  358. {
  359. //rt_kprintf("%d ",i);
  360. rt_memset(sensor_value, 0, 50); //判断是否传感器未接或故障,如果是则显示为空
  361. if (strcmp(sensor[i].eName, "\0") != 0) /*传感器eName不能为空*/
  362. {
  363. if (strstr(sensor[i].eValue, "-99.99") == NULL)
  364. {
  365. if ((strstr(sensor[i].eName, "WindDirection") != RT_NULL) || (strstr(sensor[i].eName, "360TO_") != RT_NULL))
  366. strcpy(sensor_value, Display_Data_wind_direction360(sensor[i].value)); //如果是风向则角度转为汉字
  367. else if (strcmp(sensor[i].eName, "RainSnow") == 0)
  368. {
  369. if (sensor[i].value == 0)
  370. strcpy(sensor_value, " 无 ");
  371. else if (sensor[i].value == 1)
  372. strcpy(sensor_value, " 有 ");
  373. }
  374. else
  375. strcpy(sensor_value, sensor[i].eValue);
  376. }
  377. if (qxz.Param.Dotled_Option > 1) //大于1,显示双色
  378. //total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s,green, green, sensor_value);//2.7.8版本
  379. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, red, green, sensor_value);
  380. else
  381. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, red, red, sensor_value);
  382. }
  383. }
  384. //rt_kprintf("\n");
  385. // rt_kprintf(" >>> %s \n" , buff);
  386. return total; /* 返回前数据长度 */
  387. }
  388. void controller_type(uint8_t type)
  389. {
  390. switch (type)
  391. {
  392. case 1:
  393. header[10] = 0x51;
  394. break;
  395. case 2:
  396. header[10] = 0x52;
  397. break;
  398. case 3:
  399. header[10] = 0x53;
  400. break;
  401. default:
  402. break;
  403. }
  404. }
  405. static SYSTEMTIMESET TimeSet = {
  406. .Frame = frame, //帧头 8 bytes (A5)
  407. .Header = header, //包头 12 bytes (01 00 00 80 00 00 00 00 00 00 FE 02)
  408. .Len = {0, 0}, //整个发送数据除去帧头,包头,CRC校验后的长度 2 bytes
  409. .Cmd_Group = 0xA2,
  410. .Cmd = 0x03,
  411. .Response = 0x02,
  412. // .Reserved = {0,0},
  413. .DataLen = {0, 0},
  414. .System_time = 0,
  415. .crc_data = {0, 0}, //CRC
  416. };
  417. //控制卡校准时间
  418. void DotLED_TIMESET(uint8_t set)
  419. {
  420. uint16_t add_len = 0; //整个数据总长度
  421. uint16_t total = 0; /* 记录当前数据长度 */
  422. uint16_t crc_data = 0;
  423. // uint16_t i, j, t = 0;
  424. uint16_t t = 0;
  425. static uint8_t SETIME_RUN1TIME = 1; /*清除功能1次标志*/
  426. if ((hour == 1) || (set == 1)) //每天1点对时或强制对时
  427. {
  428. if (SETIME_RUN1TIME == 1)
  429. {
  430. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  431. Time2BCD((char *)TimeSet.System_time);
  432. total = 8;
  433. TimeSet.Len[0] = (char)((total + 5) & 0xff); /*计算动态区域0数据长度*/
  434. TimeSet.Len[1] = (char)((total + 5) >> 8);
  435. TimeSet.DataLen[0] = (char)(total & 0xff); /**/
  436. TimeSet.DataLen[1] = (char)(total >> 8);
  437. rt_memcpy(Dis_Comm + add_len, TimeSet.Header, 12);
  438. add_len = 12;
  439. rt_memcpy(Dis_Comm + add_len, TimeSet.Len, 2);
  440. add_len += 2;
  441. rt_memcpy(Dis_Comm + add_len, &TimeSet.Cmd_Group, 1);
  442. add_len += 1;
  443. rt_memcpy(Dis_Comm + add_len, &TimeSet.Cmd, 1);
  444. add_len += 1;
  445. rt_memcpy(Dis_Comm + add_len, &TimeSet.Response, 1);
  446. add_len += 1;
  447. // rt_memcpy(Dis_Comm + add_len , TimeSet.Reserved, 2);add_len += 2;
  448. rt_memcpy(Dis_Comm + add_len, TimeSet.DataLen, 2);
  449. add_len += 2;
  450. rt_memcpy(Dis_Comm + add_len, TimeSet.System_time, total);
  451. add_len += total;
  452. t = (TimeSet.Len[1] << 8) + TimeSet.Len[0];
  453. t = t + 14; //加Data_Field_1+数据长度2
  454. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  455. Dis_Comm[t] = crc_data >> 8;
  456. t = t + 1;
  457. Dis_Comm[t] = crc_data;
  458. t = t + 1;
  459. t = Escape_character(Dis_Comm, t); //字符转义处理
  460. Dis_Comm[t] = 0x5a;
  461. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH);
  462. rt_device_write(dotled, 0, TimeSet.Frame, 8);
  463. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  464. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  465. led_set_mode(DOTLED, 5, led_blink_mode_1);
  466. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  467. SETIME_RUN1TIME = 0; /*只运行一次*/
  468. rt_thread_mdelay(1000);
  469. }
  470. }
  471. else
  472. SETIME_RUN1TIME = 1; /*其他时间运行1次标志复位*/
  473. }
  474. //char time_test[] = "\\DL月\\DD日\\C3\\DH时\\DM分";//\\DS秒";
  475. static char time_YM[] = "\\C3 20\\DY年\\DL月"; //"\\C3\\DY 年\\DL月\\DD日\\C3\\DH时\\DM分\\DS秒
  476. static char time_DHM[] = "\\C3\\DD日\\C3\\DH时\\DM分";
  477. static char time_YMDHM[] = " 20\\DY年\\DL月\\DD日 \\C3 \\DH时\\DM分";
  478. //抬头:区域0显示函数,显示抬头
  479. void DotLED_DisplayTime(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t TURNON_RUN)
  480. {
  481. uint16_t add_len = 0; //整个数据总长度
  482. uint16_t total = 0; /* 记录当前数据长度 */
  483. rt_uint32_t e;
  484. uint16_t crc_data = 0;
  485. uint16_t i, j, t = 0;
  486. if ((rt_event_recv(&timed_events, timed_events_RTC,
  487. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  488. 0, &e) == RT_EOK) ||
  489. (TURNON_RUN == 1)) //定时时间到或者开机运行1次
  490. {
  491. rt_thread_mdelay(1000);
  492. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  493. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  494. bx_5k.AreaX[0] = (char)(x & 0xff);
  495. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  496. // bx_5k.AreaX[1] = (char)( x >> 8);
  497. bx_5k.AreaY[0] = (char)(y & 0xff);
  498. bx_5k.AreaY[1] = (char)(y >> 8);
  499. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  500. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  501. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  502. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  503. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  504. bx_5k.DynamicAreaLoc = 0x00; //设置动态区域为0
  505. bx_5k.Lines_sizes = 0; //行间距
  506. bx_5k.RunMode = 0x00; //动态区域运行模式,动态区数据循环显示*/
  507. bx_5k.Timeout[0] = 0x03; //
  508. bx_5k.Timeout[1] = 0x00; //超时时间
  509. bx_5k.SingleLine = 0x02; //设置是否单行显示 :01单行显示02多行显示
  510. bx_5k.NewLine = 0x01; //设置是否自动换行:01不自动换行 02自动换行
  511. /*正常显示抬头效果配置*/
  512. bx_5k.DisplayMode = 0x02; //设置显示方式:02快速打出/03向左移动
  513. bx_5k.ExitMode = 0x00; //设置退出方式
  514. bx_5k.Speed = 0x02; //设置运行速度
  515. bx_5k.StayTime = 0x05; //设置停留时间 0x01为0.5s
  516. if (qxz.Param.Dotled_Option != 1) //5k1显示整个内容
  517. {
  518. if (qxz.Param.application_model == 0) //当前应用模式:环境气象站
  519. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_YM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  520. else if (qxz.Param.application_model == 1) //当前应用模式:墒情监测站
  521. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_DHM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  522. }
  523. else
  524. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_YMDHM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  525. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  526. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  527. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  528. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  529. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  530. bx_5k.DataLen[1] = (char)(total >> 8);
  531. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  532. add_len = 12;
  533. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  534. add_len += 2;
  535. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  536. add_len += 2;
  537. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  538. add_len += 1;
  539. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  540. add_len += 2;
  541. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  542. add_len += 1;
  543. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  544. add_len += 1;
  545. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  546. add_len += 2;
  547. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  548. add_len += 1;
  549. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  550. add_len += 2;
  551. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  552. add_len += 2;
  553. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  554. add_len += 2;
  555. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  556. add_len += 2;
  557. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  558. add_len += 1;
  559. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  560. add_len += 1;
  561. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  562. add_len += 1;
  563. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  564. add_len += 2;
  565. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  566. add_len += 3;
  567. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  568. add_len += 1;
  569. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  570. add_len += 1;
  571. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  572. add_len += 1;
  573. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  574. add_len += 1;
  575. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  576. add_len += 1;
  577. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  578. add_len += 1;
  579. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  580. add_len += 4;
  581. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  582. add_len += total;
  583. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  584. t = t + 14; //加Data_Field_1+数据长度2
  585. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  586. Dis_Comm[t] = crc_data >> 8;
  587. t = t + 1;
  588. Dis_Comm[t] = crc_data;
  589. t = t + 1;
  590. t = Escape_character(Dis_Comm, t); //字符转义处理
  591. Dis_Comm[t] = 0x5a;
  592. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  593. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  594. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  595. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  596. led_set_mode(DOTLED, 5, led_blink_mode_1);
  597. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  598. }
  599. }
  600. //抬头:区域0显示函数,显示抬头
  601. void DotLED_DisplayArea0(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t TURNON_RUN)
  602. {
  603. uint16_t add_len = 0; //整个数据总长度
  604. uint16_t total = 0; /* 记录当前数据长度 */
  605. rt_uint32_t e;
  606. uint16_t crc_data = 0;
  607. uint16_t i, j, t = 0;
  608. if ((rt_event_recv(&timed_events, timed_events_TITLE,
  609. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  610. 0, &e) == RT_EOK) ||
  611. (TURNON_RUN == 1)) //定时时间到或者开机运行1次
  612. {
  613. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  614. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  615. bx_5k.AreaX[0] = (char)(x & 0xff);
  616. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  617. // bx_5k.AreaX[1] = (char)( x >> 8);
  618. bx_5k.AreaY[0] = (char)(y & 0xff);
  619. bx_5k.AreaY[1] = (char)(y >> 8);
  620. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  621. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  622. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  623. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  624. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  625. bx_5k.DynamicAreaLoc = 0x00; //设置动态区域为0
  626. bx_5k.Lines_sizes = 0; //行间距
  627. bx_5k.RunMode = 0x00; //动态区域运行模式,动态区数据循环显示*/
  628. bx_5k.Timeout[0] = 0x00; //
  629. bx_5k.Timeout[1] = 0x00; //超时时间
  630. bx_5k.SingleLine = 0x01; //设置是否单行显示 :单行显示
  631. bx_5k.NewLine = 0x01; //设置是否自动换行:不自动换行
  632. if (title_timeout == 0) //正常显示气象站抬头
  633. {
  634. /*正常显示抬头效果配置*/
  635. bx_5k.DisplayMode = 0x02; //设置显示方式:02快速打出/03向左移动/05向上移动
  636. bx_5k.ExitMode = 0x00; //设置退出方式
  637. bx_5k.Speed = 0x02; //设置运行速度
  638. bx_5k.StayTime = 0xa0; //设置停留时间 0x01为5s
  639. total += sprintf((char *)bx_5k.dis_buff + total, "%s", dotledtitle); //显示抬头
  640. }
  641. else //滚动显示下发内容
  642. {
  643. /*显示自定义抬头滚动效果配置*/
  644. bx_5k.DisplayMode = 0x03; //设置显示方式:02快速打出/03向左移动
  645. bx_5k.ExitMode = 0x00; //设置退出方式
  646. bx_5k.Speed = 0x04; //设置运行速度
  647. bx_5k.StayTime = 0x01; //设置停留时间 0x01为0.5s
  648. total += sprintf((char *)bx_5k.dis_buff + total, "%s", dotledtitle_down); //显示抬头
  649. }
  650. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  651. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  652. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  653. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  654. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  655. bx_5k.DataLen[1] = (char)(total >> 8);
  656. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  657. add_len = 12;
  658. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  659. add_len += 2;
  660. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  661. add_len += 2;
  662. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  663. add_len += 1;
  664. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  665. add_len += 2;
  666. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  667. add_len += 1;
  668. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  669. add_len += 1;
  670. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  671. add_len += 2;
  672. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  673. add_len += 1;
  674. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  675. add_len += 2;
  676. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  677. add_len += 2;
  678. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  679. add_len += 2;
  680. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  681. add_len += 2;
  682. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  683. add_len += 1;
  684. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  685. add_len += 1;
  686. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  687. add_len += 1;
  688. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  689. add_len += 2;
  690. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  691. add_len += 3;
  692. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  693. add_len += 1;
  694. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  695. add_len += 1;
  696. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  697. add_len += 1;
  698. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  699. add_len += 1;
  700. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  701. add_len += 1;
  702. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  703. add_len += 1;
  704. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  705. add_len += 4;
  706. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  707. add_len += total;
  708. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  709. t = t + 14; //加Data_Field_1+数据长度2
  710. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  711. Dis_Comm[t] = crc_data >> 8;
  712. t = t + 1;
  713. Dis_Comm[t] = crc_data;
  714. t = t + 1;
  715. t = Escape_character(Dis_Comm, t); //字符转义处理
  716. Dis_Comm[t] = 0x5a;
  717. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  718. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  719. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  720. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  721. led_set_mode(DOTLED, 5, led_blink_mode_1);
  722. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  723. rt_thread_mdelay(1000);
  724. }
  725. }
  726. //内容:区域1显示函数
  727. void DotLED_DisplayArea1(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t keeptime)
  728. {
  729. uint16_t add_len = 0; //整个数据总长度
  730. uint16_t total = 0; /* 记录当前数据长度 */
  731. uint16_t crc_data = 0;
  732. uint16_t i, j, t = 0;
  733. rt_uint32_t e;
  734. if (rt_event_recv(&timed_events, timed_events_MAIN,
  735. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  736. 0, &e) == RT_EOK)
  737. {
  738. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  739. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  740. bx_5k.AreaX[0] = (char)(x & 0xff);
  741. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  742. // bx_5k.AreaX[1] = (char)( x >> 8);
  743. bx_5k.AreaY[0] = (char)(y & 0xff);
  744. bx_5k.AreaY[1] = (char)(y >> 8);
  745. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  746. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  747. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  748. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  749. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  750. bx_5k.DynamicAreaLoc = 0x01; //设置动态区域为1
  751. bx_5k.Lines_sizes = 0; //行间距
  752. bx_5k.RunMode = 0x02; //动态区域运行模式,动态区数据循环显示,超过设定时间后数据仍未更新时不再显示*/
  753. bx_5k.Timeout[0] = 0xa0; //
  754. bx_5k.Timeout[1] = 0x00; //超时10s
  755. bx_5k.SingleLine = 0x02; //设置是否单行显示 :多行显示
  756. bx_5k.NewLine = 0x02; //设置是否自动换行:自动换行
  757. bx_5k.DisplayMode = 0x02; //设置显示方式:快速打出
  758. bx_5k.ExitMode = 0x00; //设置退出方式
  759. bx_5k.Speed = 0x02; //设置运行速度
  760. bx_5k.StayTime = keeptime; //设置停留时间 0x01为0.5s
  761. total = Area1_dis_format(bx_5k.dis_buff);
  762. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  763. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  764. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  765. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  766. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  767. bx_5k.DataLen[1] = (char)(total >> 8);
  768. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  769. add_len = 12;
  770. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  771. add_len += 2;
  772. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  773. add_len += 2;
  774. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  775. add_len += 1;
  776. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  777. add_len += 2;
  778. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  779. add_len += 1;
  780. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  781. add_len += 1;
  782. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  783. add_len += 2;
  784. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  785. add_len += 1;
  786. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  787. add_len += 2;
  788. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  789. add_len += 2;
  790. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  791. add_len += 2;
  792. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  793. add_len += 2;
  794. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  795. add_len += 1;
  796. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  797. add_len += 1;
  798. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  799. add_len += 1; //动态区域运行模式
  800. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  801. add_len += 2;
  802. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  803. add_len += 3;
  804. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  805. add_len += 1;
  806. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  807. add_len += 1;
  808. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  809. add_len += 1;
  810. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  811. add_len += 1;
  812. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  813. add_len += 1;
  814. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  815. add_len += 1;
  816. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  817. add_len += 4;
  818. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  819. add_len += total;
  820. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  821. t = t + 14; //加Data_Field_1+数据长度2
  822. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  823. Dis_Comm[t] = crc_data >> 8;
  824. t = t + 1;
  825. Dis_Comm[t] = crc_data;
  826. t = t + 1;
  827. t = Escape_character(Dis_Comm, t); //字符转义处理
  828. Dis_Comm[t] = 0x5a;
  829. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  830. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  831. rt_device_write(dotled, 0, Dis_Comm, t + 1);
  832. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  833. led_set_mode(DOTLED, 5, led_blink_mode_1);
  834. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  835. rt_thread_mdelay(1000);
  836. }
  837. }
  838. //显示清屏
  839. void DotLED_DisplayClear(void)
  840. {
  841. uint16_t add_len = 0; //整个数据总长度
  842. uint16_t total = 0; /* 记录当前数据长度 */
  843. char clr[] = {0x05, 0x00, 0xA3, 0x10, 0x01, 0x00, 0x00};
  844. uint16_t crc_data = 0;
  845. uint16_t i, j, t = 0;
  846. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  847. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  848. add_len = 12;
  849. rt_memcpy(Dis_Comm + add_len, clr, 7);
  850. add_len += 7;
  851. t = add_len;
  852. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  853. Dis_Comm[t] = crc_data >> 8;
  854. t = t + 1;
  855. Dis_Comm[t] = crc_data;
  856. t = t + 1;
  857. t = Escape_character(Dis_Comm, t); //字符转义处理
  858. Dis_Comm[t] = 0x5a;
  859. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  860. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  861. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  862. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  863. led_set_mode(DOTLED, 5, led_blink_mode_1);
  864. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  865. }
  866. //内容:区域1显示函数
  867. void DotLED_DisplayArea(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t keeptime, uint8_t DynamicArea)
  868. {
  869. uint16_t add_len = 0; //整个数据总长度
  870. uint16_t total = 0; /* 记录当前数据长度 */
  871. uint16_t crc_data = 0;
  872. uint16_t i, j, t = 0;
  873. rt_uint32_t e;
  874. // if (rt_event_recv(&timed_events, timed_events_MAIN,
  875. // RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  876. // 0, &e) == RT_EOK)
  877. if (1)
  878. {
  879. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  880. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  881. bx_5k.AreaX[0] = (char)(x & 0xff);
  882. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  883. // bx_5k.AreaX[1] = (char)( x >> 8);
  884. bx_5k.AreaY[0] = (char)(y & 0xff);
  885. bx_5k.AreaY[1] = (char)(y >> 8);
  886. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  887. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  888. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  889. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  890. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  891. bx_5k.DynamicAreaLoc = DynamicArea; //设置动态区域为1
  892. bx_5k.Lines_sizes = 0; //行间距
  893. bx_5k.RunMode = 0x02; //动态区域运行模式,动态区数据循环显示,超过设定时间后数据仍未更新时不再显示*/
  894. bx_5k.Timeout[0] = 0xa0; //
  895. bx_5k.Timeout[1] = 0x00; //超时10s
  896. bx_5k.SingleLine = 0x02; //设置是否单行显示 :多行显示
  897. bx_5k.NewLine = 0x02; //设置是否自动换行:自动换行
  898. bx_5k.DisplayMode = 0x02; //设置显示方式:快速打出
  899. bx_5k.ExitMode = 0x00; //设置退出方式
  900. bx_5k.Speed = 0x02; //设置运行速度
  901. bx_5k.StayTime = keeptime; //设置停留时间 0x01为0.5s
  902. total = Area1_dis_format(bx_5k.dis_buff);
  903. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  904. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  905. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  906. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  907. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  908. bx_5k.DataLen[1] = (char)(total >> 8);
  909. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  910. add_len = 12;
  911. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  912. add_len += 2;
  913. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  914. add_len += 2;
  915. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  916. add_len += 1;
  917. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  918. add_len += 2;
  919. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  920. add_len += 1;
  921. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  922. add_len += 1;
  923. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  924. add_len += 2;
  925. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  926. add_len += 1;
  927. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  928. add_len += 2;
  929. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  930. add_len += 2;
  931. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  932. add_len += 2;
  933. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  934. add_len += 2;
  935. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  936. add_len += 1;
  937. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  938. add_len += 1;
  939. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  940. add_len += 1; //动态区域运行模式
  941. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  942. add_len += 2;
  943. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  944. add_len += 3;
  945. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  946. add_len += 1;
  947. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  948. add_len += 1;
  949. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  950. add_len += 1;
  951. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  952. add_len += 1;
  953. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  954. add_len += 1;
  955. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  956. add_len += 1;
  957. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  958. add_len += 4;
  959. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  960. add_len += total;
  961. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  962. t = t + 14; //加Data_Field_1+数据长度2
  963. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  964. Dis_Comm[t] = crc_data >> 8;
  965. t = t + 1;
  966. Dis_Comm[t] = crc_data;
  967. t = t + 1;
  968. t = Escape_character(Dis_Comm, t); //字符转义处理
  969. Dis_Comm[t] = 0x5a;
  970. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  971. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  972. rt_device_write(dotled, 0, Dis_Comm, t + 1);
  973. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  974. led_set_mode(DOTLED, 5, led_blink_mode_1);
  975. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  976. rt_thread_mdelay(1000);
  977. }
  978. }
  979. /**
  980. * @brief 仅刷新部分区域的数据
  981. *
  982. * @param x 显示区域
  983. * @param y
  984. * @param Width
  985. * @param Height
  986. * @param keeptime 保留时间
  987. * @param DynamicArea 动态区
  988. * @param start 起始要素
  989. * @param len 要素数量
  990. */
  991. void DotLED_DisplayArea_PART(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t keeptime, uint8_t DynamicArea, uint8_t start, uint8_t len)
  992. {
  993. uint16_t add_len = 0; //整个数据总长度
  994. uint16_t total = 0; /* 记录当前数据长度 */
  995. uint16_t crc_data = 0;
  996. uint16_t i, j, t = 0;
  997. rt_uint32_t e;
  998. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  999. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  1000. bx_5k.AreaX[0] = (char)(x & 0xff);
  1001. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  1002. // bx_5k.AreaX[1] = (char)( x >> 8);
  1003. bx_5k.AreaY[0] = (char)(y & 0xff);
  1004. bx_5k.AreaY[1] = (char)(y >> 8);
  1005. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  1006. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  1007. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  1008. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  1009. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  1010. bx_5k.DynamicAreaLoc = DynamicArea; //设置动态区域为1
  1011. bx_5k.Lines_sizes = 0; //行间距
  1012. bx_5k.RunMode = 0x02; //动态区域运行模式,动态区数据循环显示,超过设定时间后数据仍未更新时不再显示*/
  1013. bx_5k.Timeout[0] = 0xa0; //
  1014. bx_5k.Timeout[1] = 0x00; //超时10s
  1015. bx_5k.SingleLine = 0x02; //设置是否单行显示 :多行显示
  1016. bx_5k.NewLine = 0x02; //设置是否自动换行:自动换行
  1017. bx_5k.DisplayMode = 0x02; //设置显示方式:快速打出
  1018. bx_5k.ExitMode = 0x00; //设置退出方式
  1019. bx_5k.Speed = 0x02; //设置运行速度
  1020. bx_5k.StayTime = keeptime; //设置停留时间 0x01为0.5s
  1021. total = Area1_dis_format_PART(bx_5k.dis_buff, start, len);
  1022. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  1023. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  1024. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  1025. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  1026. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  1027. bx_5k.DataLen[1] = (char)(total >> 8);
  1028. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  1029. add_len = 12;
  1030. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  1031. add_len += 2;
  1032. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  1033. add_len += 2;
  1034. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  1035. add_len += 1;
  1036. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  1037. add_len += 2;
  1038. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  1039. add_len += 1;
  1040. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  1041. add_len += 1;
  1042. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  1043. add_len += 2;
  1044. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  1045. add_len += 1;
  1046. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  1047. add_len += 2;
  1048. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  1049. add_len += 2;
  1050. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  1051. add_len += 2;
  1052. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  1053. add_len += 2;
  1054. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  1055. add_len += 1;
  1056. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  1057. add_len += 1;
  1058. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  1059. add_len += 1; //动态区域运行模式
  1060. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  1061. add_len += 2;
  1062. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  1063. add_len += 3;
  1064. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  1065. add_len += 1;
  1066. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  1067. add_len += 1;
  1068. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  1069. add_len += 1;
  1070. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  1071. add_len += 1;
  1072. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  1073. add_len += 1;
  1074. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  1075. add_len += 1;
  1076. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  1077. add_len += 4;
  1078. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  1079. add_len += total;
  1080. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  1081. t = t + 14; //加Data_Field_1+数据长度2
  1082. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  1083. Dis_Comm[t] = crc_data >> 8;
  1084. t = t + 1;
  1085. Dis_Comm[t] = crc_data;
  1086. t = t + 1;
  1087. t = Escape_character(Dis_Comm, t); //字符转义处理
  1088. Dis_Comm[t] = 0x5a;
  1089. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  1090. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  1091. rt_device_write(dotled, 0, Dis_Comm, t + 1);
  1092. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  1093. led_set_mode(DOTLED, 5, led_blink_mode_1);
  1094. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  1095. rt_thread_mdelay(1000);
  1096. }
  1097. //获取字符串长度
  1098. uint8_t sizeof_s(char *str)
  1099. {
  1100. uint8_t len = 0;
  1101. while (1)
  1102. {
  1103. if (*str == '\0')
  1104. break; //拷贝完成了.
  1105. len++;
  1106. str++;
  1107. }
  1108. return len;
  1109. }
  1110. //把str1的内容copy到str2
  1111. //*str1:字符串1指针
  1112. //*str2:字符串2指针
  1113. void strcopy(char *str1, char *str2)
  1114. {
  1115. while (1)
  1116. {
  1117. *str2 = *str1; //拷贝
  1118. if (*str1 == '\0')
  1119. break; //拷贝完成了.
  1120. str1++;
  1121. str2++;
  1122. }
  1123. }
  1124. //转义字符,输入:待转义字符指针,长度
  1125. uint16_t Escape_character(uint8_t *buff, uint16_t len)
  1126. {
  1127. uint16_t i, j, t;
  1128. uint8_t temp;
  1129. t = len;
  1130. for (i = 0; i < t; i++)
  1131. {
  1132. /*5A转义*/
  1133. if (buff[i] == 0x5A)
  1134. {
  1135. buff[i] = 0x5B;
  1136. /* 保存最右边的元素 */
  1137. temp = buff[t];
  1138. /* 从检测到需要转移的字符开始往右移动一个位值 */
  1139. for (j = t; j > i; j--)
  1140. {
  1141. buff[j] = buff[j - 1];
  1142. }
  1143. /* 数组加一位把最右边的元素补到最右边 */
  1144. t = t + 1;
  1145. buff[t] = temp;
  1146. /* 0X5A后面跟0x02 */
  1147. buff[i + 1] = 0x02;
  1148. }
  1149. /*A6转义*/
  1150. if (buff[i] == 0xA6)
  1151. {
  1152. if (buff[i + 1] != 0x02) /*判断不是转义后的数据*/
  1153. {
  1154. buff[i] = 0xA6;
  1155. /* 保存最右边的元素 */
  1156. temp = buff[t];
  1157. /* 从检测到需要转移的字符开始往右移动一个位值 */
  1158. for (j = t; j > i; j--)
  1159. {
  1160. buff[j] = buff[j - 1];
  1161. }
  1162. /* 数组加一位把最右边的元素补到最右边 */
  1163. t = t + 1;
  1164. buff[t] = temp;
  1165. /* 0X5A后面跟0x01 */
  1166. buff[i + 1] = 0x01;
  1167. }
  1168. }
  1169. /*A5转义*/
  1170. if (buff[i] == 0xA5)
  1171. {
  1172. buff[i] = 0xA6;
  1173. /* 保存最右边的元素 */
  1174. temp = buff[t];
  1175. /* 从检测到需要转移的字符开始往右移动一个位值 */
  1176. for (j = t; j > i; j--)
  1177. {
  1178. buff[j] = buff[j - 1];
  1179. }
  1180. /* 数组加一位把最右边的元素补到最右边 */
  1181. t = t + 1;
  1182. buff[t] = temp;
  1183. /* 0X5A后面跟0x02 */
  1184. buff[i + 1] = 0x02;
  1185. }
  1186. /*5B转义*/
  1187. if (buff[i] == 0x5B)
  1188. {
  1189. if (buff[i + 1] != 0x02) /*判断不是转义后的数据*/
  1190. {
  1191. buff[i] = 0x5B;
  1192. /* 保存最右边的元素 */
  1193. temp = buff[t];
  1194. /* 从检测到需要转移的字符开始往右移动一个位值 */
  1195. for (j = t; j > i; j--)
  1196. {
  1197. buff[j] = buff[j - 1];
  1198. }
  1199. /* 数组加一位把最右边的元素补到最右边 */
  1200. t = t + 1;
  1201. buff[t] = temp;
  1202. /* 0X5A后面跟0x01 */
  1203. buff[i + 1] = 0x01;
  1204. }
  1205. }
  1206. }
  1207. return t;
  1208. }
  1209. /*******************************************************************************************
  1210. 函数名称: String2BcdTime
  1211. 描 述 : 把文件名字符串转为BCD码时间
  1212. 输入参数: 将要转换的保存文件名字符串的数组 ,以及转换之后将要保存bcd时间的数组
  1213. 输出参数: 无
  1214. 返 回 : 无
  1215. ********************************************************************************************/
  1216. void Time2BCD(char *bcd_buf)
  1217. {
  1218. /* 文件名格式为: “2018-09-15 12:25:26 1” */
  1219. /* BCD 时间格式为 “18200915122526” */
  1220. char time_buf[50] = "\0";
  1221. sprintf(time_buf, "%d-%02d-%02d %02d:%02d:%02d %d", year, month,
  1222. day, hour, min, sec, week);
  1223. bcd_buf[0] = (unsigned char)((time_buf[2] - '0') << 4) + (time_buf[3] - '0');
  1224. bcd_buf[1] = (unsigned char)((time_buf[0] - '0') << 4) + (time_buf[1] - '0');
  1225. bcd_buf[2] = (unsigned char)((time_buf[5] - '0') << 4) + (time_buf[6] - '0');
  1226. bcd_buf[3] = (unsigned char)((time_buf[8] - '0') << 4) + (time_buf[9] - '0');
  1227. bcd_buf[4] = (unsigned char)((time_buf[11] - '0') << 4) + (time_buf[12] - '0');
  1228. bcd_buf[5] = (unsigned char)((time_buf[14] - '0') << 4) + (time_buf[15] - '0');
  1229. bcd_buf[6] = (unsigned char)((time_buf[17] - '0') << 4) + (time_buf[18] - '0');
  1230. bcd_buf[7] = (unsigned char)(time_buf[20] - '0');
  1231. }
  1232. /*控制led开关标志位*/
  1233. uint8_t led_onoff_flag = 0;
  1234. #ifdef DOTLED_ONOFF
  1235. /* 定时事件控制块 */
  1236. static struct rt_event onoff_events;
  1237. static rt_timer_t dotled_onoff_task;
  1238. char on_off[] = {0x06, 0x00, 0xA3, 0x00, 0x02, 0x01, 0x00, 0x01};
  1239. uint8_t onoff_buff[21] = {0};
  1240. static rt_uint32_t onoff_cnt = 0;
  1241. //屏幕开关机
  1242. void DotLED_TURN_ON_OFF(uint8_t OnOffFlag)
  1243. {
  1244. uint16_t add_len = 0; //整个数据总长度
  1245. uint16_t total = 0; /* 记录当前数据长度 */
  1246. uint16_t crc_data = 0;
  1247. uint16_t i, j, t = 0;
  1248. rt_memset(onoff_buff, '\0', sizeof(onoff_buff));
  1249. if (OnOffFlag == 0)
  1250. {
  1251. on_off[7] = 0x02;
  1252. if (dotled_onoff_task != RT_NULL)
  1253. {
  1254. rt_timer_stop(dotled_onoff_task);
  1255. }
  1256. led_onoff_flag = 0; //切换标志位
  1257. }
  1258. else if (OnOffFlag == 1) //开启屏幕后启动定时器
  1259. {
  1260. on_off[7] = 0x01; /* 启动定时器 1 */
  1261. if (dotled_onoff_task != RT_NULL)
  1262. {
  1263. rt_timer_start(dotled_onoff_task);
  1264. }
  1265. led_onoff_flag = 1; //切换标志位
  1266. }
  1267. else
  1268. return;
  1269. rt_memcpy(onoff_buff + add_len, header, 12);
  1270. add_len = 12;
  1271. rt_memcpy(onoff_buff + add_len, on_off, 8);
  1272. add_len += 8;
  1273. t = add_len;
  1274. crc_data = CRC16_IBM(onoff_buff, t); /*先计算出CRC值再来查询转义字符*/
  1275. t = Escape_character(onoff_buff, t); //字符转义处理
  1276. onoff_buff[t] = crc_data >> 8;
  1277. t = t + 1;
  1278. onoff_buff[t] = crc_data;
  1279. t = t + 1;
  1280. onoff_buff[t] = 0x5a;
  1281. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  1282. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  1283. rt_device_write(dotled, 0, onoff_buff, t + 1);
  1284. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  1285. led_set_mode(DOTLED, 5, led_blink_mode_1);
  1286. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  1287. rt_thread_mdelay(1000);
  1288. }
  1289. void test_on(void)
  1290. {
  1291. DotLED_TURN_ON_OFF(1);
  1292. }
  1293. void test_off(void)
  1294. {
  1295. DotLED_TURN_ON_OFF(0);
  1296. }
  1297. /* 导出到 msh 命令列表中 */
  1298. MSH_CMD_EXPORT(test_on, led test on);
  1299. MSH_CMD_EXPORT(test_off, led test off);
  1300. /* 关闭超时定时器超时函数 */
  1301. static void onoff_timed(void *parameter)
  1302. {
  1303. onoff_cnt++;
  1304. if ((onoff_cnt % 3600 == 0) && (onoff_cnt > 0)) //1小时后超时关闭
  1305. {
  1306. rt_event_send(&onoff_events, timed_events_onoff); //定时时间到,发送事件
  1307. onoff_cnt = 0;
  1308. }
  1309. }
  1310. void led_timeout_off(void)
  1311. {
  1312. rt_uint32_t e;
  1313. if (rt_event_recv(&onoff_events, timed_events_onoff,
  1314. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  1315. 0, &e) == RT_EOK)
  1316. {
  1317. DotLED_TURN_ON_OFF(0);
  1318. }
  1319. }
  1320. #endif
  1321. static void dotled_thread_entry(void *parameter)
  1322. {
  1323. /*延时等待开机年月日时间全部标量赋值*/
  1324. rt_thread_mdelay(20000);
  1325. rt_pin_mode(RS485_DOTLED_EN, PIN_MODE_OUTPUT);
  1326. DotLED_TIMESET(1); //开机对rtc时间
  1327. rt_thread_mdelay(1000);
  1328. uint8_t Screen_Cnt = 0;
  1329. uint8_t len = 0;
  1330. uint8_t All_elem = 0;
  1331. while (qxz.Param.Dotled_Option >= 1 && qxz.Param.Dotled_Option <= 3)
  1332. {
  1333. All_elem = qxz.Param.Num_sensors;
  1334. for (uint8_t c = 0; c < qxz.Param.Num_sensors; c++)
  1335. {
  1336. if (strstr(sensor[c].eName, "ALINE") != NULL)
  1337. {
  1338. All_elem++;
  1339. }
  1340. if (strstr(sensor[c].eName, "SLINE") != NULL)
  1341. {
  1342. All_elem--;
  1343. }
  1344. }
  1345. //rt_kprintf("All_elem = %d > %d \n" , qxz.Param.Num_sensors,All_elem);
  1346. screen_line = qxz.Param.dotled_p0.Height / qxz.Param.dotled_p0.front; //每页可以显示的条数
  1347. main_keeptime = qxz.Param.dotled_p0.keep_time; //每页停留时间
  1348. Screen_Cnt = All_elem / screen_line; //一共需要翻几页
  1349. if (Screen_Cnt == 0)
  1350. {
  1351. Screen_Cnt = 1;
  1352. }
  1353. if (Screen_Cnt * screen_line < All_elem)
  1354. {
  1355. Screen_Cnt += 1;
  1356. }
  1357. //rt_kprintf("Ready To Display \n");
  1358. //rt_kprintf("There are %d pages, %d lines per page, and a total of %d elem_space > %d s\n\n", Screen_Cnt, screen_line, All_elem, main_keeptime);
  1359. for (uint8_t b = 0; b < qxz.Param.Num_sensors; b += len)
  1360. {
  1361. //rt_kprintf("if %d == %d \n" , (b + screen_line) , All_elem);
  1362. if ((b + screen_line) >= All_elem && (Screen_Cnt * screen_line) > All_elem)
  1363. {
  1364. len = (Screen_Cnt * screen_line) % All_elem;
  1365. len = screen_line - len;
  1366. //rt_kprintf(" len = %d\n" ,len);
  1367. }
  1368. else
  1369. {
  1370. len = screen_line;
  1371. }
  1372. for (uint8_t d = b; d < b + len; d++)
  1373. {
  1374. //rt_kprintf("for (uint8_t d = b > %s %d\n" ,sensor[d + 0].eName,len);
  1375. if (d > b && strstr(sensor[d - 1].eName, "ALINE") != NULL && len > 0)
  1376. {
  1377. len--;
  1378. }
  1379. if (strstr(sensor[d + 1].eName, "SLINE") != NULL && len > 0)
  1380. {
  1381. len++;
  1382. //rt_kprintf("sensor[d - 1].eName ++ %s\n" , sensor[d - 1].eName);
  1383. }
  1384. }
  1385. //rt_kprintf("DotLED_DisplayArea_PART B = %d len = %d\n\n\n" ,b,len);
  1386. DotLED_DisplayArea_PART(qxz.Param.dotled_p0.Start_x, qxz.Param.dotled_p0.Start_y,
  1387. qxz.Param.dotled_p0.Width, qxz.Param.dotled_p0.Height,
  1388. (qxz.Param.dotled_p0.keep_time * 2), 0,
  1389. b, len);
  1390. if (qxz.Param.dotled_p0.keep_time > 0)
  1391. {
  1392. rt_thread_mdelay(qxz.Param.dotled_p0.keep_time * 850);
  1393. }
  1394. }
  1395. DotLED_TIMESET(0); //对rtc时间
  1396. rt_thread_mdelay(500);
  1397. }
  1398. }
  1399. // led点阵屏控制线程
  1400. static int dotled_thread(int argc, char *argv[])
  1401. {
  1402. rt_err_t ret = RT_EOK;
  1403. char uart_name[RT_NAME_MAX];
  1404. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
  1405. uint8_t dotled_size;
  1406. #ifndef dot_mod
  1407. if (qxz.Param.Dotled_Option >= 1 && qxz.Param.Dotled_Option <= 3) //led点阵屏使能
  1408. {
  1409. #endif
  1410. /*按照屏幕型号赋值整屏显示数据的行数*/
  1411. // ef_get_env_blob("Dotled_Size", &dotled_size, sizeof(dotled_size), RT_NULL);
  1412. // if (dotled_size == 1)screen_line = 3;
  1413. // else if (dotled_size == 2)screen_line = 6;
  1414. // else if (dotled_size == 3)screen_line = 5;
  1415. controller_type(qxz.Param.Dotled_Option); //计算控制卡型号
  1416. Dis_Comm = (unsigned char *)rt_malloc(dis_buff_len + 300);
  1417. if (Dis_Comm == RT_NULL)
  1418. {
  1419. log_i("Dis_Comm out of memory");
  1420. ret = RT_ERROR;
  1421. goto __exit;
  1422. }
  1423. bx_5k.dis_buff = (unsigned char *)rt_malloc(dis_buff_len);
  1424. if (Dis_Comm == RT_NULL)
  1425. {
  1426. log_i("bx_5k.dis_buff out of memory");
  1427. ret = RT_ERROR;
  1428. goto __exit;
  1429. }
  1430. /* 初始化事件对象 */
  1431. ret = rt_event_init(&timed_events, "event", RT_IPC_FLAG_FIFO);
  1432. if (ret != RT_EOK)
  1433. {
  1434. log_i("init event failed.\n");
  1435. return ret;
  1436. }
  1437. /* 创建定时器 1 周期定时器 */
  1438. dotled_timed_task = rt_timer_create("dotled_timer", dotled_timed,
  1439. (void *)1, 1000,
  1440. RT_TIMER_FLAG_PERIODIC);
  1441. /* 启动定时器 1 */
  1442. if (dotled_timed_task != RT_NULL)
  1443. rt_timer_start(dotled_timed_task);
  1444. #ifdef DOTLED_ONOFF
  1445. /* 初始化事件对象 */
  1446. ret = rt_event_init(&onoff_events, "event_on", RT_IPC_FLAG_FIFO);
  1447. if (ret != RT_EOK)
  1448. {
  1449. log_i("init event failed.\n");
  1450. return ret;
  1451. }
  1452. /* 创建定时器 用于开关屏超时控制 */
  1453. dotled_onoff_task = rt_timer_create("dotled_onoff", onoff_timed,
  1454. (void *)1, 1000,
  1455. RT_TIMER_FLAG_PERIODIC);
  1456. /* 启动定时器 1 */
  1457. if (dotled_onoff_task != RT_NULL)
  1458. rt_timer_start(dotled_onoff_task);
  1459. #endif
  1460. /* 查找串口设备 */
  1461. rt_strncpy(uart_name, DOTLED_UART_NAME, RT_NAME_MAX);
  1462. dotled = rt_device_find(uart_name);
  1463. if (!dotled)
  1464. {
  1465. rt_kprintf("find %s failed!\n", uart_name);
  1466. return RT_ERROR;
  1467. }
  1468. /* step2:修改串口配置参数 */
  1469. config.baud_rate = BAUD_RATE_57600; //修改波特率为57600
  1470. config.data_bits = DATA_BITS_8; //数据位 8
  1471. config.stop_bits = STOP_BITS_1; //停止位 1
  1472. config.bufsz = 1024; //修改缓冲区 buff size 为 128
  1473. config.parity = PARITY_NONE; //无奇偶校验位
  1474. /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */
  1475. rt_device_control(dotled, RT_DEVICE_CTRL_CONFIG, &config);
  1476. rt_device_open(dotled, RT_DEVICE_FLAG_INT_RX);
  1477. /* 创建 serial 线程 */
  1478. rt_thread_t thread1 = rt_thread_create("dotled", dotled_thread_entry, RT_NULL, 2048, 17, 10);
  1479. /* 创建成功则启动线程 */
  1480. if (thread1 != RT_NULL)
  1481. {
  1482. rt_thread_startup(thread1);
  1483. }
  1484. else
  1485. {
  1486. ret = RT_ERROR;
  1487. }
  1488. #ifndef dot_mod
  1489. }
  1490. else
  1491. ret = RT_EEMPTY;
  1492. #endif
  1493. __exit:
  1494. if (ret == RT_EOK)
  1495. {
  1496. return ret;
  1497. }
  1498. else
  1499. {
  1500. rt_free(Dis_Comm);
  1501. Dis_Comm = RT_NULL;
  1502. rt_free(bx_5k.dis_buff);
  1503. bx_5k.dis_buff = RT_NULL;
  1504. }
  1505. return ret;
  1506. }
  1507. INIT_APP_EXPORT(dotled_thread);