LcdComm.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317
  1. /********************************************************************
  2. 版权所有:
  3. 文件版本: V1.00
  4. 文件名称: LcdComm.c
  5. 生成日期: 2008年10月9日
  6. 作 者:
  7. 使用范围:
  8. 功 能:与面板通信处理程序
  9. 更新信息:
  10. 更新日志1:
  11. 修改者:
  12. 修改日期:
  13. 修改内容:
  14. 修改原因:
  15. *********************************************************************/
  16. /*------------------------------- 头文件 --------------------------------------
  17. */
  18. #include "head.h"
  19. /*------------------------------- 宏定义 --------------------------------------
  20. */
  21. enum
  22. {
  23. HMI_RECV,
  24. HMI_SEND,
  25. };
  26. //#define HMI_V2
  27. /*------------------------------ 类型结构 -------------------------------------
  28. */
  29. /*------------------------------ 全局变量 -------------------------------------
  30. */
  31. UART_COMM g_tUartHMI; // 与面板通信的串口数据结构定义
  32. struct hmi g_hmi[HMI_COMM_TYPE]; //面板帧结构定义
  33. LCD_COMM_DEF g_tLcdComm; // 菜单处理数据与面板通信的结构定义
  34. DWORD dHMIDiStatus = 0Xffffffff;
  35. u8 *hzk_table;
  36. static u8 hmi_update=0;
  37. u8 lcd_dot_type; // 显示点阵显示类型
  38. int hzk_num; // 汉字库中汉字个数
  39. int hzk_change_type; // 当前切换的汉字库类型
  40. unsigned long lcd_comm_delay=0; // 面板通讯超时
  41. int g_hzk_table_flag = 0; //0表示使用主板的汉字库,1表示使用面板的汉字库
  42. char m_TzCount[12];
  43. char m_HzCount[12];
  44. /*------------------------------ 函数声明 -------------------------------------
  45. */
  46. int hzk_read_file(void);
  47. //static void _reset_uartHMI_link(void);
  48. static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len); //len为参数长度
  49. static void _hmi_call(void);
  50. static void _put_key(BYTE key);
  51. static void _hmi_comm_recv(BYTE *ps);
  52. static void _hmi_comm_send(void);
  53. void _hmi_uart_send(void);
  54. static void _send_inst(void);
  55. static void _send_continue_datas(void);
  56. static void _get_hz_dot(char *hzdot,const char *hzk);
  57. static int _hmi_changehzk(u8 type);
  58. /*------------------------------ 外部函数 -------------------------------------
  59. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  60. */
  61. /**************************************************************************
  62. 函数名称:InitLcdComm
  63. 函数版本:1.00
  64. 作者:
  65. 创建日期:2008.9.1
  66. 函数功能说明:初始化面板通信
  67. 输入参数:
  68. 输出参数:
  69. 返回值:
  70. 更新信息:
  71. 更新日志1:
  72. 日期:
  73. 修改者:
  74. 修改内容:
  75. 修改原因:
  76. ***************************************************************************/
  77. void InitLcdComm(void)
  78. {
  79. int ret;
  80. memset((BYTE *)&g_tLcdComm,0,sizeof(g_tLcdComm));
  81. memset((BYTE *)&g_tUartHMI,0,sizeof(g_tUartHMI));
  82. // mmd_menu_cfg_init();
  83. g_tLcdComm.tInit.flag=true;
  84. g_tLcdComm.bRecv=true;
  85. if(g_hzk_table_flag==0)
  86. {
  87. ret = hzk_read_file();
  88. if (ret != 0)
  89. {
  90. rt_err_set(ERR_CODE_HZK,0);
  91. rt_file_del("/app/data/hzk.bin");
  92. rt_printf("汉字库文件错误: %d\r\n", ret);
  93. }
  94. else
  95. {
  96. hzk_change_type = LCD_HP;
  97. }
  98. }
  99. g_tLcdComm.dWaitT=dTCounter;
  100. g_tLcdComm.bVirLcd=false;
  101. g_tLcdComm.bCall = true;
  102. lcd_comm_delay = ustimer_get_origin();
  103. }
  104. /**************************************************************************
  105. 函数名称:HMI_Comm_App
  106. 函数版本:1.00
  107. 作者:
  108. 创建日期:2008.9.1
  109. 函数功能说明:主函数调用与面板通信任务,10ms调用1次,100ms左右调用一次刷屏命令
  110. 输入参数:
  111. 输出参数:
  112. 返回值:
  113. 更新信息:
  114. 更新日志1:
  115. 日期:
  116. 修改者:
  117. 修改内容:
  118. 修改原因:
  119. ***************************************************************************/
  120. void HMI_Comm_App(void) /*10毫秒调用一次*/
  121. {
  122. // 字库初始化失败且使用本地字库模式时不进入处理
  123. if(hzk_table == NULL && g_hzk_table_flag ==0)
  124. return;
  125. #if 1
  126. //正在升级面板程序
  127. if(is_down_program())
  128. {
  129. //有数据
  130. if(g_tUartHMI.r_head != g_tUartHMI.r_tail)
  131. {
  132. //接收处理
  133. down_program_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]);
  134. g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1);
  135. }
  136. else
  137. {
  138. //接收超时处理
  139. down_program_recv_timeout();
  140. }
  141. //发送处理
  142. down_program_send();
  143. return;
  144. }
  145. //内置GPRS拨号时有时候占用资源比较多,所以调整为15秒比较保险
  146. if ((g_tUartHMI.r_head == g_tUartHMI.r_tail)
  147. && (ustimer_get_duration(lcd_comm_delay) > 15*USTIMER_SEC))//3s
  148. {
  149. g_tLcdComm.tInit.flag=true;
  150. g_tLcdComm.b_init_OK = false;
  151. if(!soe_check(EV_HMIERR))
  152. {
  153. //soe_record_ev(EV_HMIERR, 1, 0,0,0 );
  154. }
  155. lcd_comm_delay = ustimer_get_origin();
  156. }
  157. if(g_tUartHMI.r_head != g_tUartHMI.r_tail)
  158. {
  159. _hmi_comm_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]);
  160. g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1);
  161. lcd_comm_delay = ustimer_get_origin();
  162. }
  163. _hmi_comm_send();
  164. #endif
  165. }
  166. /**************************************************************************
  167. 函数名称:Add_Continue_Data
  168. 函数版本:1.00
  169. 作者:
  170. 创建日期:2008.9.1
  171. 函数功能说明:菜单驱动调用函数,将要显示的数据存入缓冲区中
  172. 输入参数:
  173. 输出参数:
  174. 返回值:
  175. 更新信息:
  176. 更新日志1:
  177. 日期:
  178. 修改者:
  179. 修改内容:
  180. 修改原因:
  181. ***************************************************************************/
  182. void Add_Continue_Data(BYTE x,BYTE y,BYTE *pdat,BYTE len,BYTE mode)
  183. {
  184. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  185. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->head];
  186. BYTE cnt;
  187. BYTE attrib;
  188. pt->x=x;
  189. pt->y=y;
  190. pt->attrib=len;
  191. attrib=0;
  192. if(mode==1)
  193. {
  194. pt->attrib|=0x80;
  195. attrib=1; //显示属性
  196. }
  197. for(cnt=0;cnt<len;cnt++) // 汉字处理
  198. {
  199. pt->dat[cnt]=*pdat;
  200. pdat++;
  201. }
  202. ptBuf->head++;
  203. ptBuf->head&=LCD_MAX_CONTINUE_MASK;
  204. if(ptBuf->head==ptBuf->tail) /*缓冲区满了*/
  205. {
  206. ptBuf->tail++;
  207. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  208. }
  209. }
  210. /**************************************************************************
  211. 函数名称:Add_Clear_Screen
  212. 函数版本:1.00
  213. 作者:
  214. 创建日期:2008.9.1
  215. 函数功能说明:清屏命令
  216. 输入参数:
  217. 输出参数:
  218. 返回值:
  219. 更新信息:
  220. 更新日志1:
  221. 日期:
  222. 修改者:
  223. 修改内容:
  224. 修改原因:
  225. ***************************************************************************/
  226. void Add_Clear_Screen(void) //mmidrv.c 调用
  227. {
  228. LCD_COMM_DEF *pt=&g_tLcdComm;
  229. pt->bClrScreen=true; //清全屏
  230. // 清发送缓冲区
  231. pt->tContinue.head=pt->tContinue.tail=0;
  232. // 字从首字开始
  233. pt->tContinue.index=0;
  234. }
  235. /**************************************************************************
  236. 函数名称:add_led_test
  237. 函数版本:1.00
  238. 作者:
  239. 创建日期:2008.9.1
  240. 函数功能说明:清屏命令
  241. 输入参数:
  242. 输出参数:
  243. 返回值:
  244. 更新信息:
  245. 更新日志1:
  246. 日期:
  247. 修改者:
  248. 修改内容:
  249. 修改原因:
  250. ***************************************************************************/
  251. void add_led_test(u8 test_no)
  252. {
  253. LCD_COMM_DEF *pt = &g_tLcdComm;
  254. switch (test_no)
  255. {
  256. case TEST_LED:
  257. pt->bTestLed = true;
  258. break;
  259. case TEST_LCD:
  260. pt->bTestLcd = true;
  261. break;
  262. }
  263. }
  264. void add_rmt_pair(u8 pair)
  265. {
  266. LCD_COMM_DEF *pt = &g_tLcdComm;
  267. switch (pair)
  268. {
  269. case TEST_LED:
  270. pt->bTeleMatch = true;
  271. break;
  272. case TEST_LCD:
  273. pt->bTeleClrMatch = true;
  274. break;
  275. }
  276. }
  277. /**************************************************************************
  278. 函数名称:Get_Key
  279. 函数版本:1.00
  280. 作者:
  281. 创建日期:2008.9.1
  282. 函数功能说明:获得按键函数
  283. 输入参数:
  284. 输出参数:
  285. 返回值:
  286. 更新信息:
  287. 更新日志1:
  288. 日期:
  289. 修改者:
  290. 修改内容:
  291. 修改原因:
  292. ***************************************************************************/
  293. BYTE Get_Key(void)
  294. {
  295. LCD_KEY_DEF *pt=&g_tLcdComm.tKey;
  296. BYTE key;
  297. if(pt->head==pt->tail)return NO_KEY;
  298. key=pt->keybuf[pt->tail];
  299. pt->tail++;
  300. pt->tail&=LCD_KEY_MASK;
  301. return key;
  302. }
  303. /******************************************************************************
  304. 函数名称: HMI_Board_Recv
  305. 函数版本: 01.01
  306. 创建作者: xxxxxx
  307. 创建日期: 2014-12-10
  308. 函数说明: 接收帧
  309. 参数说明: len:帧长度
  310. para:接收帧内容
  311. 返回值: 无
  312. 修改记录:
  313. */
  314. void HMI_Board_Recv(int len,BYTE *para)
  315. {
  316. UART_COMM *pt=&g_tUartHMI;
  317. memcpy(pt->r_buf[pt->r_head], para, len);
  318. pt->r_head = (pt->r_head + 1) & (UART_FRAME_MAXCNT - 1);
  319. }
  320. /******************************************************************************
  321. 函数名称: hzk_read_file
  322. 函数版本: 01.01
  323. 创建作者: xxxxxx
  324. 创建日期: 2013-08-08
  325. 函数说明: 读取汉字库
  326. 参数说明:
  327. 返回值:
  328. 0: 成功
  329. 其它: 失败
  330. 修改记录:
  331. */
  332. int hzk_read_file(void)
  333. {
  334. u32 len;
  335. u16 crc16;
  336. struct file * pfile;
  337. loff_t pos;
  338. // 打开文件
  339. pfile = rt_file_open("/app/data/hzk.bin",O_RDONLY ,0);
  340. if(IS_ERR(pfile))
  341. {
  342. return -1;
  343. }
  344. // 得到文件长度
  345. len = rt_file_getfile_size(pfile);
  346. if(len <= 0)
  347. {
  348. rt_file_close(pfile,0);
  349. return -11;
  350. }
  351. // 分配内存
  352. hzk_table = rt_malloc(len);
  353. if(hzk_table == NULL)
  354. {
  355. rt_file_close(pfile,0);
  356. return -2;
  357. }
  358. // 读出内容
  359. pos = 0;
  360. if(rt_file_read(pfile,hzk_table,len,&pos) != len)
  361. {
  362. rt_file_close(pfile,0);
  363. rt_free(hzk_table);
  364. return -3;
  365. }
  366. // 关闭文件
  367. rt_file_close(pfile,0);
  368. // 检查CRC
  369. crc16 = CrcStr(hzk_table,len-2);
  370. if(crc16 != *(u16*)(hzk_table+len-2))
  371. {
  372. rt_free(hzk_table);
  373. hzk_table = NULL;
  374. return -4;
  375. }
  376. hzk_num = (len-2) / 32;
  377. return 0;
  378. }
  379. /******************************************************************************
  380. 函数名称: hzk_exit
  381. 函数版本: 01.01
  382. 创建作者: xxxxxx
  383. 创建日期: 2015-04-16
  384. 函数说明: LED配置退出
  385. 参数说明: 无
  386. 返回值: 成功返回0.
  387. 修改记录:
  388. */
  389. int hzk_exit(void)
  390. {
  391. if(hzk_table)
  392. {
  393. rt_free(hzk_table);
  394. }
  395. return 0;
  396. }
  397. /*------------------------------ 内部函数 -------------------------------------
  398. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  399. */
  400. /**************************************************************************
  401. 函数名称:ResetUartHMILink
  402. 函数版本:1.00
  403. 作者:
  404. 创建日期:2008.9.1
  405. 函数功能说明:复归接收数据结构
  406. 输入参数:
  407. 输出参数:
  408. 返回值:
  409. 更新信息:
  410. 更新日志1:
  411. 日期:
  412. 修改者:
  413. 修改内容:
  414. 修改原因:
  415. ***************************************************************************/
  416. #if 0
  417. static void _reset_uartHMI_link(void)
  418. {
  419. g_tUartHMI.cTypeCounter=0;
  420. g_tUartHMI.cRecvCnt=0;
  421. }
  422. #endif
  423. /**************************************************************************
  424. 函数名称:Add_Inst_Frame
  425. 函数版本:1.00
  426. 作者:
  427. 创建日期:2008.9.1
  428. 函数功能说明:将发给面板的命令放入待发送指令缓冲区中
  429. 输入参数:
  430. 输出参数:
  431. 返回值:
  432. 更新信息:
  433. 更新日志1:
  434. 日期:
  435. 修改者:
  436. 修改内容:
  437. 修改原因:
  438. ***************************************************************************/
  439. static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len) //len为参数长度
  440. {
  441. BYTE i;
  442. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  443. INST_DEF *pt=&ptBuf->tInst[ptBuf->head];
  444. BYTE srcbuf[UART_FRAME_LEN];
  445. BYTE *pd=srcbuf;
  446. int offset=0;
  447. // if(pRunSet->bHMI_OLD)
  448. // {
  449. // offset = 2;
  450. // *pd++=0;// 控制域
  451. // *pd++=0xCC; // HMI地址为CC 状态板为55
  452. // }
  453. *pd++=cmd;
  454. for(i=0;i<len;i++)
  455. {
  456. *pd++=para[i];
  457. }
  458. //组包
  459. (void)protocol_packet(srcbuf, (int)len+5+offset, MAIN_BOARD, HMI_BOARD, pt->para);
  460. ptBuf->head++;
  461. ptBuf->head&=LCD_MAX_INST_MASK;
  462. if(ptBuf->head==ptBuf->tail) //缓冲区满了
  463. {
  464. ptBuf->tail++;
  465. ptBuf->tail&=LCD_MAX_INST_MASK;
  466. }
  467. }
  468. static void _get_hz_dot(char *hzdot,const char *hzk)
  469. {
  470. int i;
  471. for(i=0;i<32;i++) // 160*160液晶为负序横显
  472. {
  473. hzdot[i]=hzk[i];
  474. }
  475. #if 0 // 转换汉字库点阵,stc3100是正序纵显 ,(标准字库是正序横显)
  476. for(m=0;m<8;m++)
  477. {
  478. BYTE dat0=0;
  479. BYTE dat1=0;
  480. BYTE dat2=0;
  481. BYTE dat3=0;
  482. for(i=0;i<8;i++)
  483. {
  484. dat0|=(((hzk[i*2]>>m)&0x01)<<i);
  485. dat1|=(((hzk[i*2+1]>>m)&0x01)<<i);
  486. dat2|=(((hzk[i*2+16]>>m)&0x01)<<i);
  487. dat3|=(((hzk[i*2+17]>>m)&0x01)<<i);
  488. }
  489. hzdot[m]=dat0;
  490. hzdot[m+8]=dat1;
  491. hzdot[m+16]=dat2;
  492. hzdot[m+24]=dat3;
  493. }
  494. #endif
  495. }
  496. /**************************************************************************
  497. 函数名称:HMI_Call
  498. 函数版本:1.00
  499. 作者:
  500. 创建日期:2008.9.1
  501. 函数功能说明:主程序召唤面板数据命令
  502. 输入参数:
  503. 输出参数:
  504. 返回值:
  505. 更新信息:
  506. 更新日志1:
  507. 日期:
  508. 修改者:
  509. 修改内容:
  510. 修改原因:
  511. ***************************************************************************/
  512. static void _hmi_call(void)
  513. {
  514. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  515. INST_DEF *pt;
  516. //缓存区没有数据,发查询命令
  517. {
  518. _add_inst_frame((BYTE)HMI_CMD_POLL, (BYTE*)0, 0);
  519. pt=&ptBuf->tInst[ptBuf->tail];
  520. //
  521. Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para);
  522. ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK;
  523. }
  524. }
  525. /**************************************************************************
  526. 函数名称:Put_Key
  527. 函数版本:1.00
  528. 作者:
  529. 创建日期:2008.9.1
  530. 函数功能说明:将通信来的按键值放入缓冲中
  531. 输入参数:
  532. 输出参数:
  533. 返回值:
  534. 更新信息:
  535. 更新日志1:
  536. 日期:
  537. 修改者:
  538. 修改内容:
  539. 修改原因:
  540. ***************************************************************************/
  541. static void _put_key(BYTE key)
  542. {
  543. LCD_KEY_DEF *pt=&g_tLcdComm.tKey;
  544. pt->keybuf[pt->head]=key;
  545. pt->head++;
  546. pt->head&=LCD_KEY_MASK;
  547. if(pt->head==pt->tail) //缓冲区满了
  548. {
  549. pt->tail++;
  550. pt->tail&=LCD_KEY_MASK;
  551. }
  552. #if 0
  553. switch(key&~KE_KEY_LONG_BIT)
  554. {
  555. case 1:rt_printf("确认键");break;
  556. case 2:rt_printf("ESC键");break;
  557. case 3:rt_printf("UP键");break;
  558. case 4:rt_printf("DOWN键");break;
  559. case 5:rt_printf("LEFT键");break;
  560. case 6:rt_printf("RIGHT键");break;
  561. case 7:rt_printf("ADD键");break;
  562. case 8:rt_printf("SUB键");break;
  563. case 9:rt_printf("控制面板复归信号产生。\r\n");break;
  564. }
  565. #endif
  566. }
  567. /**************************************************************************
  568. 函数名称:HMI_CommRecv
  569. 函数版本:1.00
  570. 作者:
  571. 创建日期:2008.9.1
  572. 函数功能说明:与面板通信的接收处理函数
  573. 输入参数:
  574. 输出参数:
  575. 返回值:
  576. 更新信息:
  577. 更新日志1:
  578. 日期:
  579. 修改者:
  580. 修改内容:
  581. 修改原因:
  582. ***************************************************************************/
  583. static void _hmi_comm_recv(BYTE *ps)
  584. {
  585. BYTE *pd=ps;
  586. int offset=0;
  587. switch(pd[4+offset]&0x1f)
  588. {
  589. case DRV_CMD_POWERON: //上电报文
  590. {
  591. int ret;
  592. if(pd[5+offset]==1)//上电初始化报文
  593. {
  594. g_tLcdComm.tInit.flag=true;
  595. query_page_other_proc();
  596. }
  597. else
  598. {
  599. g_tLcdComm.b_init_OK=true;
  600. rt_printf("g_tLcdComm.b_init_OK\r\n");
  601. }
  602. // 获取面板类型,并初使化菜单和LED
  603. g_hmi_type = pd[7+offset];
  604. // 初始化之前先释放可能存在的内存,因为面板可能会重新初使化
  605. menudesc_exit();
  606. led_exit();
  607. ret = menudesc_init(g_hmi_type);
  608. if (ret == 0)
  609. {
  610. hmi_update = 1;
  611. }
  612. else
  613. {
  614. rt_printf("菜单初始化结果=%d\r\n", ret);
  615. }
  616. if(g_hzk_table_flag==0)
  617. {
  618. // 获取液晶点阵类型,并转换字库
  619. lcd_dot_type = pd[8+offset];
  620. _hmi_changehzk(lcd_dot_type);
  621. }
  622. }
  623. break;
  624. case DRV_CMD_KEY: //按键报文
  625. {
  626. _put_key(pd[5+offset]);
  627. _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0);
  628. }
  629. break;
  630. case DRV_CMD_TEMP: //面板遥信
  631. {
  632. }
  633. break;
  634. case DRV_CMD_YX: //遥信
  635. {
  636. }
  637. break;
  638. case DRV_CMD_SET: //定值
  639. {
  640. }
  641. break;
  642. case DRV_CMD_YKQ: //遥控器
  643. {
  644. g_rmt_op.key = pd[5];
  645. _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0);
  646. }
  647. break;
  648. case DRV_CMD_DOWN: //下载程序应答
  649. break;
  650. default:
  651. break;
  652. }
  653. }
  654. /**************************************************************************
  655. 函数名称:HMI_Comm_Send
  656. 函数版本:1.00
  657. 作者:
  658. 创建日期:2008.9.1
  659. 函数功能说明:启动面板通信的发送,包含重发机制。
  660. 输入参数:
  661. 输出参数:
  662. 返回值:
  663. 更新信息:
  664. 更新日志1:
  665. 日期:
  666. 修改者:
  667. 修改内容:
  668. 修改原因:
  669. ***************************************************************************/
  670. static void _hmi_comm_send(void)
  671. {
  672. static unsigned long us0=0;
  673. static unsigned long us_lcdtest=0;
  674. static unsigned long us_ledtest=0;
  675. LCD_COMM_DEF *pt=&g_tLcdComm;
  676. if (pt->bCall)
  677. {
  678. us0 = ustimer_get_origin();
  679. pt->bCall = FALSE;
  680. }
  681. // 确保菜单初始化后才进行菜单操作,
  682. // 确保接收完成才进行下一帧,以避免显示内容乱
  683. if (hmi_update)
  684. {
  685. key_hmi_app();
  686. menu_disp();
  687. }
  688. pt->ReSend=0;
  689. pt->dWaitT=dTCounter;
  690. if(pt->tInit.flag&&(!pt->bVirLcd)) //需初始化lcd
  691. {
  692. pt->tContinue.head=pt->tContinue.tail=0;
  693. pt->tInstBuf.head=pt->tInstBuf.tail=0;
  694. pt->tLight.light=LIGHT_ON;
  695. _add_inst_frame(HMI_CMD_INIT_LCD,pt->tInit.para,10); //初始化lcd
  696. _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏
  697. _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //点亮背光
  698. pt->tInit.flag=false;
  699. pt->tLight.flag=false;
  700. pt->bClrScreen=false;
  701. hmi_update = 0;
  702. }
  703. else
  704. {
  705. if(pt->bClrScreen) //需初始化lcd
  706. {
  707. _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏
  708. reset_update_flag();
  709. pt->bClrScreen=false;
  710. }
  711. if(pt->tLight.flag)
  712. {
  713. _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //背光控制
  714. pt->tLight.flag=false;
  715. }
  716. if(pt->bTestLed && (!pt->bLcdUpdate))
  717. {
  718. _add_inst_frame(HMI_CMD_LEDRUN,(void *)0,0); //led测试
  719. pt->bTestLed=false;
  720. pt->bLedUpdate = true;
  721. us_ledtest = ustimer_get_origin();
  722. }
  723. if(pt->bLedUpdate)
  724. {
  725. if (ustimer_get_duration(us_ledtest) >= 4*USTIMER_SEC)
  726. {
  727. pt->bLedUpdate = false;
  728. }
  729. lcd_comm_delay = ustimer_get_origin();
  730. }
  731. else
  732. {
  733. us_ledtest = ustimer_get_origin();
  734. }
  735. if(pt->bTestLcd && (!pt->bLedUpdate))
  736. {
  737. _add_inst_frame(HMI_CMD_LCDRUN,(void *)0,0); //lcd测试
  738. pt->bTestLcd=false;
  739. pt->bLcdUpdate = true;
  740. us_lcdtest = ustimer_get_origin();
  741. }
  742. if(pt->bLcdUpdate)
  743. {
  744. if (ustimer_get_duration(us_lcdtest) >= 3*USTIMER_SEC)
  745. {
  746. reset_update_flag();
  747. pt->bLcdUpdate = false;
  748. }
  749. lcd_comm_delay = ustimer_get_origin();
  750. }
  751. else
  752. {
  753. us_lcdtest = ustimer_get_origin();
  754. }
  755. if(pt->bTeleMatch)
  756. {
  757. pt->tTele.cmd = 0x10;
  758. _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对
  759. pt->bTeleMatch=false;
  760. }
  761. if(pt->bTeleClrMatch)
  762. {
  763. pt->tTele.cmd = 0x20;
  764. _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对清除
  765. pt->bTeleClrMatch=false;
  766. }
  767. // 1秒钟刷新一次LED
  768. if (pt->b_init_OK)
  769. {
  770. static unsigned long us0;
  771. u8 led_st[4];
  772. if(ustimer_delay_origin2(&us0,USTIMER_SEC))
  773. {
  774. led_to_hmi();
  775. // zhl TODO g_dw_led有两个,暂时先用一个测试
  776. led_st[0]=(BYTE)g_dw_led[0]; // 状态灯
  777. led_st[1]=(BYTE)(g_dw_led[0]>>8); // 状态灯高位
  778. led_st[2]=(BYTE)(g_dw_led[0]>>16); // 状态灯高位
  779. led_st[3]=(BYTE)(g_dw_led[0]>>24); // 状态灯高位
  780. _add_inst_frame(HMI_CMD_LED,led_st,4); //led点灯
  781. }
  782. }
  783. }
  784. //组织报文
  785. if(pt->tInstBuf.head!=pt->tInstBuf.tail) //组织报文
  786. {
  787. _send_inst();
  788. }
  789. else if(pt->tContinue.head!=pt->tContinue.tail) //组织报文
  790. {
  791. _send_continue_datas();
  792. pt->bClrflag = false;
  793. }
  794. else if(pt->b_init_OK && (ustimer_get_duration(us0) >= 1*USTIMER_SEC)) //无 发送数据,召唤
  795. {
  796. _hmi_call();
  797. pt->bCall = true;
  798. }
  799. }
  800. /**************************************************************************
  801. 函数名称:Send_Inst
  802. 函数版本:1.00
  803. 作者:
  804. 创建日期:2008.9.1
  805. 函数功能说明:主程序发送命令数据
  806. 输入参数:
  807. 输出参数:
  808. 返回值:
  809. 更新信息:
  810. 更新日志1:
  811. 日期:
  812. 修改者:
  813. 修改内容:
  814. 修改原因:
  815. ***************************************************************************/
  816. static void _send_inst(void)
  817. {
  818. // CONTINUE_DATA_BUF_DEF *ptBuf_con=&g_tLcdComm.tContinue;
  819. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  820. INST_DEF *pt=&ptBuf->tInst[ptBuf->tail];
  821. //
  822. Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para);
  823. ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK;
  824. }
  825. /**************************************************************************
  826. 函数名称:Send_Continue_Datas
  827. 函数版本:1.00
  828. 作者:
  829. 创建日期:2008.9.1
  830. 函数功能说明:主程序发送菜单数据命令
  831. 输入参数:
  832. 输出参数:
  833. 返回值:
  834. 更新信息:
  835. 更新日志1:
  836. 日期:
  837. 修改者:
  838. 修改内容:
  839. 修改原因:
  840. ***************************************************************************/
  841. #define HMI_V2
  842. #ifdef HMI_V2
  843. static void _send_continue_datas_0(void)
  844. {
  845. int i;
  846. BYTE num=0,cnt=0,bytenum=0;
  847. // BYTE checksum=0;
  848. // BYTE *pd=g_tUartHMI.arrSendBuf;
  849. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  850. BYTE srcbuf[UART_FRAME_LEN];
  851. BYTE dstbuf[UART_FRAME_LEN];
  852. BYTE *pd=srcbuf+2;
  853. // pd+=10; /*报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据*/
  854. while(ptBuf->head!=ptBuf->tail)
  855. {
  856. BYTE len;
  857. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail];
  858. len=(pt->attrib&0x3f);
  859. for(cnt=ptBuf->index;cnt<len;)
  860. {
  861. BYTE *pdat=&pt->dat[cnt];
  862. if(pdat[0]>0xa0&&pdat[1]>0xa0) //是汉字
  863. {
  864. BYTE FieldCode,BitCode;
  865. BYTE hzdot[32];
  866. DWORD addr;
  867. FieldCode=pdat[0]-0xa1; //wjw 区码
  868. BitCode=pdat[1]-0xa1; //wjw 位码
  869. if(FieldCode>=15) //15~19 ASCII码的位置
  870. {
  871. FieldCode-=4;
  872. }
  873. // 32:1个字所占的字节
  874. // 区码:1个区有94个汉字,位码:即1个区中汉字的实际位置
  875. addr=((DWORD)FieldCode*94+BitCode)*32;//wjw 计算出全字库的点阵地址
  876. _get_hz_dot(hzdot,&hzk_table[addr]);
  877. *pd++=pt->x+cnt*8;
  878. *pd++=pt->y;
  879. *pd++=(pt->attrib&0x80)+32;
  880. for(i=0;i<32;i++)
  881. {
  882. *pd++=hzdot[i];
  883. }
  884. num+=(32+3);
  885. cnt+=2;
  886. ptBuf->index+=2;
  887. }
  888. else
  889. {
  890. *pd++=pt->x+cnt*8;
  891. *pd++=pt->y;
  892. *pd++=(pt->attrib&0x80)+0x41;
  893. *pd++=pdat[0];
  894. num+=(1+3);
  895. cnt+=1;
  896. ptBuf->index+=1;
  897. }
  898. bytenum++;
  899. if(num>200)break;
  900. }
  901. if(cnt>=len)
  902. {
  903. ptBuf->tail++;
  904. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  905. ptBuf->index=0;
  906. }
  907. if(num>200)break;
  908. }
  909. pd=srcbuf;
  910. *pd++=HMI_CMD_WRITE_DATAS; //命令码
  911. *pd++=bytenum; //数目
  912. (void)protocol_packet(srcbuf, (int)num+2, MAIN_BOARD, HMI_BOARD, dstbuf);
  913. //添加到缓存区
  914. Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf);
  915. }
  916. static void _send_continue_datas_1(void)
  917. {
  918. int i;
  919. BYTE num=0;
  920. // BYTE checksum=0;
  921. //BYTE *pd=g_tUartHMI.arrSendBuf;
  922. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  923. int offset=0;//offend=0;
  924. BYTE srcbuf[UART_FRAME_LEN];
  925. BYTE dstbuf[UART_FRAME_LEN];
  926. BYTE *pd=srcbuf+2;
  927. //pd+=8+offset; //报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据
  928. while(ptBuf->head!=ptBuf->tail)
  929. {
  930. int len;
  931. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail];
  932. len=(pt->attrib&0x3f);
  933. *pd++=pt->x;
  934. *pd++=pt->y;
  935. *pd++=pt->attrib;
  936. printf("ptBuf->tail=%d, x=%02x, y=%02x, attrib=%02x\n",
  937. ptBuf->tail, pt->x, pt->y, pt->attrib); // zhl TODO 打印
  938. for(i=0;i<len;i++)
  939. {
  940. *pd++=pt->dat[i];
  941. }
  942. num+=(3+len);
  943. ptBuf->tail++;
  944. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  945. if(num>200)break;
  946. }
  947. #if 0
  948. pd=g_tUartHMI.arrSendBuf;
  949. *pd++=0x68;
  950. *pd++=num+6+offset;
  951. *pd++=num+6+offset;
  952. *pd++=0x68;
  953. *pd++=HMI_CMD_WRITE_DATAS; //命令码
  954. *pd++=num; //数目
  955. //计算校验和
  956. pd=&g_tUartHMI.arrSendBuf[4];
  957. for(i=0;i<g_tUartHMI.arrSendBuf[1];i++)
  958. {
  959. checksum+=*pd++;
  960. }
  961. *pd++=checksum;
  962. #else
  963. pd=srcbuf;
  964. *pd++=HMI_CMD_WRITE_DATAS; //命令码
  965. *pd++=num; //数目
  966. #endif
  967. (void)protocol_packet(srcbuf, (int)(num+6+offset), MAIN_BOARD, HMI_BOARD, dstbuf);
  968. //添加到缓存区
  969. Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf);
  970. }
  971. static void _send_continue_datas(void)
  972. {
  973. if(g_hzk_table_flag==0)
  974. {
  975. _send_continue_datas_0();
  976. }
  977. else
  978. {
  979. _send_continue_datas_1();
  980. }
  981. }
  982. #else
  983. static void _send_continue_datas(void)
  984. {
  985. int i;
  986. BYTE num=0,cnt=0,bytenum=0;
  987. // BYTE checksum=0;
  988. // BYTE *pd=g_tUartHMI.arrSendBuf;
  989. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  990. BYTE srcbuf[UART_FRAME_LEN];
  991. BYTE dstbuf[UART_FRAME_LEN];
  992. BYTE *pd=srcbuf+2;
  993. // pd+=10; /*报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据*/
  994. while(ptBuf->head!=ptBuf->tail)
  995. {
  996. BYTE len;
  997. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail];
  998. len=(pt->attrib&0x3f);
  999. for(cnt=ptBuf->index;cnt<len;)
  1000. {
  1001. BYTE *pdat=&pt->dat[cnt];
  1002. if(pdat[0]>0xa0&&pdat[1]>0xa0) //是汉字
  1003. {
  1004. BYTE FieldCode,BitCode;
  1005. BYTE hzdot[32];
  1006. DWORD addr;
  1007. FieldCode=pdat[0]-0xa1; //wjw 区码
  1008. BitCode=pdat[1]-0xa1; //wjw 位码
  1009. if(FieldCode>=15) //15~19 ASCII码的位置
  1010. {
  1011. FieldCode-=4;
  1012. }
  1013. // 32:1个字所占的字节
  1014. // 区码:1个区有94个汉字,位码:即1个区中汉字的实际位置
  1015. addr=((DWORD)FieldCode*94+BitCode)*32;//wjw 计算出全字库的点阵地址
  1016. _get_hz_dot(hzdot,&hzk_table[addr]);
  1017. *pd++=pt->x+cnt*8;
  1018. *pd++=pt->y;
  1019. *pd++=(pt->attrib&0x80)+32;
  1020. for(i=0;i<32;i++)
  1021. {
  1022. *pd++=hzdot[i];
  1023. }
  1024. num+=(32+3);
  1025. cnt+=2;
  1026. ptBuf->index+=2;
  1027. }
  1028. else
  1029. {
  1030. *pd++=pt->x+cnt*8;
  1031. *pd++=pt->y;
  1032. *pd++=(pt->attrib&0x80)+0x41;
  1033. *pd++=pdat[0];
  1034. num+=(1+3);
  1035. cnt+=1;
  1036. ptBuf->index+=1;
  1037. }
  1038. bytenum++;
  1039. if(num>200)break;
  1040. }
  1041. if(cnt>=len)
  1042. {
  1043. ptBuf->tail++;
  1044. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  1045. ptBuf->index=0;
  1046. }
  1047. if(num>200)break;
  1048. }
  1049. pd=srcbuf;
  1050. *pd++=HMI_CMD_WRITE_DATAS; //命令码
  1051. *pd++=bytenum; //数目
  1052. (void)protocol_packet(srcbuf, (int)num+2, MAIN_BOARD, HMI_BOARD, dstbuf);
  1053. //添加到缓存区
  1054. Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf);
  1055. }
  1056. #endif
  1057. /******************************************************************************
  1058. 函数名称: _hmi_changehzk
  1059. 函数版本: 01.01
  1060. 创建作者: 钟务贵
  1061. 创建日期: 2015-07-16
  1062. 函数说明: 根据液晶点阵类型,转换字库,原始字库为横向正序
  1063. 参数说明: type:液晶点阵类型
  1064. 返回值: 无
  1065. 修改记录:
  1066. */
  1067. static int _hmi_changehzk(u8 type)
  1068. {
  1069. int i, j, k, n, ch, data_idx;
  1070. u8 hz[32], data[32];
  1071. if(hzk_table == NULL)
  1072. {
  1073. return 0;
  1074. }
  1075. switch(type)
  1076. {
  1077. case LCD_HN:
  1078. {
  1079. if (hzk_change_type == LCD_HN)
  1080. {
  1081. return 0;
  1082. }
  1083. hzk_change_type = LCD_HN;
  1084. }
  1085. break;
  1086. case LCD_VN:
  1087. {
  1088. if (hzk_change_type == LCD_VN)
  1089. {
  1090. return 0;
  1091. }
  1092. // 纵向取模,字节倒序
  1093. for (k=0; k<hzk_num; k++)
  1094. {
  1095. memcpy(hz, &hzk_table[k*32], 32);
  1096. //第一组8字节
  1097. for(i=7; i >=0 ; i=i-1)
  1098. {
  1099. ch = 0;
  1100. n = 0;
  1101. for(j=0; j<16; j=j+2)
  1102. {
  1103. ch |= ((hz[j] >> i) & 0x01) << n ;
  1104. n++;
  1105. }
  1106. data[data_idx++] = ch;
  1107. }
  1108. //第二组8字节
  1109. for(i=7; i >=0 ; i=i-1)
  1110. {
  1111. ch = 0;
  1112. n = 0;
  1113. for(j=1; j<16; j=j+2)
  1114. {
  1115. ch |= ((hz[j] >> i) & 0x01) << n ;
  1116. n++;
  1117. }
  1118. data[data_idx++] = ch;
  1119. }
  1120. //第三组8字节
  1121. for(i=7; i >=0 ; i=i-1)
  1122. {
  1123. ch = 0;
  1124. n = 0;
  1125. for(j=16; j<32; j=j+2)
  1126. {
  1127. ch |= ((hz[j] >> i) & 0x01) << n ;
  1128. n++;
  1129. }
  1130. data[data_idx++] = ch;
  1131. }
  1132. //第四组8字节
  1133. for(i=7; i >=0 ; i=i-1)
  1134. {
  1135. ch = 0;
  1136. n = 0;
  1137. for(j=17; j<32; j=j+2)
  1138. {
  1139. ch |= ((hz[j] >> i) & 0x01) << n ;
  1140. n++;
  1141. }
  1142. data[data_idx++] = ch;
  1143. }
  1144. memcpy(&hzk_table[k*32], data, 32);
  1145. data_idx = 0;
  1146. hzk_change_type = LCD_VN;
  1147. }
  1148. }
  1149. break;
  1150. }
  1151. return 0;
  1152. };
  1153. /*------------------------------ 测试函数 -------------------------------------
  1154. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  1155. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  1156. */
  1157. /*------------------------------ 文件结束 -------------------------------------
  1158. */