LcdComm.c 31 KB

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