dotled_y.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  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. extern char *Display_Data_wind_direction360(uint16_t direction);
  18. #define RS485_DOTLED_EN GET_PIN(D, 1)
  19. #define DOTLED_UART_NAME "uart3" /* 串口设备名称 */
  20. /* 串口设备句柄 */
  21. static rt_device_t dotled;
  22. #define timed_events_TITLE (1 << 0) //标题刷新计时
  23. #define timed_events_MAIN (1 << 1) //内容刷新计时
  24. #define timed_events_RTC (1 << 2) //时间显示刷新计时
  25. /* 定时事件控制块 */
  26. static struct rt_event timed_events;
  27. /* 定时器的控制块 */
  28. static rt_timer_t dotled_timed_task;
  29. #define dis_buff_len 40 * qxz.Param.Num_sensors
  30. /*1米*0.5米屏幕点阵为 96*48 */
  31. /*1米* 1米屏幕点阵为 96*96 */
  32. /*2米* 1米屏幕点阵为192*96 */
  33. static char dotledtitle[60]; // LED显示屏抬头,最大显示30个汉字
  34. static char dotledtitle_down[60]; // LED显示屏下发抬头内容,最大显示30个汉字
  35. static uint32_t title_timeout = 0; // 下发后抬头显示超时失效时间。
  36. static uint16_t main_keeptime = 16; //主显示区单页面显示时长,0.5s步进
  37. /*屏幕显示行数 1 * 0.5米为96*48点阵,显示3行
  38. *屏幕显示行数 1 * 1米为96*96点阵, 显示6行
  39. *屏幕显示行数 2 * 1米为192*96点阵, 显示5行
  40. */
  41. static uint16_t screen_line = 12;
  42. //点阵屏尺寸规格区分标志位
  43. //static uint8_t dotled_size = 0;SoilTemperature
  44. static char *green = "\\C2";
  45. static char *red = "\\C2";
  46. // static char *red = "";
  47. //char *font = "\\F0021"; //字体
  48. /*发送显示数据使用缓存指针*/
  49. static uint8_t *Dis_Comm = RT_NULL;
  50. //static uint8_t *dis_buff = RT_NULL;
  51. //转义字符,输入:待转义字符指针,长度
  52. extern uint16_t Escape_character(uint8_t *buff, uint16_t len);
  53. extern void Time2BCD(char *bcd_buf);
  54. static uint8_t frame[8] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5}; //包头
  55. static uint8_t header[12] = {0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02}; //帧头,5K1,5K2屏幕区分
  56. //十进制转ASCII码
  57. #define KB2ASC(x) (u8)(0x30 + x)
  58. //ASCII码转十进制
  59. #define ASC2KB(x) (u8)(x % (0x30))
  60. #define PLOY 0xa001 //0x8005 反转
  61. //static uint8_t crc16(uint8_t *data, uint8_t size);
  62. //获取字符串长度
  63. extern uint8_t sizeof_s(char *str);
  64. //把str1的内容copy到str2
  65. //*str1:字符串1指针
  66. //*str2:字符串2指针
  67. extern void strcopy(char *str1, char *str2);
  68. /* 定时器超时函数 */
  69. static void dotled_timed(void *parameter)
  70. {
  71. static rt_uint32_t cnt = 0;
  72. cnt++;
  73. rt_uint8_t temp;
  74. if (cnt % ((rt_uint32_t)parameter * main_keeptime * ((qxz.Param.Num_sensors / screen_line) + 3)) == 0)
  75. {
  76. rt_event_send(&timed_events, timed_events_TITLE); //定时时间到,发送事件
  77. }
  78. if (qxz.Param.Num_sensors % screen_line != 0)
  79. {
  80. temp = qxz.Param.Num_sensors / screen_line + 1;
  81. }
  82. else
  83. temp = qxz.Param.Num_sensors / screen_line;
  84. if (cnt % ((rt_uint32_t)parameter * (uint16_t)(main_keeptime / 2) * temp) == 0) //
  85. {
  86. rt_event_send(&timed_events, timed_events_MAIN); //定时时间到,发送事件
  87. }
  88. if (cnt % 3600 == 0) //1小时刷新1次
  89. {
  90. rt_event_send(&timed_events, timed_events_RTC); //定时时间到,发送事件
  91. }
  92. }
  93. //参数结构变量赋初值
  94. static bx_5k_area_header bx_5k = {
  95. .Frame = frame, //帧头 8 bytes (A5)
  96. .Header = header, //包头 12 bytes (01 00 00 80 00 00 00 00 00 00 FE 02)
  97. .Len = {0, 0}, //整个发送数据除去帧头,包头,CRC校验后的长度 2 bytes
  98. .Cmd_dis = {0xa3, 0x06}, //发送实时显示信息命令 A3 06
  99. .Reply_f = 0x01, //控制器回复标志 01
  100. .Reserved0 = {0x00, 0x00}, //2D 00→保留字节(此值未使用)
  101. .Areadealnum = 0, //00→要删除的区域个数
  102. .AreaNum = 0x01, //区域个数,默认为 0x01,1 bytes
  103. .AreaLen = {0, 0}, //动态区域0数据长度,2 bytes
  104. .AreaType = 0x00, //设置区域类型,默认为 0x00 1 bytes
  105. .AreaX = {0x00, 0}, //设置 X 坐标 2 bytes
  106. .AreaY = {0x00, 0}, //设置 Y 坐标 2 bytes
  107. .AreaWidth = {0x80, 0}, //设置屏宽度 2 bytes
  108. .AreaHeight = {0x34, 0}, //设置屏高度 2 bytes
  109. .DynamicAreaLoc = 1, //设置动态区编号 1 bytes
  110. .Lines_sizes = 0, //行间距
  111. .RunMode = 0, //动态区数据循环模式 1 bytes
  112. .Timeout = {0x05, 0x00}, //设置超时时间 2 bytes
  113. .Reserved1 = {0, 0, 0}, //保留 3 bytes
  114. .SingleLine = 0x02, //设置是否单行显示 1 bytes
  115. .NewLine = 0x02, //设置是否自动换行 1 bytes
  116. .DisplayMode = 0x02, //设置显示方式 1 bytes 01静止显示
  117. .ExitMode = 0x00, //设置退出方式 1 bytes
  118. .Speed = 0x02, //设置运行速度 1 bytes
  119. .StayTime = 0x05, //设置停留时间 1 bytes
  120. .DataLen = {0, 0, 0, 0}, //要显示内容的个数 4 bytes
  121. .dis_buff = 0, //显示内容
  122. .crc_data = {0, 0}, //CRC
  123. };
  124. // /*刷新风向传感器数据*/
  125. // char *Display_Data_wind_direction360(uint16_t direction)
  126. // {
  127. // uint8_t temp;
  128. // #ifdef saitong_sensor
  129. // temp = (uint8_t)(direction / 10 / 22.5);
  130. // #else
  131. // temp = (uint8_t)(direction / 22.5);
  132. // #endif
  133. // static char direction_op[10];
  134. // switch (temp)
  135. // {
  136. // case 0:
  137. // rt_memset(direction_op, '\0', 10);
  138. // sprintf(direction_op, "%s", "北风 ");
  139. // break;
  140. // case 1:
  141. // rt_memset(direction_op, '\0', 10);
  142. // sprintf(direction_op, "%s", "东北风");
  143. // break;
  144. // case 2:
  145. // rt_memset(direction_op, '\0', 10);
  146. // sprintf(direction_op, "%s", "东北风");
  147. // break;
  148. // case 3:
  149. // rt_memset(direction_op, '\0', 10);
  150. // sprintf(direction_op, "%s", "东风 ");
  151. // break;
  152. // case 4:
  153. // rt_memset(direction_op, '\0', 10);
  154. // sprintf(direction_op, "%s", "东风 ");
  155. // break;
  156. // case 5:
  157. // rt_memset(direction_op, '\0', 10);
  158. // sprintf(direction_op, "%s", "东南风");
  159. // break;
  160. // case 6:
  161. // rt_memset(direction_op, '\0', 10);
  162. // sprintf(direction_op, "%s", "东南风");
  163. // break;
  164. // case 7:
  165. // rt_memset(direction_op, '\0', 10);
  166. // sprintf(direction_op, "%s", "南风 ");
  167. // break;
  168. // case 8:
  169. // rt_memset(direction_op, '\0', 10);
  170. // sprintf(direction_op, "%s", "南风 ");
  171. // break;
  172. // case 9:
  173. // rt_memset(direction_op, '\0', 10);
  174. // sprintf(direction_op, "%s", "西南风");
  175. // break;
  176. // case 10:
  177. // rt_memset(direction_op, '\0', 10);
  178. // sprintf(direction_op, "%s", "西南风");
  179. // break;
  180. // case 11:
  181. // rt_memset(direction_op, '\0', 10);
  182. // sprintf(direction_op, "%s", "西风 ");
  183. // break;
  184. // case 12:
  185. // rt_memset(direction_op, '\0', 10);
  186. // sprintf(direction_op, "%s", "西风 ");
  187. // break;
  188. // case 13:
  189. // rt_memset(direction_op, '\0', 10);
  190. // sprintf(direction_op, "%s", "西北风");
  191. // break;
  192. // case 14:
  193. // rt_memset(direction_op, '\0', 10);
  194. // sprintf(direction_op, "%s", "西北风");
  195. // break;
  196. // case 15:
  197. // rt_memset(direction_op, '\0', 10);
  198. // sprintf(direction_op, "%s", "北风 ");
  199. // break;
  200. // default:
  201. // break;
  202. // }
  203. // return direction_op;
  204. // }
  205. // //区域1显示数据格式化,返回长度
  206. // uint16_t Area1_dis_format(uint8_t *buff)
  207. // {
  208. // uint16_t i = 0;
  209. // char sensor_value[50] = {0};
  210. // uint16_t total = 0; /* 记录当前数据长度 */
  211. // char sensor_nop[4] = {0};
  212. // //加上字体大小
  213. // total = rt_sprintf((char *)buff, "%s", font);
  214. // for (i = 0; i < qxz.Param.Num_sensors; i++)
  215. // {
  216. // rt_memset(sensor_value, 0, 50); //判断是否传感器未接或故障,如果是则显示为空
  217. // if (strcmp(sensor[i].eName, "\0") != 0) /*传感器eName不能为空*/
  218. // {
  219. // if (strstr(sensor[i].eValue, "-99.99") == NULL)
  220. // {
  221. // if (strcmp(sensor[i].eName, "WindDirection") == 0)
  222. // strcpy(sensor_value, Display_Data_wind_direction360(sensor[i].value)); //如果是风向则角度转为汉字
  223. // else if (strcmp(sensor[i].eName, "RainSnow") == 0)
  224. // {
  225. // if (sensor[i].value == 0)
  226. // strcpy(sensor_value, " 无 ");
  227. // else if (sensor[i].value == 1)
  228. // strcpy(sensor_value, " 有 ");
  229. // }
  230. // else
  231. // strcpy(sensor_value, sensor[i].eValue);
  232. // }
  233. // total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, green , green , sensor_value);
  234. // }
  235. // }
  236. // return total; /* 返回前数据长度 */
  237. // }
  238. /*区域1显示数据格式化,返回长度*/
  239. /*pos 需要截断显示的要素位置,DynamicArea 显示动态区域编号*/
  240. // Control_card != 5 && //Y1A 单区域(1Bit)
  241. // Control_card != 6 && //Y1A 单区域(8Bit)
  242. // Control_card != 7 && //Y1A 双区域(1Bit)
  243. // Control_card != 8) //Y1A 双区域(8Bit)
  244. uint16_t Area1_dis_format_area(uint8_t *buff, uint8_t pos, uint8_t DynamicArea)
  245. {
  246. uint16_t i = 0;
  247. char sensor_value[50] = {0};
  248. uint16_t total = 0; /* 记录当前数据长度 */
  249. // char sensor_nop[4] = {0};
  250. uint8_t ForTime_D0 = 0, ForTime_D1 = 0, ForStart_D0 = 0, ForStart_D1 = 0;
  251. if (qxz.Param.Dotled_Option == 5 || qxz.Param.Dotled_Option == 6)
  252. {
  253. ForTime_D0 = qxz.Param.Num_sensors;
  254. ForStart_D0 = 0;
  255. }
  256. else if (qxz.Param.Dotled_Option == 7 || qxz.Param.Dotled_Option == 8)
  257. {
  258. ForStart_D0 = 0;
  259. ForTime_D0 = qxz.Param.Num_sensors / 2;
  260. ForStart_D1 = qxz.Param.Num_sensors / 2;
  261. ForTime_D1 = qxz.Param.Num_sensors;
  262. }
  263. //加上字体大小
  264. total = rt_sprintf((char *)buff, "\\F00%02d", qxz.Param.dotled_p0.front);
  265. if (DynamicArea == 0)
  266. {
  267. // rt_kprintf("MARK 0 \n\n");
  268. for (i = ForStart_D0; i < ForTime_D0; i++)
  269. {
  270. rt_memset(sensor_value, 0, 50); //判断是否传感器未接或故障,如果是则显示为空
  271. // rt_kprintf("MARK 1 \n");
  272. if (strcmp(sensor[i].eName, "\0") != 0) /*传感器eName不能为空*/
  273. {
  274. // rt_kprintf("MARK 2 \n");
  275. if (strstr(sensor[i].eValue, "-99.99") == NULL && sensor[i].online_flag == 1)
  276. {
  277. // rt_kprintf("MARK 3 \n");
  278. //if (strstr(sensor[i].eName, "WindDirection") != RT_NULL)//xz 2.7.5改strcmp(==0)-> strstr(!=RT_NULL)
  279. if ((strstr(sensor[i].eName, "WindDirection") != RT_NULL) || (strstr(sensor[i].eName, "360TO_") != RT_NULL))
  280. strcpy(sensor_value, Display_Data_wind_direction360(sensor[i].value)); //如果是风向则角度转为汉字
  281. else if (strcmp(sensor[i].eName, "RainSnow") == 0)
  282. {
  283. if (sensor[i].value == 0)
  284. strcpy(sensor_value, " 无 ");
  285. else if (sensor[i].value == 1)
  286. strcpy(sensor_value, " 有 ");
  287. }
  288. else
  289. strcpy(sensor_value, sensor[i].eValue);
  290. }
  291. else
  292. {
  293. // rt_kprintf("MARK 4 \n");
  294. rt_sprintf(sensor_value, "-99.99");
  295. }
  296. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, green, red, sensor_value);
  297. //rt_kprintf("%s eval >%s \n",sensor[i].eName , sensor_value);
  298. }
  299. }
  300. }
  301. else if (DynamicArea == 1)
  302. {
  303. for (i = ForStart_D1; i < ForTime_D1; i++)
  304. {
  305. rt_memset(sensor_value, 0, 50); //判断是否传感器未接或故障,如果是则显示为空
  306. if (strcmp(sensor[i].eName, "\0") != 0) /*传感器eName不能为空*/
  307. {
  308. if (strstr(sensor[i].eValue, "-99.99") == NULL)
  309. {
  310. //if (strstr(sensor[i].eName, "WindDirection") != RT_NULL)//xz 2.7.5改strcmp(==0)-> strstr(!=RT_NULL)
  311. if ((strstr(sensor[i].eName, "WindDirection") != RT_NULL) || (strstr(sensor[i].eName, "360TO_") != RT_NULL))
  312. strcpy(sensor_value, Display_Data_wind_direction360(sensor[i].value)); //如果是风向则角度转为汉字
  313. else if (strcmp(sensor[i].eName, "RainSnow") == 0)
  314. {
  315. if (sensor[i].value == 0)
  316. strcpy(sensor_value, " 无 ");
  317. else if (sensor[i].value == 1)
  318. strcpy(sensor_value, " 有 ");
  319. }
  320. else
  321. strcpy(sensor_value, sensor[i].eValue);
  322. }
  323. total += rt_sprintf((char *)(buff + total), sensor[i].dotled_s, green, sensor_value, red);
  324. }
  325. }
  326. }
  327. return total; /* 返回前数据长度 */
  328. }
  329. //计算控制卡型号:
  330. // void controller_type(uint8_t type)
  331. // {
  332. // switch (type)
  333. // {
  334. // case 1:
  335. // header[10] = 0x51;
  336. // break;
  337. // case 2:
  338. // header[10] = 0x52;
  339. // break;
  340. // case 3:
  341. // header[10] = 0x53;
  342. // break;
  343. // default:
  344. // break;
  345. // }
  346. // }
  347. static SYSTEMTIMESET TimeSet = {
  348. .Frame = frame, //帧头 8 bytes (A5)
  349. .Header = header, //包头 12 bytes (01 00 00 80 00 00 00 00 00 00 FE 02)
  350. .Len = {0, 0}, //整个发送数据除去帧头,包头,CRC校验后的长度 2 bytes
  351. .Cmd_Group = 0xA2,
  352. .Cmd = 0x03,
  353. .Response = 0x02,
  354. // .Reserved = {0,0},
  355. .DataLen = {0, 0},
  356. .System_time = 0,
  357. .crc_data = {0, 0}, //CRC
  358. };
  359. //控制卡校准时间
  360. void DotLED_TIMESET_y(uint8_t set)
  361. {
  362. uint16_t add_len = 0; //整个数据总长度
  363. uint16_t total = 0; /* 记录当前数据长度 */
  364. uint16_t crc_data = 0;
  365. // uint16_t i, j, t = 0;
  366. uint16_t t = 0;
  367. static uint8_t SETIME_RUN1TIME = 1; /*清除功能1次标志*/
  368. if ((hour == 1) || (set == 1)) //每天1点对时或强制对时
  369. {
  370. if (SETIME_RUN1TIME == 1)
  371. {
  372. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  373. Time2BCD((char *)TimeSet.System_time);
  374. total = 8;
  375. TimeSet.Len[0] = (char)((total + 5) & 0xff); /*计算动态区域0数据长度*/
  376. TimeSet.Len[1] = (char)((total + 5) >> 8);
  377. TimeSet.DataLen[0] = (char)(total & 0xff); /**/
  378. TimeSet.DataLen[1] = (char)(total >> 8);
  379. rt_memcpy(Dis_Comm + add_len, TimeSet.Header, 12);
  380. add_len = 12;
  381. rt_memcpy(Dis_Comm + add_len, TimeSet.Len, 2);
  382. add_len += 2;
  383. rt_memcpy(Dis_Comm + add_len, &TimeSet.Cmd_Group, 1);
  384. add_len += 1;
  385. rt_memcpy(Dis_Comm + add_len, &TimeSet.Cmd, 1);
  386. add_len += 1;
  387. rt_memcpy(Dis_Comm + add_len, &TimeSet.Response, 1);
  388. add_len += 1;
  389. // rt_memcpy(Dis_Comm + add_len , TimeSet.Reserved, 2);add_len += 2;
  390. rt_memcpy(Dis_Comm + add_len, TimeSet.DataLen, 2);
  391. add_len += 2;
  392. rt_memcpy(Dis_Comm + add_len, TimeSet.System_time, total);
  393. add_len += total;
  394. t = (TimeSet.Len[1] << 8) + TimeSet.Len[0];
  395. t = t + 14; //加Data_Field_1+数据长度2
  396. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  397. Dis_Comm[t] = crc_data >> 8;
  398. t = t + 1;
  399. Dis_Comm[t] = crc_data;
  400. t = t + 1;
  401. t = Escape_character(Dis_Comm, t); //字符转义处理
  402. Dis_Comm[t] = 0x5a;
  403. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH);
  404. rt_device_write(dotled, 0, TimeSet.Frame, 8);
  405. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  406. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  407. led_set_mode(DOTLED, 5, led_blink_mode_1);
  408. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  409. SETIME_RUN1TIME = 0; /*只运行一次*/
  410. }
  411. }
  412. else
  413. SETIME_RUN1TIME = 1; /*其他时间运行1次标志复位*/
  414. }
  415. //char time_test[] = "\\DL月\\DD日\\C3\\DH时\\DM分";//\\DS秒";
  416. static char time_YM[] = "\\C3 20\\DY年\\DL月"; //"\\C3\\DY 年\\DL月\\DD日\\C3\\DH时\\DM分\\DS秒
  417. static char time_DHM[] = "\\C3\\DD日\\C3\\DH时\\DM分";
  418. static char time_YMDHM[] = " 20\\DY年\\DL月\\DD日 \\C3 \\DH时\\DM分";
  419. //抬头:区域0显示函数,显示抬头
  420. void DotLED_DisplayTime_y(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t TURNON_RUN)
  421. {
  422. uint16_t add_len = 0; //整个数据总长度
  423. uint16_t total = 0; /* 记录当前数据长度 */
  424. rt_uint32_t e;
  425. uint16_t crc_data = 0;
  426. // uint16_t i, j, t = 0;
  427. uint16_t t = 0;
  428. if ((rt_event_recv(&timed_events, timed_events_RTC,
  429. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  430. 0, &e) == RT_EOK) ||
  431. (TURNON_RUN == 1)) //定时时间到或者开机运行1次
  432. {
  433. rt_thread_mdelay(1000);
  434. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  435. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  436. bx_5k.AreaX[0] = (char)(x & 0xff);
  437. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  438. // bx_5k.AreaX[1] = (char)( x >> 8);
  439. bx_5k.AreaY[0] = (char)(y & 0xff);
  440. bx_5k.AreaY[1] = (char)(y >> 8);
  441. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  442. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  443. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  444. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  445. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  446. bx_5k.DynamicAreaLoc = 0x00; //设置动态区域为0
  447. bx_5k.Lines_sizes = 0; //行间距
  448. bx_5k.RunMode = 0x00; //动态区域运行模式,动态区数据循环显示*/
  449. bx_5k.Timeout[0] = 0x03; //
  450. bx_5k.Timeout[1] = 0x00; //超时时间
  451. bx_5k.SingleLine = 0x02; //设置是否单行显示 :01单行显示02多行显示
  452. bx_5k.NewLine = 0x01; //设置是否自动换行:01不自动换行 02自动换行
  453. /*正常显示抬头效果配置*/
  454. bx_5k.DisplayMode = 0x02; //设置显示方式:02快速打出/03向左移动
  455. bx_5k.ExitMode = 0x00; //设置退出方式
  456. bx_5k.Speed = 0x02; //设置运行速度
  457. bx_5k.StayTime = 0x05; //设置停留时间 0x01为0.5s
  458. if (qxz.Param.Dotled_Option != 1) //5k1显示整个内容
  459. {
  460. if (qxz.Param.application_model == 0) //当前应用模式:环境气象站
  461. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_YM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  462. else if (qxz.Param.application_model == 1) //当前应用模式:墒情监测站
  463. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_DHM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  464. }
  465. else
  466. total += sprintf((char *)bx_5k.dis_buff + total, "%s", time_YMDHM); //显示抬头\\C3\\DH时\\DM分\\DS秒
  467. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  468. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  469. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  470. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  471. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  472. bx_5k.DataLen[1] = (char)(total >> 8);
  473. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  474. add_len = 12;
  475. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  476. add_len += 2;
  477. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  478. add_len += 2;
  479. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  480. add_len += 1;
  481. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  482. add_len += 2;
  483. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  484. add_len += 1;
  485. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  486. add_len += 1;
  487. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  488. add_len += 2;
  489. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  490. add_len += 1;
  491. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  492. add_len += 2;
  493. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  494. add_len += 2;
  495. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  496. add_len += 2;
  497. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  498. add_len += 2;
  499. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  500. add_len += 1;
  501. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  502. add_len += 1;
  503. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  504. add_len += 1;
  505. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  506. add_len += 2;
  507. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  508. add_len += 3;
  509. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  510. add_len += 1;
  511. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  512. add_len += 1;
  513. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  514. add_len += 1;
  515. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  516. add_len += 1;
  517. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  518. add_len += 1;
  519. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  520. add_len += 1;
  521. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  522. add_len += 4;
  523. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  524. add_len += total;
  525. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  526. t = t + 14; //加Data_Field_1+数据长度2
  527. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  528. Dis_Comm[t] = crc_data >> 8;
  529. t = t + 1;
  530. Dis_Comm[t] = crc_data;
  531. t = t + 1;
  532. t = Escape_character(Dis_Comm, t); //字符转义处理
  533. Dis_Comm[t] = 0x5a;
  534. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  535. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  536. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  537. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  538. led_set_mode(DOTLED, 5, led_blink_mode_1);
  539. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  540. }
  541. }
  542. //抬头:区域0显示函数,显示抬头
  543. void DotLED_DisplayArea0_y(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t TURNON_RUN)
  544. {
  545. uint16_t add_len = 0; //整个数据总长度
  546. uint16_t total = 0; /* 记录当前数据长度 */
  547. rt_uint32_t e;
  548. uint16_t crc_data = 0;
  549. // uint16_t i, j, t = 0;
  550. uint16_t t = 0;
  551. if ((rt_event_recv(&timed_events, timed_events_TITLE,
  552. RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  553. 0, &e) == RT_EOK) ||
  554. (TURNON_RUN == 1)) //定时时间到或者开机运行1次
  555. {
  556. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  557. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  558. bx_5k.AreaX[0] = (char)(x & 0xff);
  559. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  560. // bx_5k.AreaX[1] = (char)( x >> 8);
  561. bx_5k.AreaY[0] = (char)(y & 0xff);
  562. bx_5k.AreaY[1] = (char)(y >> 8);
  563. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  564. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  565. // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  566. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  567. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  568. bx_5k.DynamicAreaLoc = 0x00; //设置动态区域为0
  569. bx_5k.Lines_sizes = 0; //行间距
  570. bx_5k.RunMode = 0x00; //动态区域运行模式,动态区数据循环显示*/
  571. bx_5k.Timeout[0] = 0x00; //
  572. bx_5k.Timeout[1] = 0x00; //超时时间
  573. bx_5k.SingleLine = 0x01; //设置是否单行显示 :单行显示
  574. bx_5k.NewLine = 0x01; //设置是否自动换行:不自动换行
  575. if (title_timeout == 0) //正常显示气象站抬头
  576. {
  577. /*正常显示抬头效果配置*/
  578. bx_5k.DisplayMode = 0x01; //设置显示方式:02快速打出/03向左移动/05向上移动
  579. bx_5k.ExitMode = 0x00; //设置退出方式
  580. bx_5k.Speed = 0x02; //设置运行速度
  581. bx_5k.StayTime = 0xa0; //设置停留时间 0x01为5s
  582. total += sprintf((char *)bx_5k.dis_buff + total, "%s", dotledtitle); //显示抬头
  583. }
  584. else //滚动显示下发内容
  585. {
  586. /*显示自定义抬头滚动效果配置*/
  587. bx_5k.DisplayMode = 0x03; //设置显示方式:02快速打出/03向左移动
  588. bx_5k.ExitMode = 0x00; //设置退出方式
  589. bx_5k.Speed = 0x04; //设置运行速度
  590. bx_5k.StayTime = 0x01; //设置停留时间 0x01为0.5s
  591. total += sprintf((char *)bx_5k.dis_buff + total, "%s", dotledtitle_down); //显示抬头
  592. }
  593. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  594. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  595. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  596. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  597. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  598. bx_5k.DataLen[1] = (char)(total >> 8);
  599. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  600. add_len = 12;
  601. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  602. add_len += 2;
  603. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  604. add_len += 2;
  605. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  606. add_len += 1;
  607. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  608. add_len += 2;
  609. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  610. add_len += 1;
  611. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  612. add_len += 1;
  613. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  614. add_len += 2;
  615. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  616. add_len += 1;
  617. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  618. add_len += 2;
  619. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  620. add_len += 2;
  621. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  622. add_len += 2;
  623. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  624. add_len += 2;
  625. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  626. add_len += 1;
  627. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  628. add_len += 1;
  629. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  630. add_len += 1;
  631. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  632. add_len += 2;
  633. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  634. add_len += 3;
  635. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  636. add_len += 1;
  637. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  638. add_len += 1;
  639. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  640. add_len += 1;
  641. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  642. add_len += 1;
  643. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  644. add_len += 1;
  645. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  646. add_len += 1;
  647. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  648. add_len += 4;
  649. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  650. add_len += total;
  651. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  652. t = t + 14; //加Data_Field_1+数据长度2
  653. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  654. Dis_Comm[t] = crc_data >> 8;
  655. t = t + 1;
  656. Dis_Comm[t] = crc_data;
  657. t = t + 1;
  658. t = Escape_character(Dis_Comm, t); //字符转义处理
  659. Dis_Comm[t] = 0x5a;
  660. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  661. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  662. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  663. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  664. led_set_mode(DOTLED, 5, led_blink_mode_1);
  665. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  666. }
  667. }
  668. // //内容:区域1显示函数
  669. // void DotLED_DisplayArea1(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t keeptime)
  670. // {
  671. // uint16_t add_len = 0; //整个数据总长度
  672. // uint16_t total = 0; /* 记录当前数据长度 */
  673. // uint16_t crc_data = 0;
  674. // uint16_t i, j, t = 0;
  675. // rt_uint32_t e;
  676. // if (rt_event_recv(&timed_events, timed_events_MAIN,
  677. // RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
  678. // 0, &e) == RT_EOK)
  679. // {
  680. // rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  681. // rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  682. // bx_5k.AreaX[0] = (char)(x & 0xff);
  683. // bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  684. // // bx_5k.AreaX[1] = (char)( x >> 8);
  685. // bx_5k.AreaY[0] = (char)(y & 0xff);
  686. // bx_5k.AreaY[1] = (char)(y >> 8);
  687. // bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  688. // bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  689. // // bx_5k.AreaWidth[1] = (char)( Width >> 8);
  690. // bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  691. // bx_5k.AreaHeight[1] = (char)(Height >> 8);
  692. // bx_5k.DynamicAreaLoc = 0x01; //设置动态区域为1
  693. // bx_5k.Lines_sizes = 0x01; //行间距
  694. // bx_5k.RunMode = 0x02; //动态区域运行模式,动态区数据循环显示,超过设定时间后数据仍未更新时不再显示*/
  695. // bx_5k.Timeout[0] = 0xa0; //
  696. // bx_5k.Timeout[1] = 0x00; //超时10s
  697. // bx_5k.SingleLine = 0x02; //设置是否单行显示 :多行显示
  698. // bx_5k.NewLine = 0x02; //设置是否自动换行:自动换行
  699. // bx_5k.DisplayMode = 0x02; //设置显示方式:快速打出
  700. // bx_5k.ExitMode = 0x00; //设置退出方式
  701. // bx_5k.Speed = 0x18; //设置运行速度
  702. // bx_5k.StayTime = keeptime; //设置停留时间 0x01为0.5s
  703. // total = Area1_dis_format(bx_5k.dis_buff);
  704. // bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  705. // bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  706. // bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  707. // bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  708. // bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  709. // bx_5k.DataLen[1] = (char)(total >> 8);
  710. // rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  711. // add_len = 12;
  712. // rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  713. // add_len += 2;
  714. // rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  715. // add_len += 2;
  716. // rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  717. // add_len += 1;
  718. // rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  719. // add_len += 2;
  720. // rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  721. // add_len += 1;
  722. // rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  723. // add_len += 1;
  724. // rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  725. // add_len += 2;
  726. // rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  727. // add_len += 1;
  728. // rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  729. // add_len += 2;
  730. // rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  731. // add_len += 2;
  732. // rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  733. // add_len += 2;
  734. // rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  735. // add_len += 2;
  736. // rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  737. // add_len += 1;
  738. // rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  739. // add_len += 1;
  740. // rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  741. // add_len += 1; //动态区域运行模式
  742. // rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  743. // add_len += 2;
  744. // rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  745. // add_len += 3;
  746. // rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  747. // add_len += 1;
  748. // rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  749. // add_len += 1;
  750. // rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  751. // add_len += 1;
  752. // rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  753. // add_len += 1;
  754. // rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  755. // add_len += 1;
  756. // rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  757. // add_len += 1;
  758. // rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  759. // add_len += 4;
  760. // rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  761. // add_len += total;
  762. // t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  763. // t = t + 14; //加Data_Field_1+数据长度2
  764. // crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  765. // t = Escape_character(Dis_Comm, t); //字符转义处理
  766. // Dis_Comm[t] = crc_data >> 8;
  767. // t = t + 1;
  768. // Dis_Comm[t] = crc_data;
  769. // t = t + 1;
  770. // Dis_Comm[t] = 0x5a;
  771. // rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  772. // rt_device_write(dotled, 0, bx_5k.Frame, 8);
  773. // rt_device_write(dotled, 0, Dis_Comm, t + 1);
  774. // char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  775. // led_set_mode(DOTLED, 5, led_blink_mode_1);
  776. // rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  777. // }
  778. // }
  779. //内容:区域1显示函数
  780. void DotLED_DisplayArea_y(uint8_t x, uint8_t y, uint8_t Width, uint8_t Height, uint8_t keeptime, uint8_t pos, uint8_t DynamicArea)
  781. {
  782. uint16_t add_len = 0; //整个数据总长度
  783. uint16_t total = 0; /* 记录当前数据长度 */
  784. uint16_t crc_data = 0;
  785. // uint16_t i, j, t = 0;
  786. uint16_t t = 0;
  787. // rt_uint32_t e;
  788. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  789. rt_memset(bx_5k.dis_buff, '\0', dis_buff_len);
  790. bx_5k.AreaX[0] = (char)(x & 0xff);
  791. //根据控制卡型号设定显示格式(X :1BIt or 8Bit)
  792. if (qxz.Param.Dotled_Option == 5 || qxz.Param.Dotled_Option == 7)
  793. {
  794. bx_5k.AreaX[1] = (char)((x >> 8) | 0x80); //最高位置一,以像素点为单位
  795. }
  796. else if (qxz.Param.Dotled_Option == 6 || qxz.Param.Dotled_Option == 8)
  797. {
  798. bx_5k.AreaX[1] = (char)(x >> 8); //8Bit
  799. }
  800. bx_5k.AreaY[0] = (char)(y & 0xff);
  801. bx_5k.AreaY[1] = (char)(y >> 8);
  802. bx_5k.AreaWidth[0] = (char)(Width & 0xff);
  803. //根据控制卡型号设定显示格式(W :1BIt or 8Bit)
  804. if (qxz.Param.Dotled_Option == 5 || qxz.Param.Dotled_Option == 7)
  805. {
  806. bx_5k.AreaWidth[1] = (char)((Width >> 8) | 0x80); //最高位置一,以像素点为单位
  807. }
  808. if (qxz.Param.Dotled_Option == 6 || qxz.Param.Dotled_Option == 8)
  809. {
  810. bx_5k.AreaWidth[1] = (char)(Width >> 8);
  811. }
  812. bx_5k.AreaHeight[0] = (char)(Height & 0xff);
  813. bx_5k.AreaHeight[1] = (char)(Height >> 8);
  814. bx_5k.DynamicAreaLoc = DynamicArea; //设置动态区域为1
  815. bx_5k.Lines_sizes = 0x01; //行间距
  816. bx_5k.RunMode = 0x02; //动态区域运行模式,动态区数据循环显示,超过设定时间后数据仍未更新时不再显示*/
  817. bx_5k.Timeout[0] = 0xa0; //
  818. bx_5k.Timeout[1] = 0x00; //超时10s
  819. bx_5k.SingleLine = 0x02; //设置是否单行显示 :多行显示
  820. bx_5k.NewLine = 0x02; //设置是否自动换行:自动换行
  821. bx_5k.DisplayMode = 0x02; //设置显示方式:快速打出
  822. bx_5k.ExitMode = 0x00; //设置退出方式
  823. bx_5k.Speed = 0x18; //设置运行速度
  824. bx_5k.StayTime = keeptime; //设置停留时间 0x01为0.5s
  825. total = Area1_dis_format_area(bx_5k.dis_buff, pos, DynamicArea);
  826. bx_5k.Len[0] = (char)((total + 9 + 27) & 0xff); /*计算动态区域0数据长度*/
  827. bx_5k.Len[1] = (char)((total + 9 + 27) >> 8);
  828. bx_5k.AreaLen[0] = (char)((total + 27) & 0xff); /*计算动态区域0数据长度*/
  829. bx_5k.AreaLen[1] = (char)((total + 27) >> 8);
  830. bx_5k.DataLen[0] = (char)(total & 0xff); /*实际显示内容长度,实际占32位,只实现了16位*/
  831. bx_5k.DataLen[1] = (char)(total >> 8);
  832. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  833. add_len = 12;
  834. rt_memcpy(Dis_Comm + add_len, bx_5k.Len, 2);
  835. add_len += 2;
  836. rt_memcpy(Dis_Comm + add_len, bx_5k.Cmd_dis, 2);
  837. add_len += 2;
  838. rt_memcpy(Dis_Comm + add_len, &bx_5k.Reply_f, 1);
  839. add_len += 1;
  840. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved0, 2);
  841. add_len += 2;
  842. rt_memcpy(Dis_Comm + add_len, &bx_5k.Areadealnum, 1);
  843. add_len += 1;
  844. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaNum, 1);
  845. add_len += 1;
  846. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaLen, 2);
  847. add_len += 2;
  848. rt_memcpy(Dis_Comm + add_len, &bx_5k.AreaType, 1);
  849. add_len += 1;
  850. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaX, 2);
  851. add_len += 2;
  852. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaY, 2);
  853. add_len += 2;
  854. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaWidth, 2);
  855. add_len += 2;
  856. rt_memcpy(Dis_Comm + add_len, bx_5k.AreaHeight, 2);
  857. add_len += 2;
  858. rt_memcpy(Dis_Comm + add_len, &bx_5k.DynamicAreaLoc, 1);
  859. add_len += 1;
  860. rt_memcpy(Dis_Comm + add_len, &bx_5k.Lines_sizes, 1);
  861. add_len += 1;
  862. rt_memcpy(Dis_Comm + add_len, &bx_5k.RunMode, 1);
  863. add_len += 1; //动态区域运行模式
  864. rt_memcpy(Dis_Comm + add_len, bx_5k.Timeout, 2);
  865. add_len += 2;
  866. rt_memcpy(Dis_Comm + add_len, bx_5k.Reserved1, 3);
  867. add_len += 3;
  868. rt_memcpy(Dis_Comm + add_len, &bx_5k.SingleLine, 1);
  869. add_len += 1;
  870. rt_memcpy(Dis_Comm + add_len, &bx_5k.NewLine, 1);
  871. add_len += 1;
  872. rt_memcpy(Dis_Comm + add_len, &bx_5k.DisplayMode, 1);
  873. add_len += 1;
  874. rt_memcpy(Dis_Comm + add_len, &bx_5k.ExitMode, 1);
  875. add_len += 1;
  876. rt_memcpy(Dis_Comm + add_len, &bx_5k.Speed, 1);
  877. add_len += 1;
  878. rt_memcpy(Dis_Comm + add_len, &bx_5k.StayTime, 1);
  879. add_len += 1;
  880. rt_memcpy(Dis_Comm + add_len, bx_5k.DataLen, 4);
  881. add_len += 4;
  882. rt_memcpy(Dis_Comm + add_len, (uint8_t *)bx_5k.dis_buff, total);
  883. add_len += total;
  884. t = (bx_5k.Len[1] << 8) + bx_5k.Len[0];
  885. t = t + 14; //加Data_Field_1+数据长度2
  886. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  887. Dis_Comm[t] = crc_data >> 8;
  888. t = t + 1;
  889. Dis_Comm[t] = crc_data;
  890. t = t + 1;
  891. t = Escape_character(Dis_Comm, t); //字符转义处理
  892. Dis_Comm[t] = 0x5a;
  893. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  894. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  895. rt_device_write(dotled, 0, Dis_Comm, t + 1);
  896. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  897. led_set_mode(DOTLED, 5, led_blink_mode_1);
  898. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  899. }
  900. //显示清屏
  901. void DotLED_DisplayClear_y(void)
  902. {
  903. uint16_t add_len = 0; //整个数据总长度
  904. // uint16_t total = 0; /* 记录当前数据长度 */
  905. char clr[] = {0x05, 0x00, 0xA3, 0x10, 0x01, 0x00, 0x00};
  906. uint16_t crc_data = 0;
  907. // uint16_t i, j, t = 0;
  908. uint16_t t = 0;
  909. rt_memset(Dis_Comm, '\0', dis_buff_len + 300);
  910. rt_memcpy(Dis_Comm + add_len, bx_5k.Header, 12);
  911. add_len = 12;
  912. rt_memcpy(Dis_Comm + add_len, clr, 7);
  913. add_len += 7;
  914. t = add_len;
  915. crc_data = CRC16_IBM(Dis_Comm, t); /*先计算出CRC值再来查询转义字符*/
  916. Dis_Comm[t] = crc_data >> 8;
  917. t = t + 1;
  918. Dis_Comm[t] = crc_data;
  919. t = t + 1;
  920. t = Escape_character(Dis_Comm, t); //字符转义处理
  921. Dis_Comm[t] = 0x5a;
  922. rt_pin_write(RS485_DOTLED_EN, PIN_HIGH); /*485输出使能*/
  923. rt_device_write(dotled, 0, bx_5k.Frame, 8);
  924. rt_device_write(dotled, 0, (Dis_Comm), t + 1);
  925. char *led_blink_mode_1 = "50,50,"; //10Hz闪烁
  926. led_set_mode(DOTLED, 5, led_blink_mode_1);
  927. rt_pin_write(RS485_DOTLED_EN, PIN_LOW); /*485输入使能*/
  928. }
  929. //显示属性初始化
  930. //LED_DIS_PAR led_dis[2] = {0};
  931. static void dotled_y_thread_entry(void *parameter)
  932. {
  933. rt_thread_mdelay(8000); //等待led参数读取
  934. rt_pin_mode(RS485_DOTLED_EN, PIN_MODE_OUTPUT);
  935. if (qxz.Param.Dotled_Option > 1) //其他尺寸,没有抬头的显示
  936. {
  937. // Control_card != 5 && //Y1A 单区域(1Bit)
  938. // Control_card != 6 && //Y1A 单区域(8Bit)
  939. // Control_card != 7 && //Y1A 双区域(1Bit)
  940. // Control_card != 8) //Y1A 双区域(8Bit)
  941. /*
  942. Note:
  943. 1. 控制卡大于等于5 说明启用Y1A控制卡(Y08通用)
  944. 2. 当keeptime小于11的时候 负责keeptime 大于等于的时候 同时负责调整动态区域间的间隙
  945. 此时keeptime为 (数值%11)
  946. 此时刷新延时为5秒
  947. 此时两个区域间隔为 keeptime * 2
  948. 综上可得 间隔可调区域为 22-64
  949. */
  950. uint16_t spacing = 0; //两动态区域之间的间距
  951. uint16_t D1_X = 0; //D1 的起始位置的计算
  952. // uint8_t Screen_Cnt = 0;
  953. // uint8_t len = 0;
  954. uint8_t All_elem = 0;
  955. screen_line = qxz.Param.dotled_p0.Height / qxz.Param.dotled_p0.front; //高度除以字体高度
  956. while (1)
  957. {
  958. All_elem = qxz.Param.Num_sensors;
  959. for (uint8_t c = 0; c < qxz.Param.Num_sensors; c++)
  960. {
  961. if (strstr(sensor[c].eName, "ALINE") != NULL)
  962. {
  963. All_elem++;
  964. }
  965. }
  966. if (qxz.Param.dotled_p0.keep_time > 10)
  967. {
  968. spacing = qxz.Param.dotled_p0.keep_time * 2;
  969. }
  970. else
  971. {
  972. spacing = 30;
  973. }
  974. // rt_kprintf("spacing %d D1_X %d\n" , spacing ,D1_X);
  975. if (qxz.Param.Dotled_Option >= 5)
  976. {
  977. DotLED_DisplayArea_y(qxz.Param.dotled_p0.Start_x,
  978. qxz.Param.dotled_p0.Start_y,
  979. qxz.Param.dotled_p0.Width,
  980. qxz.Param.dotled_p0.Height,
  981. (qxz.Param.dotled_p0.keep_time % 11) * 2,
  982. qxz.Param.dotled_p0.keep_time, 0);
  983. }
  984. //rt_kprintf("D0 send\n");
  985. if (qxz.Param.dotled_p0.keep_time <= 10)
  986. {
  987. rt_thread_mdelay(qxz.Param.dotled_p0.keep_time * 2000);
  988. }
  989. else
  990. {
  991. rt_thread_mdelay(5000);
  992. }
  993. if (qxz.Param.Dotled_Option >= 7)
  994. {
  995. if (qxz.Param.Dotled_Option == 7)
  996. {
  997. D1_X = (qxz.Param.dotled_p0.Start_x + qxz.Param.dotled_p0.Width + spacing);
  998. }
  999. else if (qxz.Param.Dotled_Option == 8)
  1000. {
  1001. D1_X = qxz.Param.dotled_p0.Start_x + qxz.Param.dotled_p0.Width + spacing / 8;
  1002. }
  1003. DotLED_DisplayArea_y(D1_X,
  1004. qxz.Param.dotled_p0.Start_y,
  1005. qxz.Param.dotled_p0.Width,
  1006. qxz.Param.dotled_p0.Height,
  1007. (qxz.Param.dotled_p0.keep_time % 11) * 2,
  1008. qxz.Param.dotled_p0.keep_time, 1);
  1009. //rt_kprintf("D1 send\n");
  1010. if (qxz.Param.dotled_p0.keep_time <= 10)
  1011. {
  1012. rt_thread_mdelay(qxz.Param.dotled_p0.keep_time * 2000);
  1013. }
  1014. else
  1015. {
  1016. rt_thread_mdelay(5000);
  1017. }
  1018. }
  1019. }
  1020. }
  1021. }
  1022. // led点阵屏控制线程
  1023. static void dotled_y_thread(void *param)
  1024. {
  1025. rt_err_t ret = RT_EOK;
  1026. char uart_name[RT_NAME_MAX];
  1027. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
  1028. // uint8_t dotled_size;
  1029. if (qxz.Param.Dotled_Option > 3 && qxz.Param.Dotled_Option < 9) //彩屏led点阵屏使能
  1030. {
  1031. // controller_type(qxz.Param.Dotled_Option);//计算控制卡型号
  1032. Dis_Comm = (unsigned char *)rt_malloc(dis_buff_len + 300);
  1033. if (Dis_Comm == RT_NULL)
  1034. {
  1035. log_i("Dis_Comm out of memory");
  1036. ret = RT_ERROR;
  1037. goto __exit;
  1038. }
  1039. bx_5k.dis_buff = (unsigned char *)rt_malloc(dis_buff_len);
  1040. if (Dis_Comm == RT_NULL)
  1041. {
  1042. log_i("bx_5k.dis_buff out of memory");
  1043. ret = RT_ERROR;
  1044. goto __exit;
  1045. }
  1046. /* 初始化事件对象 */
  1047. ret = rt_event_init(&timed_events, "event", RT_IPC_FLAG_FIFO);
  1048. if (ret != RT_EOK)
  1049. {
  1050. log_i("init event failed.\n");
  1051. return (void)ret;
  1052. }
  1053. /* 创建定时器 1 周期定时器 */
  1054. dotled_timed_task = rt_timer_create("dotled_timer", dotled_timed,
  1055. (void *)1, 1000,
  1056. RT_TIMER_FLAG_PERIODIC);
  1057. /* 启动定时器 1 */
  1058. if (dotled_timed_task != RT_NULL)
  1059. rt_timer_start(dotled_timed_task);
  1060. /* 查找串口设备 */
  1061. rt_strncpy(uart_name, DOTLED_UART_NAME, RT_NAME_MAX);
  1062. dotled = rt_device_find(uart_name);
  1063. if (!dotled)
  1064. {
  1065. rt_kprintf("find %s failed!\n", uart_name);
  1066. return RT_ERROR;
  1067. }
  1068. /* step2:修改串口配置参数 */
  1069. config.baud_rate = BAUD_RATE_57600; //修改波特率为57600
  1070. config.data_bits = DATA_BITS_8; //数据位 8
  1071. config.stop_bits = STOP_BITS_1; //停止位 1
  1072. config.bufsz = 1024; //修改缓冲区 buff size 为 128
  1073. config.parity = PARITY_NONE; //无奇偶校验位
  1074. /* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */
  1075. rt_device_control(dotled, RT_DEVICE_CTRL_CONFIG, &config);
  1076. rt_device_open(dotled, RT_DEVICE_FLAG_INT_RX);
  1077. /* 创建 serial 线程 */
  1078. rt_thread_t thread1 = rt_thread_create("dotled_y", dotled_y_thread_entry, RT_NULL, 2048, 17, 10);
  1079. /* 创建成功则启动线程 */
  1080. if (thread1 != RT_NULL)
  1081. {
  1082. rt_thread_startup(thread1);
  1083. }
  1084. else
  1085. {
  1086. ret = RT_ERROR;
  1087. }
  1088. }
  1089. else
  1090. ret = RT_EEMPTY;
  1091. __exit:
  1092. if (ret == RT_EOK)
  1093. {
  1094. //return ret;
  1095. }
  1096. else
  1097. {
  1098. rt_free(Dis_Comm);
  1099. Dis_Comm = RT_NULL;
  1100. rt_free(bx_5k.dis_buff);
  1101. bx_5k.dis_buff = RT_NULL;
  1102. }
  1103. //return ret;
  1104. }
  1105. INIT_APP_EXPORT(dotled_y_thread);