LcdComm.c 31 KB

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