/******************************************************************** 版权所有: 文件版本: V1.00 文件名称: LcdComm.c 生成日期: 2008年10月9日 作 者: 使用范围: 功 能:与面板通信处理程序 更新信息: 更新日志1: 修改者: 修改日期: 修改内容: 修改原因: *********************************************************************/ /*------------------------------- 头文件 -------------------------------------- */ #include "head.h" /*------------------------------- 宏定义 -------------------------------------- */ enum { HMI_RECV, HMI_SEND, }; //#define HMI_V2 /*------------------------------ 类型结构 ------------------------------------- */ /*------------------------------ 全局变量 ------------------------------------- */ UART_COMM g_tUartHMI; // 与面板通信的串口数据结构定义 struct hmi g_hmi[HMI_COMM_TYPE]; //面板帧结构定义 LCD_COMM_DEF g_tLcdComm; // 菜单处理数据与面板通信的结构定义 DWORD dHMIDiStatus = 0Xffffffff; u8 *hzk_table; static u8 hmi_update=0; int g_hmi_type; u8 lcd_dot_type; // 显示点阵显示类型 int hzk_num; // 汉字库中汉字个数 int hzk_change_type; // 当前切换的汉字库类型 uint32_t lcd_comm_delay=0; // 面板通讯超时 /*------------------------------ 函数声明 ------------------------------------- */ int hzk_read_file(void); //static void _reset_uartHMI_link(void); static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len); //len为参数长度 static void _hmi_call(void); static void _put_key(BYTE key); static void _hmi_comm_recv(BYTE *ps); static void _hmi_comm_send(void); void _hmi_uart_send(void); static void _send_inst(void); static int _send_continue_datas(void); static void _send_dot_datas(void); /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ void mainImage_Init(void) { u32 len; u8 *buf; struct file * pfile; loff_t pos; g_tLcdComm.tImage.pBuf=NULL; // 打开文件 pfile = rt_file_open("/app/data/mainImage.lcd",O_RDONLY ,0); if(IS_ERR(pfile)) { //rt_printf("\r\n打开 app/data/mainImage.lcd 失败\r\n"); return ; } // 得到文件长度 len = rt_file_getfile_size(pfile); if(len <= 0) { rt_file_close(pfile,0); return ; } // 分配内存 buf = rt_malloc(len); if((buf) == NULL) { rt_printf("\r\n分配mainImage.lcd内存失败\r\n"); rt_file_close(pfile,0); return ; } // 读出内容 pos = 0; if(rt_file_read(pfile,buf,len,&pos) != len) { rt_file_close(pfile,0); rt_free(buf); return ; } // 关闭文件 rt_file_close(pfile,0); g_tLcdComm.tImage.pBuf=buf; { // 获取主接线图的内容 WORD num; int i; D_UNIT_DEF tUnit; YC_UNIT_DEF tYc; MAIN_IMAGE_DEF *pm=&g_tLcdComm.tImage; BYTE *pd=buf;//主接线图的位置 pm->sYxNum=0; pm->sYcNum=0; pm->sImageX=pd[0]+((WORD)pd[1]<<8);pd+=2; pm->sImageY=pd[0]+((WORD)pd[1]<<8);pd+=2; pm->lnImageAddr=pd[0]+((DWORD)pd[1]<<8)+((DWORD)pd[2]<<16)+((DWORD)pd[3]<<24);pd+=4; num=pd[0]+((WORD)pd[1]<<8);pd+=2; for(i=0;itYxUnits[pm->sYxNum++]=tUnit; if(pm->sYxNum>=MAX_YX_UNITS)return ; } num=pd[0]+((WORD)pd[1]<<8);pd+=2; for(i=0;itYcUnits[pm->sYcNum++]=tYc; if(pm->sYcNum>=MAX_YC_UNITS)return ; } } m_LockIcon[0]=' '; m_LockIcon[1]='\0'; } int mainimage_exit(void) { if(g_tLcdComm.tImage.pBuf!=NULL) { rt_free(g_tLcdComm.tImage.pBuf); } return 0; } void lcd_DrawImage(short x,short y,BYTE *ps,unsigned char mode) //画图标,index为索引值,与按键的属性定义一致 { int h,w,head; short width,height,num; //点阵高 BYTE *pd; DOT_DATA_BUF_DEF *pdot=&g_tLcdComm.tDot; width=(ps[1]<<8)+ps[0]; height=(ps[3]<<8)+ps[2]; if(width>SCREENWIDTH||height>SCREENHEIGHT||(x<0||x>SCREENWIDTH)||(y<0||y>SCREENHEIGHT)) { rt_printf("\r\n image error !width=%d height=%d",width,height); return; } head=pdot->head; pd=pdot->dot[head].dat; num=0; ps+=4; pdot->dot[head].x=x; pdot->dot[head].y=y; pdot->dot[head].w=width; pdot->dot[head].mode=mode; pdot->dot[head].ex=x; for(h=0;h=230) { bool bline;// 换行 pdot->dot[head].num=num; pdot->head++; pdot->head&=LCD_MAX_DOT_MASK; if(pdot->head==pdot->tail) /*缓冲区满了*/ { pdot->tail++; pdot->tail&=LCD_MAX_DOT_MASK; } head=pdot->head; pd=pdot->dot[head].dat; bline=((w+1)>=width/8)?true:false; pdot->dot[head].x=x; pdot->dot[head].y=(bline)?(h+1):h; pdot->dot[head].w=width; pdot->dot[head].mode=mode; pdot->dot[head].ex=(bline)?x:(x+(w+1)*8); num=0; } } } if(num>0) { pdot->dot[head].num=num; pdot->head++; pdot->head&=LCD_MAX_DOT_MASK; if(pdot->head==pdot->tail) /*缓冲区满了*/ { pdot->tail++; pdot->tail&=LCD_MAX_DOT_MASK; } } } /************************************************************************** 函数名称:lcdcomm_init 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:初始化面板通信 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void lcdcomm_init(void) { memset((BYTE *)&g_tLcdComm,0,sizeof(g_tLcdComm)); memset((BYTE *)&g_tUartHMI,0,sizeof(g_tUartHMI)); led_init_hmi(); mainImage_Init(); //主接线图初始化 mmd_menu_cfg_init(); mmi_ScreenInit(); g_tLcdComm.tInit.flag=true; g_tLcdComm.bRecv=true; g_tLcdComm.bCall = true; lcd_comm_delay = ustimer_get_origin(); g_dw_led[0]=0; g_dw_led[1]=0; g_dw_ledsave[0]=0; // 灯状态 g_dw_ledsave[1]=0; // 灯状态 // 通过面板配置灯,获取灯的状态,使用脉宽==0 黄 ==1 绿 ==2 红 通道0 ==0x55(85) 六键 管理板,其他默认6键控制单元 { u32 slot; // 检查状态板是否配置 slot = equ_get_slot_by_type(BOARD_TYPE_LCD_16LED); if(slot ==0) { slot = equ_get_slot_by_type(BOARD_TYPE_LCD_24LED); if(slot==0) //jack.liu 2020 增加26个灯灯板定义 slot = equ_get_slot_by_type(BOARD_TYPE_LCD_26LED); } if(slot >0) { int i; u8 index; struct equ_config_do *ecd; ecd = g_equ_config_do; for(i=0;ido_num;i++) { if(ecd[i].slot== slot) { index=ecd[i].index; if(index>=LCD_MAX_LED)continue; g_tLcdComm.tInit.para[index]=(BYTE)ecd[i].time_pulse; } } #ifndef DISP_SET_67KEY if(g_tLcdComm.tInit.para[0]==200) { g_tScreen.lcd_type=LCD_TYPE_6KEY; } else if(g_tLcdComm.tInit.para[0]==10||g_tLcdComm.tInit.para[0]==11||g_tLcdComm.tInit.para[0]==12) // 9键定义 10 黄 11绿 12 红 { g_tLcdComm.tInit.para[0]-=10; g_tScreen.lcd_type=LCD_TYPE_160_KEY9; } #endif } } } /************************************************************************** 函数名称:HMI_Comm_App 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:主函数调用与面板通信任务,10ms调用1次,100ms左右调用一次刷屏命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void HMI_Comm_App(void) /*10毫秒调用一次*/ { #if 1 //正在升级面板程序 if(is_down_program()) { //有数据 if(g_tUartHMI.r_head != g_tUartHMI.r_tail) { //接收处理 down_program_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]); g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1); } else { //接收超时处理 down_program_recv_timeout(); } //发送处理 down_program_send(); return; } //内置GPRS拨号时有时候占用资源比较多,所以调整为15秒比较保险 if ((g_tUartHMI.r_head == g_tUartHMI.r_tail) && (ustimer_get_duration(lcd_comm_delay) > 5*USTIMER_SEC))// { static bool b_first=false; g_tLcdComm.tInit.flag=true; g_tLcdComm.b_init_OK = false; if(!soe_check(EV_HMIERR)) { //soe_record_ev(EV_HMIERR, 1, 0,0,0 ); } if(!b_first) { int i; b_first = true; for(i=0;itBuf[ptBuf->head]; BYTE cnt; pt->x=x; pt->y=y; if(g_tScreen.lcd_type==LCD_TYPE_160160) { if(x+len>20) { len=20-x; } } else if(g_tScreen.lcd_type==LCD_TYPE_128128||g_tScreen.lcd_type==LCD_TYPE_12864) { if(x+len>16) { len=16-x; } } else if(g_tScreen.lcd_type==LCD_TYPE_12232) { if(x+len>15) { len=15-x; } } pt->attrib=len; if(mode==1) { pt->attrib|=0x80; } else if(mode==2) { pt->attrib|=0x40; } for(cnt=0;cntdat[cnt]=*pdat; pdat++; } ptBuf->head++; ptBuf->head&=LCD_MAX_CONTINUE_MASK; if(ptBuf->head==ptBuf->tail) /*缓冲区满了*/ { ptBuf->tail++; ptBuf->tail&=LCD_MAX_CONTINUE_MASK; } } /************************************************************************** 函数名称:Add_Clear_Screen 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:清屏命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void Add_Clear_Screen(void) //mmidrv.c 调用 { LCD_COMM_DEF *pt=&g_tLcdComm; pt->bClrScreen=true; //清全屏 // 清发送缓冲区 pt->tContinue.head=pt->tContinue.tail=0; // 字从首字开始 pt->tContinue.index=0; memset(pt->lcdbuf,0,sizeof(pt->lcdbuf)); memset(pt->lcdattrib,0,sizeof(pt->lcdattrib)); } /************************************************************************** 函数名称:add_led_test 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:清屏命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void add_led_test(u8 test_no) { LCD_COMM_DEF *pt = &g_tLcdComm; switch (test_no) { case TEST_LED: pt->bTestLed = true; break; case TEST_LCD: pt->bTestLcd = true; break; } } void add_rmt_pair(u8 pair) { LCD_COMM_DEF *pt = &g_tLcdComm; switch (pair) { case TEST_LED: pt->bTeleMatch = true; break; case TEST_LCD: pt->bTeleClrMatch = true; break; } } /************************************************************************** 函数名称:Get_Key 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:获得按键函数 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ BYTE Get_Key(void) { LCD_KEY_DEF *pt=&g_tLcdComm.tKey; BYTE key; if(pt->head==pt->tail)return NO_KEY; key=pt->keybuf[pt->tail]; pt->tail++; pt->tail&=LCD_KEY_MASK; return key; } /****************************************************************************** 函数名称: HMI_Board_Recv 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-12-10 函数说明: 接收帧 参数说明: len:帧长度 para:接收帧内容 返回值: 无 修改记录: */ void HMI_Board_Recv(int len,BYTE *para) { UART_COMM *pt=&g_tUartHMI; memcpy(pt->r_buf[pt->r_head], para, len); pt->r_head = (pt->r_head + 1) & (UART_FRAME_MAXCNT - 1); } /****************************************************************************** 函数名称: hzk_read_file 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2013-08-08 函数说明: 读取汉字库 参数说明: 返回值: 0: 成功 其它: 失败 修改记录: */ int hzk_read_file(void) { u32 len; u16 crc16; struct file * pfile; loff_t pos; // 打开文件 pfile = rt_file_open("/app/data/hzk.bin",O_RDONLY ,0); if(IS_ERR(pfile)) { return -1; } // 得到文件长度 len = rt_file_getfile_size(pfile); if(len <= 0) { rt_file_close(pfile,0); return -11; } // 分配内存 hzk_table = rt_malloc(len); if(hzk_table == NULL) { rt_file_close(pfile,0); return -2; } // 读出内容 pos = 0; if(rt_file_read(pfile,hzk_table,len,&pos) != len) { rt_file_close(pfile,0); rt_free(hzk_table); return -3; } // 关闭文件 rt_file_close(pfile,0); // 检查CRC crc16 = CrcStr(hzk_table,len-2); if(crc16 != *(u16*)(hzk_table+len-2)) { rt_free(hzk_table); hzk_table = NULL; return -4; } hzk_num = (len-2) / 32; return 0; } /****************************************************************************** 函数名称: hzk_exit 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-04-16 函数说明: LED配置退出 参数说明: 无 返回值: 成功返回0. 修改记录: */ int hzk_exit(void) { if(hzk_table) { rt_free(hzk_table); } return 0; } /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ /************************************************************************** 函数名称:ResetUartHMILink 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:复归接收数据结构 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ #if 0 static void _reset_uartHMI_link(void) { g_tUartHMI.cTypeCounter=0; g_tUartHMI.cRecvCnt=0; } #endif /************************************************************************** 函数名称:Add_Inst_Frame 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:将发给面板的命令放入待发送指令缓冲区中 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _add_inst_frame(BYTE cmd,BYTE *para,BYTE len) //len为参数长度 { BYTE i; LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf; INST_DEF *pt=&ptBuf->tInst[ptBuf->head]; BYTE srcbuf[UART_FRAME_LEN]; BYTE *pd=srcbuf; int offset=0; // if(pRunSet->bHMI_OLD) // { // offset = 2; // *pd++=0;// 控制域 // *pd++=0xCC; // HMI地址为CC 状态板为55 // } *pd++=cmd; for(i=0;ipara); ptBuf->head++; ptBuf->head&=LCD_MAX_INST_MASK; if(ptBuf->head==ptBuf->tail) //缓冲区满了 { ptBuf->tail++; ptBuf->tail&=LCD_MAX_INST_MASK; } } void HMI_add_inst_frame(BYTE cmd,BYTE *para,BYTE len) { _add_inst_frame(cmd,para, len) ; } #if 0 // 转换汉字库点阵,stc3100是正序纵显 ,(标准字库是正序横显) static void _get_hz_dot(char *hzdot,const char *hzk) { int i; for(i=0;i<32;i++) // 160*160液晶为负序横显 { hzdot[i]=hzk[i]; } for(m=0;m<8;m++) { BYTE dat0=0; BYTE dat1=0; BYTE dat2=0; BYTE dat3=0; for(i=0;i<8;i++) { dat0|=(((hzk[i*2]>>m)&0x01)<>m)&0x01)<>m)&0x01)<>m)&0x01)<tInst[ptBuf->tail]; // Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para); ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK; } } #ifdef GD_TEST_2021 // 处理复归按键 void lcd_FG_key(BYTE cmd,BYTE key) { static DWORD dTKeyRst=0; static DWORD dTNoKey=0; static BYTE oldkey=NO_KEY; key&=KE_KEY_MASK; if(cmd==DRV_CMD_KEY&&key==HA_KEY_RST) { if(dTCounter-dTKeyRst>pRunSet->resReuseFuncFilterTime*T_1s) //复归按键满足防抖要求 { if(key != oldkey) { oldkey=key; // ResetHzLed(0); // SignalReset(0,true); if(pRunSet->resReuseFuncSelect == 1) //解锁 { g_run_stu.rmtjs=true; rt_printf("装置解锁\r\n"); } else if(pRunSet->resReuseFuncSelect == 2) //复位 { rt_printf("装置复位\r\n"); watchdog_reset_cpu(2); //装置复位 } } dTKeyRst=dTCounter; } dTNoKey=dTCounter; } else { if(dTCounter-dTNoKey>T_500ms) { dTKeyRst=dTCounter; oldkey=NO_KEY; } } } #endif /************************************************************************** 函数名称:Put_Key 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:将通信来的按键值放入缓冲中 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _put_key(BYTE lnkey) { LCD_KEY_DEF *pt=&g_tLcdComm.tKey; BYTE key=lnkey; if(g_tScreen.lcd_type==LCD_TYPE_6KEY) //老版本按键,ESC和ENTER键互换 { key&=KE_KEY_MASK; if(key==HA_KEY_ENTER) { key=HA_KEY_ESC; } if(key==HA_KEY_ESC) { key=HA_KEY_ENTER; } key|=(lnkey&(~KE_KEY_MASK)); } pt->keybuf[pt->head]=key; pt->head++; pt->head&=LCD_KEY_MASK; if(pt->head==pt->tail) //缓冲区满了 { pt->tail++; pt->tail&=LCD_KEY_MASK; } g_tLcdComm.tLight.light=LIGHT_ON; g_tLcdComm.tLight.flag=true; g_tScreen.lnLightTime=dTCounter; } /************************************************************************** 函数名称:HMI_CommRecv 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:与面板通信的接收处理函数 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _hmi_comm_recv(BYTE *ps) { BYTE *pd=ps; int offset=0; g_tLcdComm.b_init_OK=true; switch(pd[4+offset]&0x1f) { case DRV_CMD_POWERON: //上电报文 { if(pd[5+offset]==1)//上电初始化报文 { g_tLcdComm.tInit.flag=true; } else { g_tLcdComm.bClrScreen=true; } } break; case DRV_CMD_KEY: //按键报文 { _put_key(pd[5+offset]); _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0); } break; case DRV_CMD_TEMP: //面板遥信 { } break; case DRV_CMD_YX: //遥信 { } break; case DRV_CMD_SET: //定值 { } break; case DRV_CMD_YKQ: //遥控器 { g_rmt_op.key = pd[5]; _add_inst_frame(HMI_CMD_RESPOND,(void *)0,0); } break; case DRV_CMD_DOWN: //下载程序应答 break; default: break; } #ifdef GD_TEST_2021 // 处理复归按键 lcd_FG_key((pd[4+offset]&0x1f),pd[5+offset]); #endif } /************************************************************************** 函数名称:HMI_Comm_Send 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:启动面板通信的发送,包含重发机制。 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _hmi_comm_send(void) { static uint32_t us_call=0; static uint32_t us_lcdtest=0; static uint32_t us_ledtest=0; static uint32_t us_menu=0; static uint32_t us_send=0; LCD_COMM_DEF *pt=&g_tLcdComm; //pt->ReSend=0; if(pt->tInit.flag) //需初始化lcd { pt->tInstBuf.head=pt->tInstBuf.tail=0; Add_Clear_Screen(); pt->tLight.light=LIGHT_ON; _add_inst_frame(HMI_CMD_INIT_LCD,pt->tInit.para,LCD_MAX_LED); //初始化lcd _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏 _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //点亮背光 pt->tInit.flag=false; pt->tLight.flag=false; pt->bClrScreen=false; pt->bFreshLed=true; hmi_update = 0; } else { if(pt->bClrScreen) //需初始化lcd { _add_inst_frame(HMI_CMD_CLEAR_SCREEN,(void *)0,0); //清屏 //reset_update_flag(); pt->bClrScreen=false; } if(pt->tLight.flag) { _add_inst_frame(HMI_CMD_BLIGHT,&pt->tLight.light,1); //背光控制 pt->tLight.flag=false; } if(pt->bTestLed && (!pt->bLcdUpdate)) { _add_inst_frame(HMI_CMD_LEDRUN,(void *)0,0); //led测试 pt->bTestLed=false; pt->bLedUpdate = true; us_ledtest = ustimer_get_origin(); } if(pt->bLedUpdate) { if (ustimer_get_duration(us_ledtest) >= 4*USTIMER_SEC) { pt->bLedUpdate = false; } lcd_comm_delay = ustimer_get_origin(); } else { us_ledtest = ustimer_get_origin(); } if(pt->bTestLcd && (!pt->bLedUpdate)) { _add_inst_frame(HMI_CMD_TESTLCD,(void *)0,0); //lcd测试 pt->bTestLcd=false; pt->bLcdUpdate = true; us_lcdtest = ustimer_get_origin(); } if(pt->bLcdUpdate) { if (ustimer_get_duration(us_lcdtest) >= 3*USTIMER_SEC) { //reset_update_flag(); pt->bLcdUpdate = false; } lcd_comm_delay = ustimer_get_origin(); } else { us_lcdtest = ustimer_get_origin(); } if(pt->bTeleMatch) { pt->tTele.cmd = 0x10; _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对 pt->bTeleMatch=false; } if(pt->bTeleClrMatch) { pt->tTele.cmd = 0x20; _add_inst_frame(HMI_CMD_WIRELESS,&pt->tTele.cmd,1); //遥控器配对清除 pt->bTeleClrMatch=false; } // 1秒钟刷新一次LED if (pt->b_init_OK) { static uint32_t us0_led; u8 led_st[8]; int i; if(ustimer_delay_origin2(&us0_led,USTIMER_SEC/8)) { for(i=0;ibFreshLed) { led_st[0]=(BYTE)g_dw_led[0]; // 状态灯 led_st[1]=(BYTE)(g_dw_led[0]>>8); // 状态灯高位 led_st[2]=(BYTE)(g_dw_led[0]>>16); // 状态灯高位 led_st[3]=(BYTE)(g_dw_led[0]>>24); // 状态灯高位 led_st[4]=(BYTE)g_dw_led[1]; // 状态灯 led_st[5]=(BYTE)(g_dw_led[1]>>8); // 状态灯高位 led_st[6]=(BYTE)(g_dw_led[1]>>16); // 状态灯高位 led_st[7]=(BYTE)(g_dw_led[1]>>24); // 状态灯高位 _add_inst_frame(HMI_CMD_LED,led_st,8); //led点灯 g_dw_ledsave[0]=g_dw_led[0]; g_dw_ledsave[1]=g_dw_led[1]; pt->bFreshLed=false; } for(i=0;ibRecv) { if(ustimer_get_duration(us_send) >= USTIMER_SEC/2) // 发送接收超时0.5秒 { if(pt->ReSend++>3) //重发3次 { pt->tInit.flag=true; pt->bRecv=true; pt->ReSend=0; } else { us_send= ustimer_get_origin(); Sub_Uart_Frame(HMI_BOARD); pt->bRecv=false; } } return; } pt->ReSend=0; //组织报文 if(pt->tInstBuf.head!=pt->tInstBuf.tail) //组织报文 { _send_inst(); us_send= ustimer_get_origin(); pt->bRecv=false; } else if(pt->tDot.head!=pt->tDot.tail) //组织报文 { _send_dot_datas(); us_send= ustimer_get_origin(); pt->bRecv=false; } else if(pt->tContinue.head!=pt->tContinue.tail) //组织报文 { if(_send_continue_datas()>0) { us_send= ustimer_get_origin(); pt->bRecv=false; } } else if(ustimer_get_duration(us_call) >= 200*USTIMER_MS) //无 发送数据,召唤 { _hmi_call(); us_call = ustimer_get_origin(); us_send= ustimer_get_origin(); pt->bRecv=false; pt->bCall = true; } else if(ustimer_get_duration(us_menu) >= 100*USTIMER_MS) // 无数据发送后再刷新菜单 { mmi_Menu_Task(); us_menu= ustimer_get_origin(); } } /************************************************************************** 函数名称:Send_Inst 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:主程序发送命令数据 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _send_inst(void) { // CONTINUE_DATA_BUF_DEF *ptBuf_con=&g_tLcdComm.tContinue; LCD_INST_BUF_DEF *ptBuf=&g_tLcdComm.tInstBuf; INST_DEF *pt=&ptBuf->tInst[ptBuf->tail]; // Add_Uart_Frame(HMI_BOARD, (int)pt->para[1] + 6, pt->para); ptBuf->tail = (ptBuf->tail+1) & LCD_MAX_INST_MASK; } /************************************************************************** 函数名称:Send_Continue_Datas 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:主程序发送菜单数据命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static int _send_continue_datas(void) { int i,cnt; BYTE num=0; // BYTE checksum=0; //BYTE *pd=g_tUartHMI.arrSendBuf; CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue; BYTE srcbuf[UART_FRAME_LEN]; BYTE dstbuf[UART_FRAME_LEN]; BYTE *pd=srcbuf+2; //pd+=8+offset; //报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据 while(ptBuf->head!=ptBuf->tail) { int len; CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail]; WORD bufoffset; BYTE attrib=0; len=(pt->attrib&0x3f); bufoffset=pt->x+(WORD)pt->y/4*20; if(pt->attrib&0x80) { attrib=((pt->attrib>>6)&0x03); } if((bufoffset+len)>=LCD_BUF_BYTES) { rt_printf("\r\n LCD BUF溢出!!!\r\n"); rt_printf("\r\n x=%d ,y=%d",pt->x,pt->y); bufoffset=0; } for(cnt=0;cntdat[cnt]>0x80)// 是汉字 { if(g_tLcdComm.lcdbuf[bufoffset]!=pt->dat[cnt]||g_tLcdComm.lcdbuf[bufoffset+1]!=pt->dat[cnt+1])break; // lcd 缓冲区数据不相等 bufoffset++; cnt++; } else { if(g_tLcdComm.lcdbuf[bufoffset]!=pt->dat[cnt])break; // lcd 缓冲区数据不相等 } bufoffset++; } ptBuf->tail++; ptBuf->tail&=LCD_MAX_CONTINUE_MASK; if(cntx+cnt)*8; *pd++=pt->y; *pd++=len|(pt->attrib&0xc0); for(i=0;idat[cnt]; g_tLcdComm.lcdbuf[bufoffset]=pt->dat[cnt]; g_tLcdComm.lcdattrib[bufoffset]=attrib; bufoffset++; cnt++; } num+=(3+len); if(num>200)break; } } if(num>0) { pd=srcbuf; *pd++=HMI_CMD_WRITE_DATAS; //命令码 *pd++=num; //数目 (void)protocol_packet(srcbuf, (int)(num+6), MAIN_BOARD, HMI_BOARD, dstbuf); //添加到缓存区 Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf); } return num; } /************************************************************************** 函数名称:Send_dot_Datas 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:主程序发送菜单数据命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _send_dot_datas(void) { int i; DOT_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tDot; BYTE srcbuf[UART_FRAME_LEN]; BYTE dstbuf[UART_FRAME_LEN]; BYTE *pd=srcbuf+2; int num=0;; while(ptBuf->head!=ptBuf->tail) { DOT_DATA_DEF *pt=&ptBuf->dot[ptBuf->tail]; ptBuf->tail++; ptBuf->tail&=LCD_MAX_DOT_MASK; *pd++=(BYTE)pt->x; *pd++=(BYTE)(pt->x>>8); *pd++=(BYTE)pt->y; *pd++=(BYTE)(pt->y>>8); *pd++=(BYTE)pt->w; *pd++=(BYTE)(pt->w>>8); *pd++=(BYTE)pt->ex; *pd++=(BYTE)(pt->ex>>8); *pd++=pt->mode; *pd++=pt->num; for(i=0;inum;i++) { *pd++=pt->dat[i]; } num+=pt->num+10; if((num+ptBuf->dot[ptBuf->tail].num)>230) { break; } } if(num>0) { pd=srcbuf; *pd++=HMI_CMD_WRITE_DOTS; //命令码 *pd++=num; //数目 (void)protocol_packet(srcbuf, (int)(num+6), MAIN_BOARD, HMI_BOARD, dstbuf); //添加到缓存区 Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf); } } /****************************************************************************** 函数名称: _hmi_changehzk 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-07-16 函数说明: 根据液晶点阵类型,转换字库,原始字库为横向正序 参数说明: type:液晶点阵类型 返回值: 无 修改记录: */ int _hmi_changehzk(u8 type) { int i, j, k, n, ch, data_idx; u8 hz[32], data[32]; if(hzk_table == NULL) { return 0; } switch(type) { case LCD_HN: { if (hzk_change_type == LCD_HN) { return 0; } hzk_change_type = LCD_HN; } break; case LCD_VN: { if (hzk_change_type == LCD_VN) { return 0; } // 纵向取模,字节倒序 for (k=0; k=0 ; i=i-1) { ch = 0; n = 0; for(j=0; j<16; j=j+2) { ch |= ((hz[j] >> i) & 0x01) << n ; n++; } data[data_idx++] = ch; } //第二组8字节 for(i=7; i >=0 ; i=i-1) { ch = 0; n = 0; for(j=1; j<16; j=j+2) { ch |= ((hz[j] >> i) & 0x01) << n ; n++; } data[data_idx++] = ch; } //第三组8字节 for(i=7; i >=0 ; i=i-1) { ch = 0; n = 0; for(j=16; j<32; j=j+2) { ch |= ((hz[j] >> i) & 0x01) << n ; n++; } data[data_idx++] = ch; } //第四组8字节 for(i=7; i >=0 ; i=i-1) { ch = 0; n = 0; for(j=17; j<32; j=j+2) { ch |= ((hz[j] >> i) & 0x01) << n ; n++; } data[data_idx++] = ch; } memcpy(&hzk_table[k*32], data, 32); data_idx = 0; hzk_change_type = LCD_VN; } } break; } return 0; }; /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ /*------------------------------ 文件结束 ------------------------------------- */