LcdComm.c 31 KB

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