LcdComm.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  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. int g_hmi_type;
  38. u8 lcd_dot_type; // 显示点阵显示类型
  39. int hzk_num; // 汉字库中汉字个数
  40. int hzk_change_type; // 当前切换的汉字库类型
  41. uint32_t lcd_comm_delay=0; // 面板通讯超时
  42. /*------------------------------ 函数声明 -------------------------------------
  43. */
  44. int hzk_read_file(void);
  45. //static void _reset_uartHMI_link(void);
  46. static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len); //len为参数长度
  47. static void _hmi_call(void);
  48. static void _put_key(BYTE key);
  49. static void _hmi_comm_recv(BYTE *ps);
  50. static void _hmi_comm_send(void);
  51. void _hmi_uart_send(void);
  52. static void _send_inst(void);
  53. static int _send_continue_datas(void);
  54. static void _send_dot_datas(void);
  55. /*------------------------------ 外部函数 -------------------------------------
  56. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  57. */
  58. void mainImage_Init(void)
  59. {
  60. u32 len;
  61. u8 *buf;
  62. struct file * pfile;
  63. loff_t pos;
  64. g_tLcdComm.tImage.pBuf=NULL;
  65. // 打开文件
  66. pfile = rt_file_open("/app/data/mainImage.lcd",O_RDONLY ,0);
  67. if(IS_ERR(pfile))
  68. {
  69. //rt_printf("\r\n打开 app/data/mainImage.lcd 失败\r\n");
  70. return ;
  71. }
  72. // 得到文件长度
  73. len = rt_file_getfile_size(pfile);
  74. if(len <= 0)
  75. {
  76. rt_file_close(pfile,0);
  77. return ;
  78. }
  79. // 分配内存
  80. buf = rt_malloc(len);
  81. if((buf) == NULL)
  82. {
  83. rt_printf("\r\n分配mainImage.lcd内存失败\r\n");
  84. rt_file_close(pfile,0);
  85. return ;
  86. }
  87. // 读出内容
  88. pos = 0;
  89. if(rt_file_read(pfile,buf,len,&pos) != len)
  90. {
  91. rt_file_close(pfile,0);
  92. rt_free(buf);
  93. return ;
  94. }
  95. // 关闭文件
  96. rt_file_close(pfile,0);
  97. g_tLcdComm.tImage.pBuf=buf;
  98. { // 获取主接线图的内容
  99. WORD num;
  100. int i;
  101. D_UNIT_DEF tUnit;
  102. YC_UNIT_DEF tYc;
  103. MAIN_IMAGE_DEF *pm=&g_tLcdComm.tImage;
  104. BYTE *pd=buf;//主接线图的位置
  105. pm->sYxNum=0;
  106. pm->sYcNum=0;
  107. pm->sImageX=pd[0]+((WORD)pd[1]<<8);pd+=2;
  108. pm->sImageY=pd[0]+((WORD)pd[1]<<8);pd+=2;
  109. pm->lnImageAddr=pd[0]+((DWORD)pd[1]<<8)+((DWORD)pd[2]<<16)+((DWORD)pd[3]<<24);pd+=4;
  110. num=pd[0]+((WORD)pd[1]<<8);pd+=2;
  111. for(i=0;i<num;i++) //器件初始化
  112. {
  113. tUnit.sx=pd[0]+((WORD)pd[1]<<8);pd+=2;
  114. tUnit.sy=pd[0]+((WORD)pd[1]<<8);pd+=2;
  115. tUnit.yx_di=pd[0]+((WORD)pd[1]<<8);pd+=2;
  116. tUnit.yx_attrib=pd[0];pd+=2;
  117. tUnit.yx_value=0;
  118. pd+=4; // 遥控点号
  119. tUnit.addr_close=pd[0]+((DWORD)pd[1]<<8)+((DWORD)pd[2]<<16)+((DWORD)pd[3]<<24);pd+=4;
  120. tUnit.addr_open=pd[0]+((DWORD)pd[1]<<8)+((DWORD)pd[2]<<16)+((DWORD)pd[3]<<24);pd+=4;
  121. tUnit.addr_third=pd[0]+((DWORD)pd[1]<<8)+((DWORD)pd[2]<<16)+((DWORD)pd[3]<<24);pd+=4;
  122. pm->tYxUnits[pm->sYxNum++]=tUnit;
  123. if(pm->sYxNum>=MAX_YX_UNITS)return ;
  124. }
  125. num=pd[0]+((WORD)pd[1]<<8);pd+=2;
  126. for(i=0;i<num;i++)
  127. {
  128. tYc.sx=pd[0]+((WORD)pd[1]<<8);pd+=2;
  129. tYc.sy=pd[0]+((WORD)pd[1]<<8);pd+=2;
  130. tYc.yc_di=pd[0]+((WORD)pd[1]<<8);pd+=2;
  131. {
  132. int j;
  133. BYTE *p=tYc.fmtstr;
  134. for(j=0;j<32;j++)
  135. {
  136. *p++=*pd++;
  137. }
  138. *p='\0';
  139. }
  140. pm->tYcUnits[pm->sYcNum++]=tYc;
  141. if(pm->sYcNum>=MAX_YC_UNITS)return ;
  142. }
  143. }
  144. m_LockIcon[0]=' ';
  145. m_LockIcon[1]='\0';
  146. }
  147. int mainimage_exit(void)
  148. {
  149. if(g_tLcdComm.tImage.pBuf!=NULL)
  150. {
  151. rt_free(g_tLcdComm.tImage.pBuf);
  152. }
  153. return 0;
  154. }
  155. void lcd_DrawImage(short x,short y,BYTE *ps,unsigned char mode) //画图标,index为索引值,与按键的属性定义一致
  156. {
  157. int h,w,head;
  158. short width,height,num; //点阵高
  159. BYTE *pd;
  160. DOT_DATA_BUF_DEF *pdot=&g_tLcdComm.tDot;
  161. width=(ps[1]<<8)+ps[0];
  162. height=(ps[3]<<8)+ps[2];
  163. if(width>SCREENWIDTH||height>SCREENHEIGHT||(x<0||x>SCREENWIDTH)||(y<0||y>SCREENHEIGHT))
  164. {
  165. rt_printf("\r\n image error !width=%d height=%d",width,height);
  166. return;
  167. }
  168. head=pdot->head;
  169. pd=pdot->dot[head].dat;
  170. num=0;
  171. ps+=4;
  172. pdot->dot[head].x=x;
  173. pdot->dot[head].y=y;
  174. pdot->dot[head].w=width;
  175. pdot->dot[head].mode=mode;
  176. pdot->dot[head].ex=x;
  177. for(h=0;h<height;h++)
  178. {
  179. for(w=0;w<width/8;w++)
  180. {
  181. pd[num++]=*ps++;
  182. if(num>=230)
  183. {
  184. bool bline;// 换行
  185. pdot->dot[head].num=num;
  186. pdot->head++;
  187. pdot->head&=LCD_MAX_DOT_MASK;
  188. if(pdot->head==pdot->tail) /*缓冲区满了*/
  189. {
  190. pdot->tail++;
  191. pdot->tail&=LCD_MAX_DOT_MASK;
  192. }
  193. head=pdot->head;
  194. pd=pdot->dot[head].dat;
  195. bline=((w+1)>=width/8)?true:false;
  196. pdot->dot[head].x=x;
  197. pdot->dot[head].y=(bline)?(h+1):h;
  198. pdot->dot[head].w=width;
  199. pdot->dot[head].mode=mode;
  200. pdot->dot[head].ex=(bline)?x:(x+(w+1)*8);
  201. num=0;
  202. }
  203. }
  204. }
  205. if(num>0)
  206. {
  207. pdot->dot[head].num=num;
  208. pdot->head++;
  209. pdot->head&=LCD_MAX_DOT_MASK;
  210. if(pdot->head==pdot->tail) /*缓冲区满了*/
  211. {
  212. pdot->tail++;
  213. pdot->tail&=LCD_MAX_DOT_MASK;
  214. }
  215. }
  216. }
  217. /**************************************************************************
  218. 函数名称:lcdcomm_init
  219. 函数版本:1.00
  220. 作者:
  221. 创建日期:2008.9.1
  222. 函数功能说明:初始化面板通信
  223. 输入参数:
  224. 输出参数:
  225. 返回值:
  226. 更新信息:
  227. 更新日志1:
  228. 日期:
  229. 修改者:
  230. 修改内容:
  231. 修改原因:
  232. ***************************************************************************/
  233. void lcdcomm_init(void)
  234. {
  235. memset((BYTE *)&g_tLcdComm,0,sizeof(g_tLcdComm));
  236. memset((BYTE *)&g_tUartHMI,0,sizeof(g_tUartHMI));
  237. led_init_hmi();
  238. mainImage_Init(); //主接线图初始化
  239. mmd_menu_cfg_init();
  240. mmi_ScreenInit();
  241. g_tLcdComm.tInit.flag=true;
  242. g_tLcdComm.bRecv=true;
  243. g_tLcdComm.bCall = true;
  244. lcd_comm_delay = ustimer_get_origin();
  245. g_dw_led[0]=0;
  246. g_dw_led[1]=0;
  247. g_dw_ledsave[0]=0; // 灯状态
  248. g_dw_ledsave[1]=0; // 灯状态
  249. // 通过面板配置灯,获取灯的状态,使用脉宽==0 黄 ==1 绿 ==2 红 通道0 ==0x55(85) 六键 管理板,其他默认6键控制单元
  250. {
  251. u32 slot;
  252. // 检查状态板是否配置
  253. slot = equ_get_slot_by_type(BOARD_TYPE_LCD_16LED);
  254. if(slot ==0)
  255. {
  256. slot = equ_get_slot_by_type(BOARD_TYPE_LCD_24LED);
  257. if(slot==0) //jack.liu 2020 增加26个灯灯板定义
  258. slot = equ_get_slot_by_type(BOARD_TYPE_LCD_26LED);
  259. }
  260. if(slot >0)
  261. {
  262. int i;
  263. u8 index;
  264. struct equ_config_do *ecd;
  265. ecd = g_equ_config_do;
  266. for(i=0;i<g_equ_config->do_num;i++)
  267. {
  268. if(ecd[i].slot== slot)
  269. {
  270. index=ecd[i].index;
  271. if(index>=LCD_MAX_LED)continue;
  272. g_tLcdComm.tInit.para[index]=(BYTE)ecd[i].time_pulse;
  273. }
  274. }
  275. #ifndef DISP_SET_67KEY
  276. if(g_tLcdComm.tInit.para[0]==200)
  277. {
  278. g_tScreen.lcd_type=LCD_TYPE_6KEY;
  279. }
  280. else if(g_tLcdComm.tInit.para[0]==10||g_tLcdComm.tInit.para[0]==11||g_tLcdComm.tInit.para[0]==12) // 9键定义 10 黄 11绿 12 红
  281. {
  282. g_tLcdComm.tInit.para[0]-=10;
  283. g_tScreen.lcd_type=LCD_TYPE_160_KEY9;
  284. }
  285. #endif
  286. }
  287. }
  288. }
  289. /**************************************************************************
  290. 函数名称:HMI_Comm_App
  291. 函数版本:1.00
  292. 作者:
  293. 创建日期:2008.9.1
  294. 函数功能说明:主函数调用与面板通信任务,10ms调用1次,100ms左右调用一次刷屏命令
  295. 输入参数:
  296. 输出参数:
  297. 返回值:
  298. 更新信息:
  299. 更新日志1:
  300. 日期:
  301. 修改者:
  302. 修改内容:
  303. 修改原因:
  304. ***************************************************************************/
  305. void HMI_Comm_App(void) /*10毫秒调用一次*/
  306. {
  307. #if 1
  308. //正在升级面板程序
  309. if(is_down_program())
  310. {
  311. //有数据
  312. if(g_tUartHMI.r_head != g_tUartHMI.r_tail)
  313. {
  314. //接收处理
  315. down_program_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]);
  316. g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1);
  317. }
  318. else
  319. {
  320. //接收超时处理
  321. down_program_recv_timeout();
  322. }
  323. //发送处理
  324. down_program_send();
  325. return;
  326. }
  327. //内置GPRS拨号时有时候占用资源比较多,所以调整为15秒比较保险
  328. if ((g_tUartHMI.r_head == g_tUartHMI.r_tail)
  329. && (ustimer_get_duration(lcd_comm_delay) > 5*USTIMER_SEC))//
  330. {
  331. static bool b_first=false;
  332. g_tLcdComm.tInit.flag=true;
  333. g_tLcdComm.b_init_OK = false;
  334. if(!soe_check(EV_HMIERR))
  335. {
  336. //soe_record_ev(EV_HMIERR, 1, 0,0,0 );
  337. }
  338. if(!b_first)
  339. {
  340. int i;
  341. b_first = true;
  342. for(i=0;i<CFG_UART_NUM_MAX;i++)
  343. {
  344. // 如果硬件通道不存在,跳过
  345. if(UART_CHANNEL[i]<0)continue;
  346. #ifndef CFG_UART_232_DEBUG_TO_COMM
  347. // 如果此串口不是系统控制台串口,协议也不是空闲,初始化串口
  348. if(UART_CHANNEL[i] != g_con_uart_index && tRunPara.tUartPara[i].wProtocol != PROTOCOL_IDLE)
  349. #else
  350. if(tRunPara.tUartPara[i].wProtocol != PROTOCOL_IDLE)
  351. #endif
  352. {
  353. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_HMI) // 面板规约
  354. {
  355. int ret;
  356. ret = uart_open(UART_CHANNEL[i],tRunPara.tUartPara[i].dBaud,tRunPara.tUartPara[i].wParity);
  357. if (ret < 0) {
  358. printf("%s: outside uart %d open failed!\n", __FUNCTION__, UART_CHANNEL[i]);
  359. }
  360. RS_Ena_Init(i);
  361. RS_Recv_Enable(i);
  362. g_h_boj[0].fd = UART_CHANNEL[i];
  363. user_conf_init(); //用户配置初始化(面板)
  364. #ifdef CPU_FUXI
  365. uart_isr_thread_create(i);
  366. #endif
  367. lcdcomm_init();
  368. }
  369. }
  370. }
  371. }
  372. lcd_comm_delay = ustimer_get_origin();
  373. }
  374. if(g_tUartHMI.r_head != g_tUartHMI.r_tail)
  375. {
  376. _hmi_comm_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]);
  377. g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1);
  378. lcd_comm_delay = ustimer_get_origin();
  379. g_tLcdComm.bRecv=true;
  380. }
  381. _hmi_comm_send();
  382. #endif
  383. }
  384. /**************************************************************************
  385. 函数名称:Add_Continue_Data
  386. 函数版本:1.00
  387. 作者:
  388. 创建日期:2008.9.1
  389. 函数功能说明:菜单驱动调用函数,将要显示的数据存入缓冲区中
  390. 输入参数:
  391. 输出参数:
  392. 返回值:
  393. 更新信息:
  394. 更新日志1:
  395. 日期:
  396. 修改者:
  397. 修改内容:
  398. 修改原因:
  399. ***************************************************************************/
  400. void Add_Continue_Data(BYTE x,BYTE y,BYTE *pdat,BYTE len,BYTE mode)
  401. {
  402. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  403. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->head];
  404. BYTE cnt;
  405. pt->x=x;
  406. pt->y=y;
  407. if(g_tScreen.lcd_type==LCD_TYPE_160160)
  408. {
  409. if(x+len>20)
  410. {
  411. len=20-x;
  412. }
  413. }
  414. else if(g_tScreen.lcd_type==LCD_TYPE_128128||g_tScreen.lcd_type==LCD_TYPE_12864)
  415. {
  416. if(x+len>16)
  417. {
  418. len=16-x;
  419. }
  420. }
  421. else if(g_tScreen.lcd_type==LCD_TYPE_12232)
  422. {
  423. if(x+len>15)
  424. {
  425. len=15-x;
  426. }
  427. }
  428. pt->attrib=len;
  429. if(mode==1)
  430. {
  431. pt->attrib|=0x80;
  432. }
  433. else if(mode==2)
  434. {
  435. pt->attrib|=0x40;
  436. }
  437. for(cnt=0;cnt<len;cnt++) // 汉字处理
  438. {
  439. pt->dat[cnt]=*pdat;
  440. pdat++;
  441. }
  442. ptBuf->head++;
  443. ptBuf->head&=LCD_MAX_CONTINUE_MASK;
  444. if(ptBuf->head==ptBuf->tail) /*缓冲区满了*/
  445. {
  446. ptBuf->tail++;
  447. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  448. }
  449. }
  450. /**************************************************************************
  451. 函数名称:Add_Clear_Screen
  452. 函数版本:1.00
  453. 作者:
  454. 创建日期:2008.9.1
  455. 函数功能说明:清屏命令
  456. 输入参数:
  457. 输出参数:
  458. 返回值:
  459. 更新信息:
  460. 更新日志1:
  461. 日期:
  462. 修改者:
  463. 修改内容:
  464. 修改原因:
  465. ***************************************************************************/
  466. void Add_Clear_Screen(void) //mmidrv.c 调用
  467. {
  468. LCD_COMM_DEF *pt=&g_tLcdComm;
  469. pt->bClrScreen=true; //清全屏
  470. // 清发送缓冲区
  471. pt->tContinue.head=pt->tContinue.tail=0;
  472. // 字从首字开始
  473. pt->tContinue.index=0;
  474. memset(pt->lcdbuf,0,sizeof(pt->lcdbuf));
  475. memset(pt->lcdattrib,0,sizeof(pt->lcdattrib));
  476. }
  477. /**************************************************************************
  478. 函数名称:add_led_test
  479. 函数版本:1.00
  480. 作者:
  481. 创建日期:2008.9.1
  482. 函数功能说明:清屏命令
  483. 输入参数:
  484. 输出参数:
  485. 返回值:
  486. 更新信息:
  487. 更新日志1:
  488. 日期:
  489. 修改者:
  490. 修改内容:
  491. 修改原因:
  492. ***************************************************************************/
  493. void add_led_test(u8 test_no)
  494. {
  495. LCD_COMM_DEF *pt = &g_tLcdComm;
  496. switch (test_no)
  497. {
  498. case TEST_LED:
  499. pt->bTestLed = true;
  500. break;
  501. case TEST_LCD:
  502. pt->bTestLcd = true;
  503. break;
  504. }
  505. }
  506. void add_rmt_pair(u8 pair)
  507. {
  508. LCD_COMM_DEF *pt = &g_tLcdComm;
  509. switch (pair)
  510. {
  511. case TEST_LED:
  512. pt->bTeleMatch = true;
  513. break;
  514. case TEST_LCD:
  515. pt->bTeleClrMatch = true;
  516. break;
  517. }
  518. }
  519. /**************************************************************************
  520. 函数名称:Get_Key
  521. 函数版本:1.00
  522. 作者:
  523. 创建日期:2008.9.1
  524. 函数功能说明:获得按键函数
  525. 输入参数:
  526. 输出参数:
  527. 返回值:
  528. 更新信息:
  529. 更新日志1:
  530. 日期:
  531. 修改者:
  532. 修改内容:
  533. 修改原因:
  534. ***************************************************************************/
  535. BYTE Get_Key(void)
  536. {
  537. LCD_KEY_DEF *pt=&g_tLcdComm.tKey;
  538. BYTE key;
  539. if(pt->head==pt->tail)return NO_KEY;
  540. key=pt->keybuf[pt->tail];
  541. pt->tail++;
  542. pt->tail&=LCD_KEY_MASK;
  543. return key;
  544. }
  545. /******************************************************************************
  546. 函数名称: HMI_Board_Recv
  547. 函数版本: 01.01
  548. 创建作者: xxxxxx
  549. 创建日期: 2014-12-10
  550. 函数说明: 接收帧
  551. 参数说明: len:帧长度
  552. para:接收帧内容
  553. 返回值: 无
  554. 修改记录:
  555. */
  556. void HMI_Board_Recv(int len,BYTE *para)
  557. {
  558. UART_COMM *pt=&g_tUartHMI;
  559. memcpy(pt->r_buf[pt->r_head], para, len);
  560. pt->r_head = (pt->r_head + 1) & (UART_FRAME_MAXCNT - 1);
  561. }
  562. /******************************************************************************
  563. 函数名称: hzk_read_file
  564. 函数版本: 01.01
  565. 创建作者: xxxxxx
  566. 创建日期: 2013-08-08
  567. 函数说明: 读取汉字库
  568. 参数说明:
  569. 返回值:
  570. 0: 成功
  571. 其它: 失败
  572. 修改记录:
  573. */
  574. int hzk_read_file(void)
  575. {
  576. u32 len;
  577. u16 crc16;
  578. struct file * pfile;
  579. loff_t pos;
  580. // 打开文件
  581. pfile = rt_file_open("/app/data/hzk.bin",O_RDONLY ,0);
  582. if(IS_ERR(pfile))
  583. {
  584. return -1;
  585. }
  586. // 得到文件长度
  587. len = rt_file_getfile_size(pfile);
  588. if(len <= 0)
  589. {
  590. rt_file_close(pfile,0);
  591. return -11;
  592. }
  593. // 分配内存
  594. hzk_table = rt_malloc(len);
  595. if(hzk_table == NULL)
  596. {
  597. rt_file_close(pfile,0);
  598. return -2;
  599. }
  600. // 读出内容
  601. pos = 0;
  602. if(rt_file_read(pfile,hzk_table,len,&pos) != len)
  603. {
  604. rt_file_close(pfile,0);
  605. rt_free(hzk_table);
  606. return -3;
  607. }
  608. // 关闭文件
  609. rt_file_close(pfile,0);
  610. // 检查CRC
  611. crc16 = CrcStr(hzk_table,len-2);
  612. if(crc16 != *(u16*)(hzk_table+len-2))
  613. {
  614. rt_free(hzk_table);
  615. hzk_table = NULL;
  616. return -4;
  617. }
  618. hzk_num = (len-2) / 32;
  619. return 0;
  620. }
  621. /******************************************************************************
  622. 函数名称: hzk_exit
  623. 函数版本: 01.01
  624. 创建作者: xxxxxx
  625. 创建日期: 2015-04-16
  626. 函数说明: LED配置退出
  627. 参数说明: 无
  628. 返回值: 成功返回0.
  629. 修改记录:
  630. */
  631. int hzk_exit(void)
  632. {
  633. if(hzk_table)
  634. {
  635. rt_free(hzk_table);
  636. }
  637. return 0;
  638. }
  639. /*------------------------------ 内部函数 -------------------------------------
  640. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  641. */
  642. /**************************************************************************
  643. 函数名称:ResetUartHMILink
  644. 函数版本:1.00
  645. 作者:
  646. 创建日期:2008.9.1
  647. 函数功能说明:复归接收数据结构
  648. 输入参数:
  649. 输出参数:
  650. 返回值:
  651. 更新信息:
  652. 更新日志1:
  653. 日期:
  654. 修改者:
  655. 修改内容:
  656. 修改原因:
  657. ***************************************************************************/
  658. #if 0
  659. static void _reset_uartHMI_link(void)
  660. {
  661. g_tUartHMI.cTypeCounter=0;
  662. g_tUartHMI.cRecvCnt=0;
  663. }
  664. #endif
  665. /**************************************************************************
  666. 函数名称:Add_Inst_Frame
  667. 函数版本:1.00
  668. 作者:
  669. 创建日期:2008.9.1
  670. 函数功能说明:将发给面板的命令放入待发送指令缓冲区中
  671. 输入参数:
  672. 输出参数:
  673. 返回值:
  674. 更新信息:
  675. 更新日志1:
  676. 日期:
  677. 修改者:
  678. 修改内容:
  679. 修改原因:
  680. ***************************************************************************/
  681. static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len) //len为参数长度
  682. {
  683. BYTE i;
  684. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  685. INST_DEF *pt=&ptBuf->tInst[ptBuf->head];
  686. BYTE srcbuf[UART_FRAME_LEN];
  687. BYTE *pd=srcbuf;
  688. int offset=0;
  689. // if(pRunSet->bHMI_OLD)
  690. // {
  691. // offset = 2;
  692. // *pd++=0;// 控制域
  693. // *pd++=0xCC; // HMI地址为CC 状态板为55
  694. // }
  695. *pd++=cmd;
  696. for(i=0;i<len;i++)
  697. {
  698. *pd++=para[i];
  699. }
  700. //组包
  701. (void)protocol_packet(srcbuf, (int)len+5+offset, MAIN_BOARD, HMI_BOARD, pt->para);
  702. ptBuf->head++;
  703. ptBuf->head&=LCD_MAX_INST_MASK;
  704. if(ptBuf->head==ptBuf->tail) //缓冲区满了
  705. {
  706. ptBuf->tail++;
  707. ptBuf->tail&=LCD_MAX_INST_MASK;
  708. }
  709. }
  710. void HMI_add_inst_frame(BYTE cmd,BYTE *para,BYTE len)
  711. {
  712. _add_inst_frame(cmd,para, len) ;
  713. }
  714. #if 0 // 转换汉字库点阵,stc3100是正序纵显 ,(标准字库是正序横显)
  715. static void _get_hz_dot(char *hzdot,const char *hzk)
  716. {
  717. int i;
  718. for(i=0;i<32;i++) // 160*160液晶为负序横显
  719. {
  720. hzdot[i]=hzk[i];
  721. }
  722. for(m=0;m<8;m++)
  723. {
  724. BYTE dat0=0;
  725. BYTE dat1=0;
  726. BYTE dat2=0;
  727. BYTE dat3=0;
  728. for(i=0;i<8;i++)
  729. {
  730. dat0|=(((hzk[i*2]>>m)&0x01)<<i);
  731. dat1|=(((hzk[i*2+1]>>m)&0x01)<<i);
  732. dat2|=(((hzk[i*2+16]>>m)&0x01)<<i);
  733. dat3|=(((hzk[i*2+17]>>m)&0x01)<<i);
  734. }
  735. hzdot[m]=dat0;
  736. hzdot[m+8]=dat1;
  737. hzdot[m+16]=dat2;
  738. hzdot[m+24]=dat3;
  739. }
  740. }
  741. #endif
  742. /**************************************************************************
  743. 函数名称:HMI_Call
  744. 函数版本:1.00
  745. 作者:
  746. 创建日期:2008.9.1
  747. 函数功能说明:主程序召唤面板数据命令
  748. 输入参数:
  749. 输出参数:
  750. 返回值:
  751. 更新信息:
  752. 更新日志1:
  753. 日期:
  754. 修改者:
  755. 修改内容:
  756. 修改原因:
  757. ***************************************************************************/
  758. static void _hmi_call(void)
  759. {
  760. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  761. INST_DEF *pt;
  762. //缓存区没有数据,发查询命令
  763. {
  764. _add_inst_frame((BYTE)HMI_CMD_POLL, (BYTE*)0, 0);
  765. pt=&ptBuf->tInst[ptBuf->tail];
  766. //
  767. Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para);
  768. ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK;
  769. }
  770. }
  771. #ifdef GD_TEST_2021 // 处理复归按键
  772. void lcd_FG_key(BYTE cmd,BYTE key)
  773. {
  774. static DWORD dTKeyRst=0;
  775. static DWORD dTNoKey=0;
  776. static BYTE oldkey=NO_KEY;
  777. key&=KE_KEY_MASK;
  778. if(cmd==DRV_CMD_KEY&&key==HA_KEY_RST)
  779. {
  780. if(dTCounter-dTKeyRst>pRunSet->resReuseFuncFilterTime*T_1s) //复归按键满足防抖要求
  781. {
  782. if(key != oldkey)
  783. {
  784. oldkey=key;
  785. // ResetHzLed(0);
  786. // SignalReset(0,true);
  787. if(pRunSet->resReuseFuncSelect == 1) //解锁
  788. {
  789. g_run_stu.rmtjs=true;
  790. rt_printf("装置解锁\r\n");
  791. }
  792. else if(pRunSet->resReuseFuncSelect == 2) //复位
  793. {
  794. rt_printf("装置复位\r\n");
  795. watchdog_reset_cpu(2); //装置复位
  796. }
  797. }
  798. dTKeyRst=dTCounter;
  799. }
  800. dTNoKey=dTCounter;
  801. }
  802. else
  803. {
  804. if(dTCounter-dTNoKey>T_500ms)
  805. {
  806. dTKeyRst=dTCounter;
  807. oldkey=NO_KEY;
  808. }
  809. }
  810. }
  811. #endif
  812. /**************************************************************************
  813. 函数名称:Put_Key
  814. 函数版本:1.00
  815. 作者:
  816. 创建日期:2008.9.1
  817. 函数功能说明:将通信来的按键值放入缓冲中
  818. 输入参数:
  819. 输出参数:
  820. 返回值:
  821. 更新信息:
  822. 更新日志1:
  823. 日期:
  824. 修改者:
  825. 修改内容:
  826. 修改原因:
  827. ***************************************************************************/
  828. static void _put_key(BYTE lnkey)
  829. {
  830. LCD_KEY_DEF *pt=&g_tLcdComm.tKey;
  831. BYTE key=lnkey;
  832. if(g_tScreen.lcd_type==LCD_TYPE_6KEY) //老版本按键,ESC和ENTER键互换
  833. {
  834. key&=KE_KEY_MASK;
  835. if(key==HA_KEY_ENTER)
  836. {
  837. key=HA_KEY_ESC;
  838. }
  839. if(key==HA_KEY_ESC)
  840. {
  841. key=HA_KEY_ENTER;
  842. }
  843. key|=(lnkey&(~KE_KEY_MASK));
  844. }
  845. pt->keybuf[pt->head]=key;
  846. pt->head++;
  847. pt->head&=LCD_KEY_MASK;
  848. if(pt->head==pt->tail) //缓冲区满了
  849. {
  850. pt->tail++;
  851. pt->tail&=LCD_KEY_MASK;
  852. }
  853. g_tLcdComm.tLight.light=LIGHT_ON;
  854. g_tLcdComm.tLight.flag=true;
  855. g_tScreen.lnLightTime=dTCounter;
  856. }
  857. /**************************************************************************
  858. 函数名称:HMI_CommRecv
  859. 函数版本:1.00
  860. 作者:
  861. 创建日期:2008.9.1
  862. 函数功能说明:与面板通信的接收处理函数
  863. 输入参数:
  864. 输出参数:
  865. 返回值:
  866. 更新信息:
  867. 更新日志1:
  868. 日期:
  869. 修改者:
  870. 修改内容:
  871. 修改原因:
  872. ***************************************************************************/
  873. static void _hmi_comm_recv(BYTE *ps)
  874. {
  875. BYTE *pd=ps;
  876. int offset=0;
  877. g_tLcdComm.b_init_OK=true;
  878. switch(pd[4+offset]&0x1f)
  879. {
  880. case DRV_CMD_POWERON: //上电报文
  881. {
  882. if(pd[5+offset]==1)//上电初始化报文
  883. {
  884. g_tLcdComm.tInit.flag=true;
  885. }
  886. else
  887. {
  888. g_tLcdComm.bClrScreen=true;
  889. }
  890. }
  891. break;
  892. case DRV_CMD_KEY: //按键报文
  893. {
  894. _put_key(pd[5+offset]);
  895. _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0);
  896. }
  897. break;
  898. case DRV_CMD_TEMP: //面板遥信
  899. {
  900. }
  901. break;
  902. case DRV_CMD_YX: //遥信
  903. {
  904. }
  905. break;
  906. case DRV_CMD_SET: //定值
  907. {
  908. }
  909. break;
  910. case DRV_CMD_YKQ: //遥控器
  911. {
  912. g_rmt_op.key = pd[5];
  913. _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0);
  914. }
  915. break;
  916. case DRV_CMD_DOWN: //下载程序应答
  917. break;
  918. default:
  919. break;
  920. }
  921. #ifdef GD_TEST_2021 // 处理复归按键
  922. lcd_FG_key((pd[4+offset]&0x1f),pd[5+offset]);
  923. #endif
  924. }
  925. /**************************************************************************
  926. 函数名称:HMI_Comm_Send
  927. 函数版本:1.00
  928. 作者:
  929. 创建日期:2008.9.1
  930. 函数功能说明:启动面板通信的发送,包含重发机制。
  931. 输入参数:
  932. 输出参数:
  933. 返回值:
  934. 更新信息:
  935. 更新日志1:
  936. 日期:
  937. 修改者:
  938. 修改内容:
  939. 修改原因:
  940. ***************************************************************************/
  941. static void _hmi_comm_send(void)
  942. {
  943. static uint32_t us_call=0;
  944. static uint32_t us_lcdtest=0;
  945. static uint32_t us_ledtest=0;
  946. static uint32_t us_menu=0;
  947. static uint32_t us_send=0;
  948. LCD_COMM_DEF *pt=&g_tLcdComm;
  949. //pt->ReSend=0;
  950. if(pt->tInit.flag) //需初始化lcd
  951. {
  952. pt->tInstBuf.head=pt->tInstBuf.tail=0;
  953. Add_Clear_Screen();
  954. pt->tLight.light=LIGHT_ON;
  955. _add_inst_frame(HMI_CMD_INIT_LCD,pt->tInit.para,LCD_MAX_LED); //初始化lcd
  956. _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏
  957. _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //点亮背光
  958. pt->tInit.flag=false;
  959. pt->tLight.flag=false;
  960. pt->bClrScreen=false;
  961. pt->bFreshLed=true;
  962. hmi_update = 0;
  963. }
  964. else
  965. {
  966. if(pt->bClrScreen) //需初始化lcd
  967. {
  968. _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏
  969. //reset_update_flag();
  970. pt->bClrScreen=false;
  971. }
  972. if(pt->tLight.flag)
  973. {
  974. _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //背光控制
  975. pt->tLight.flag=false;
  976. }
  977. if(pt->bTestLed && (!pt->bLcdUpdate))
  978. {
  979. _add_inst_frame(HMI_CMD_LEDRUN,(void *)0,0); //led测试
  980. pt->bTestLed=false;
  981. pt->bLedUpdate = true;
  982. us_ledtest = ustimer_get_origin();
  983. }
  984. if(pt->bLedUpdate)
  985. {
  986. if (ustimer_get_duration(us_ledtest) >= 4*USTIMER_SEC)
  987. {
  988. pt->bLedUpdate = false;
  989. }
  990. lcd_comm_delay = ustimer_get_origin();
  991. }
  992. else
  993. {
  994. us_ledtest = ustimer_get_origin();
  995. }
  996. if(pt->bTestLcd && (!pt->bLedUpdate))
  997. {
  998. _add_inst_frame(HMI_CMD_TESTLCD,(void *)0,0); //lcd测试
  999. pt->bTestLcd=false;
  1000. pt->bLcdUpdate = true;
  1001. us_lcdtest = ustimer_get_origin();
  1002. }
  1003. if(pt->bLcdUpdate)
  1004. {
  1005. if (ustimer_get_duration(us_lcdtest) >= 3*USTIMER_SEC)
  1006. {
  1007. //reset_update_flag();
  1008. pt->bLcdUpdate = false;
  1009. }
  1010. lcd_comm_delay = ustimer_get_origin();
  1011. }
  1012. else
  1013. {
  1014. us_lcdtest = ustimer_get_origin();
  1015. }
  1016. if(pt->bTeleMatch)
  1017. {
  1018. pt->tTele.cmd = 0x10;
  1019. _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对
  1020. pt->bTeleMatch=false;
  1021. }
  1022. if(pt->bTeleClrMatch)
  1023. {
  1024. pt->tTele.cmd = 0x20;
  1025. _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对清除
  1026. pt->bTeleClrMatch=false;
  1027. }
  1028. // 1秒钟刷新一次LED
  1029. if (pt->b_init_OK)
  1030. {
  1031. static uint32_t us0_led;
  1032. u8 led_st[8];
  1033. int i;
  1034. if(ustimer_delay_origin2(&us0_led,USTIMER_SEC/8))
  1035. {
  1036. for(i=0;i<CFG_UART_NUM_MAX*2+CFG_ETH_NUM_MAX;i++)
  1037. {
  1038. if(g_run_stu.led[i]) // 232 1TX
  1039. {
  1040. led_set_pub(PUB_LED_232T1+i, LED_QUICK);
  1041. g_run_stu.led[i]=0;
  1042. }
  1043. }
  1044. if(g_bCommLed)
  1045. {
  1046. led_set_pub(PUB_LED_COMM, LED_QUICK);
  1047. g_bCommLed=false;
  1048. }
  1049. led_to_hmi();
  1050. if((g_dw_led[0]!=g_dw_ledsave[0])||(g_dw_led[1]!=g_dw_ledsave[1])||pt->bFreshLed)
  1051. {
  1052. led_st[0]=(BYTE)g_dw_led[0]; // 状态灯
  1053. led_st[1]=(BYTE)(g_dw_led[0]>>8); // 状态灯高位
  1054. led_st[2]=(BYTE)(g_dw_led[0]>>16); // 状态灯高位
  1055. led_st[3]=(BYTE)(g_dw_led[0]>>24); // 状态灯高位
  1056. led_st[4]=(BYTE)g_dw_led[1]; // 状态灯
  1057. led_st[5]=(BYTE)(g_dw_led[1]>>8); // 状态灯高位
  1058. led_st[6]=(BYTE)(g_dw_led[1]>>16); // 状态灯高位
  1059. led_st[7]=(BYTE)(g_dw_led[1]>>24); // 状态灯高位
  1060. _add_inst_frame(HMI_CMD_LED,led_st,8); //led点灯
  1061. g_dw_ledsave[0]=g_dw_led[0];
  1062. g_dw_ledsave[1]=g_dw_led[1];
  1063. pt->bFreshLed=false;
  1064. }
  1065. for(i=0;i<CFG_UART_NUM_MAX*2+CFG_ETH_NUM_MAX;i++)
  1066. {
  1067. led_set_pub(PUB_LED_232T1+i, LED_OFF);
  1068. }
  1069. led_set_pub(PUB_LED_COMM, LED_OFF);
  1070. }
  1071. }
  1072. }
  1073. if(!pt->bRecv)
  1074. {
  1075. if(ustimer_get_duration(us_send) >= USTIMER_SEC/2) // 发送接收超时0.5秒
  1076. {
  1077. if(pt->ReSend++>3) //重发3次
  1078. {
  1079. pt->tInit.flag=true;
  1080. pt->bRecv=true;
  1081. pt->ReSend=0;
  1082. }
  1083. else
  1084. {
  1085. us_send= ustimer_get_origin();
  1086. Sub_Uart_Frame(HMI_BOARD);
  1087. pt->bRecv=false;
  1088. }
  1089. }
  1090. return;
  1091. }
  1092. pt->ReSend=0;
  1093. //组织报文
  1094. if(pt->tInstBuf.head!=pt->tInstBuf.tail) //组织报文
  1095. {
  1096. _send_inst();
  1097. us_send= ustimer_get_origin();
  1098. pt->bRecv=false;
  1099. }
  1100. else if(pt->tDot.head!=pt->tDot.tail) //组织报文
  1101. {
  1102. _send_dot_datas();
  1103. us_send= ustimer_get_origin();
  1104. pt->bRecv=false;
  1105. }
  1106. else if(pt->tContinue.head!=pt->tContinue.tail) //组织报文
  1107. {
  1108. if(_send_continue_datas()>0)
  1109. {
  1110. us_send= ustimer_get_origin();
  1111. pt->bRecv=false;
  1112. }
  1113. }
  1114. else if(ustimer_get_duration(us_call) >= 200*USTIMER_MS) //无 发送数据,召唤
  1115. {
  1116. _hmi_call();
  1117. us_call = ustimer_get_origin();
  1118. us_send= ustimer_get_origin();
  1119. pt->bRecv=false;
  1120. pt->bCall = true;
  1121. }
  1122. else if(ustimer_get_duration(us_menu) >= 100*USTIMER_MS) // 无数据发送后再刷新菜单
  1123. {
  1124. mmi_Menu_Task();
  1125. us_menu= ustimer_get_origin();
  1126. }
  1127. }
  1128. /**************************************************************************
  1129. 函数名称:Send_Inst
  1130. 函数版本:1.00
  1131. 作者:
  1132. 创建日期:2008.9.1
  1133. 函数功能说明:主程序发送命令数据
  1134. 输入参数:
  1135. 输出参数:
  1136. 返回值:
  1137. 更新信息:
  1138. 更新日志1:
  1139. 日期:
  1140. 修改者:
  1141. 修改内容:
  1142. 修改原因:
  1143. ***************************************************************************/
  1144. static void _send_inst(void)
  1145. {
  1146. // CONTINUE_DATA_BUF_DEF *ptBuf_con=&g_tLcdComm.tContinue;
  1147. LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf;
  1148. INST_DEF *pt=&ptBuf->tInst[ptBuf->tail];
  1149. //
  1150. Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para);
  1151. ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK;
  1152. }
  1153. /**************************************************************************
  1154. 函数名称:Send_Continue_Datas
  1155. 函数版本:1.00
  1156. 作者:
  1157. 创建日期:2008.9.1
  1158. 函数功能说明:主程序发送菜单数据命令
  1159. 输入参数:
  1160. 输出参数:
  1161. 返回值:
  1162. 更新信息:
  1163. 更新日志1:
  1164. 日期:
  1165. 修改者:
  1166. 修改内容:
  1167. 修改原因:
  1168. ***************************************************************************/
  1169. static int _send_continue_datas(void)
  1170. {
  1171. int i,cnt;
  1172. BYTE num=0;
  1173. // BYTE checksum=0;
  1174. //BYTE *pd=g_tUartHMI.arrSendBuf;
  1175. CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue;
  1176. BYTE srcbuf[UART_FRAME_LEN];
  1177. BYTE dstbuf[UART_FRAME_LEN];
  1178. BYTE *pd=srcbuf+2;
  1179. //pd+=8+offset; //报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据
  1180. while(ptBuf->head!=ptBuf->tail)
  1181. {
  1182. int len;
  1183. CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail];
  1184. WORD bufoffset;
  1185. BYTE attrib=0;
  1186. len=(pt->attrib&0x3f);
  1187. bufoffset=pt->x+(WORD)pt->y/4*20;
  1188. if(pt->attrib&0x80)
  1189. {
  1190. attrib=((pt->attrib>>6)&0x03);
  1191. }
  1192. if((bufoffset+len)>=LCD_BUF_BYTES)
  1193. {
  1194. rt_printf("\r\n LCD BUF溢出!!!\r\n");
  1195. rt_printf("\r\n x=%d ,y=%d",pt->x,pt->y);
  1196. bufoffset=0;
  1197. }
  1198. for(cnt=0;cnt<len;cnt++)
  1199. {
  1200. if(g_tLcdComm.lcdattrib[bufoffset]!=attrib)break; // lcd 缓冲区数据不相等
  1201. if(pt->dat[cnt]>0x80)// 是汉字
  1202. {
  1203. if(g_tLcdComm.lcdbuf[bufoffset]!=pt->dat[cnt]||g_tLcdComm.lcdbuf[bufoffset+1]!=pt->dat[cnt+1])break; // lcd 缓冲区数据不相等
  1204. bufoffset++;
  1205. cnt++;
  1206. }
  1207. else
  1208. {
  1209. if(g_tLcdComm.lcdbuf[bufoffset]!=pt->dat[cnt])break; // lcd 缓冲区数据不相等
  1210. }
  1211. bufoffset++;
  1212. }
  1213. ptBuf->tail++;
  1214. ptBuf->tail&=LCD_MAX_CONTINUE_MASK;
  1215. if(cnt<len)
  1216. {
  1217. len-=cnt;
  1218. *pd++=(pt->x+cnt)*8;
  1219. *pd++=pt->y;
  1220. *pd++=len|(pt->attrib&0xc0);
  1221. for(i=0;i<len;i++)
  1222. {
  1223. *pd++=pt->dat[cnt];
  1224. g_tLcdComm.lcdbuf[bufoffset]=pt->dat[cnt];
  1225. g_tLcdComm.lcdattrib[bufoffset]=attrib;
  1226. bufoffset++;
  1227. cnt++;
  1228. }
  1229. num+=(3+len);
  1230. if(num>200)break;
  1231. }
  1232. }
  1233. if(num>0)
  1234. {
  1235. pd=srcbuf;
  1236. *pd++=HMI_CMD_WRITE_DATAS; //命令码
  1237. *pd++=num; //数目
  1238. (void)protocol_packet(srcbuf, (int)(num+6), MAIN_BOARD, HMI_BOARD, dstbuf);
  1239. //添加到缓存区
  1240. Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf);
  1241. }
  1242. return num;
  1243. }
  1244. /**************************************************************************
  1245. 函数名称:Send_dot_Datas
  1246. 函数版本:1.00
  1247. 作者:
  1248. 创建日期:2008.9.1
  1249. 函数功能说明:主程序发送菜单数据命令
  1250. 输入参数:
  1251. 输出参数:
  1252. 返回值:
  1253. 更新信息:
  1254. 更新日志1:
  1255. 日期:
  1256. 修改者:
  1257. 修改内容:
  1258. 修改原因:
  1259. ***************************************************************************/
  1260. static void _send_dot_datas(void)
  1261. {
  1262. int i;
  1263. DOT_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tDot;
  1264. BYTE srcbuf[UART_FRAME_LEN];
  1265. BYTE dstbuf[UART_FRAME_LEN];
  1266. BYTE *pd=srcbuf+2;
  1267. int num=0;;
  1268. while(ptBuf->head!=ptBuf->tail)
  1269. {
  1270. DOT_DATA_DEF *pt=&ptBuf->dot[ptBuf->tail];
  1271. ptBuf->tail++;
  1272. ptBuf->tail&=LCD_MAX_DOT_MASK;
  1273. *pd++=(BYTE)pt->x;
  1274. *pd++=(BYTE)(pt->x>>8);
  1275. *pd++=(BYTE)pt->y;
  1276. *pd++=(BYTE)(pt->y>>8);
  1277. *pd++=(BYTE)pt->w;
  1278. *pd++=(BYTE)(pt->w>>8);
  1279. *pd++=(BYTE)pt->ex;
  1280. *pd++=(BYTE)(pt->ex>>8);
  1281. *pd++=pt->mode;
  1282. *pd++=pt->num;
  1283. for(i=0;i<pt->num;i++)
  1284. {
  1285. *pd++=pt->dat[i];
  1286. }
  1287. num+=pt->num+10;
  1288. if((num+ptBuf->dot[ptBuf->tail].num)>230)
  1289. {
  1290. break;
  1291. }
  1292. }
  1293. if(num>0)
  1294. {
  1295. pd=srcbuf;
  1296. *pd++=HMI_CMD_WRITE_DOTS; //命令码
  1297. *pd++=num; //数目
  1298. (void)protocol_packet(srcbuf, (int)(num+6), MAIN_BOARD, HMI_BOARD, dstbuf);
  1299. //添加到缓存区
  1300. Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf);
  1301. }
  1302. }
  1303. /******************************************************************************
  1304. 函数名称: _hmi_changehzk
  1305. 函数版本: 01.01
  1306. 创建作者: xxxxxx
  1307. 创建日期: 2015-07-16
  1308. 函数说明: 根据液晶点阵类型,转换字库,原始字库为横向正序
  1309. 参数说明: type:液晶点阵类型
  1310. 返回值: 无
  1311. 修改记录:
  1312. */
  1313. int _hmi_changehzk(u8 type)
  1314. {
  1315. int i, j, k, n, ch, data_idx;
  1316. u8 hz[32], data[32];
  1317. if(hzk_table == NULL)
  1318. {
  1319. return 0;
  1320. }
  1321. switch(type)
  1322. {
  1323. case LCD_HN:
  1324. {
  1325. if (hzk_change_type == LCD_HN)
  1326. {
  1327. return 0;
  1328. }
  1329. hzk_change_type = LCD_HN;
  1330. }
  1331. break;
  1332. case LCD_VN:
  1333. {
  1334. if (hzk_change_type == LCD_VN)
  1335. {
  1336. return 0;
  1337. }
  1338. // 纵向取模,字节倒序
  1339. for (k=0; k<hzk_num; k++)
  1340. {
  1341. memcpy(hz, &hzk_table[k*32], 32);
  1342. //第一组8字节
  1343. for(i=7; i >=0 ; i=i-1)
  1344. {
  1345. ch = 0;
  1346. n = 0;
  1347. for(j=0; j<16; j=j+2)
  1348. {
  1349. ch |= ((hz[j] >> i) & 0x01) << n ;
  1350. n++;
  1351. }
  1352. data[data_idx++] = ch;
  1353. }
  1354. //第二组8字节
  1355. for(i=7; i >=0 ; i=i-1)
  1356. {
  1357. ch = 0;
  1358. n = 0;
  1359. for(j=1; j<16; j=j+2)
  1360. {
  1361. ch |= ((hz[j] >> i) & 0x01) << n ;
  1362. n++;
  1363. }
  1364. data[data_idx++] = ch;
  1365. }
  1366. //第三组8字节
  1367. for(i=7; i >=0 ; i=i-1)
  1368. {
  1369. ch = 0;
  1370. n = 0;
  1371. for(j=16; j<32; j=j+2)
  1372. {
  1373. ch |= ((hz[j] >> i) & 0x01) << n ;
  1374. n++;
  1375. }
  1376. data[data_idx++] = ch;
  1377. }
  1378. //第四组8字节
  1379. for(i=7; i >=0 ; i=i-1)
  1380. {
  1381. ch = 0;
  1382. n = 0;
  1383. for(j=17; j<32; j=j+2)
  1384. {
  1385. ch |= ((hz[j] >> i) & 0x01) << n ;
  1386. n++;
  1387. }
  1388. data[data_idx++] = ch;
  1389. }
  1390. memcpy(&hzk_table[k*32], data, 32);
  1391. data_idx = 0;
  1392. hzk_change_type = LCD_VN;
  1393. }
  1394. }
  1395. break;
  1396. }
  1397. return 0;
  1398. };
  1399. /*------------------------------ 测试函数 -------------------------------------
  1400. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  1401. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  1402. */
  1403. /*------------------------------ 文件结束 -------------------------------------
  1404. */