/******************************************************************** 版权所有: 文件版本: 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; u8 lcd_dot_type; // 显示点阵显示类型 int hzk_num; // 汉字库中汉字个数 int hzk_change_type; // 当前切换的汉字库类型 unsigned long lcd_comm_delay=0; // 面板通讯超时 int g_hzk_table_flag = 0; //0表示使用主板的汉字库,1表示使用面板的汉字库 char m_TzCount[12]; char m_HzCount[12]; /*------------------------------ 函数声明 ------------------------------------- */ 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 void _send_continue_datas(void); static void _get_hz_dot(char *hzdot,const char *hzk); static int _hmi_changehzk(u8 type); /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ /************************************************************************** 函数名称:InitLcdComm 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:初始化面板通信 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void InitLcdComm(void) { int ret; memset((BYTE *)&g_tLcdComm,0,sizeof(g_tLcdComm)); memset((BYTE *)&g_tUartHMI,0,sizeof(g_tUartHMI)); // mmd_menu_cfg_init(); g_tLcdComm.tInit.flag=true; g_tLcdComm.bRecv=true; if(g_hzk_table_flag==0) { ret = hzk_read_file(); if (ret != 0) { rt_err_set(ERR_CODE_HZK,0); rt_file_del("/app/data/hzk.bin"); rt_printf("汉字库文件错误: %d\r\n", ret); } else { hzk_change_type = LCD_HP; } } g_tLcdComm.dWaitT=dTCounter; g_tLcdComm.bVirLcd=false; g_tLcdComm.bCall = true; lcd_comm_delay = ustimer_get_origin(); } /************************************************************************** 函数名称:HMI_Comm_App 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:主函数调用与面板通信任务,10ms调用1次,100ms左右调用一次刷屏命令 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void HMI_Comm_App(void) /*10毫秒调用一次*/ { // 字库初始化失败且使用本地字库模式时不进入处理 if(hzk_table == NULL && g_hzk_table_flag ==0) return; #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) > 15*USTIMER_SEC))//3s { 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 ); } lcd_comm_delay = ustimer_get_origin(); } if(g_tUartHMI.r_head != g_tUartHMI.r_tail) { _hmi_comm_recv(g_tUartHMI.r_buf[g_tUartHMI.r_tail]); g_tUartHMI.r_tail = (g_tUartHMI.r_tail + 1) & (UART_FRAME_MAXCNT - 1); lcd_comm_delay = ustimer_get_origin(); } _hmi_comm_send(); #endif } /************************************************************************** 函数名称:Add_Continue_Data 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:菜单驱动调用函数,将要显示的数据存入缓冲区中 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void Add_Continue_Data(BYTE x,BYTE y,BYTE *pdat,BYTE len,BYTE mode) { CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue; CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->head]; BYTE cnt; BYTE attrib; pt->x=x; pt->y=y; pt->attrib=len; attrib=0; if(mode==1) { pt->attrib|=0x80; attrib=1; //显示属性 } 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; } /************************************************************************** 函数名称: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; } } static void _get_hz_dot(char *hzdot,const char *hzk) { int i; for(i=0;i<32;i++) // 160*160液晶为负序横显 { hzdot[i]=hzk[i]; } #if 0 // 转换汉字库点阵,stc3100是正序纵显 ,(标准字库是正序横显) 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; } } /************************************************************************** 函数名称:Put_Key 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:将通信来的按键值放入缓冲中 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _put_key(BYTE key) { LCD_KEY_DEF *pt=&g_tLcdComm.tKey; pt->keybuf[pt->head]=key; pt->head++; pt->head&=LCD_KEY_MASK; if(pt->head==pt->tail) //缓冲区满了 { pt->tail++; pt->tail&=LCD_KEY_MASK; } #if 0 switch(key&~KE_KEY_LONG_BIT) { case 1:rt_printf("确认键");break; case 2:rt_printf("ESC键");break; case 3:rt_printf("UP键");break; case 4:rt_printf("DOWN键");break; case 5:rt_printf("LEFT键");break; case 6:rt_printf("RIGHT键");break; case 7:rt_printf("ADD键");break; case 8:rt_printf("SUB键");break; case 9:rt_printf("控制面板复归信号产生。\r\n");break; } #endif } /************************************************************************** 函数名称:HMI_CommRecv 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:与面板通信的接收处理函数 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _hmi_comm_recv(BYTE *ps) { BYTE *pd=ps; int offset=0; switch(pd[4+offset]&0x1f) { case DRV_CMD_POWERON: //上电报文 { int ret; if(pd[5+offset]==1)//上电初始化报文 { g_tLcdComm.tInit.flag=true; query_page_other_proc(); } else { g_tLcdComm.b_init_OK=true; rt_printf("g_tLcdComm.b_init_OK\r\n"); } // 获取面板类型,并初使化菜单和LED g_hmi_type = pd[7+offset]; // 初始化之前先释放可能存在的内存,因为面板可能会重新初使化 menudesc_exit(); led_exit(); ret = menudesc_init(g_hmi_type); if (ret == 0) { hmi_update = 1; } else { rt_printf("菜单初始化结果=%d\r\n", ret); } if(g_hzk_table_flag==0) { // 获取液晶点阵类型,并转换字库 lcd_dot_type = pd[8+offset]; _hmi_changehzk(lcd_dot_type); } } 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; } } /************************************************************************** 函数名称:HMI_Comm_Send 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:启动面板通信的发送,包含重发机制。 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _hmi_comm_send(void) { static unsigned long us0=0; static unsigned long us_lcdtest=0; static unsigned long us_ledtest=0; LCD_COMM_DEF *pt=&g_tLcdComm; if (pt->bCall) { us0 = ustimer_get_origin(); pt->bCall = FALSE; } // 确保菜单初始化后才进行菜单操作, // 确保接收完成才进行下一帧,以避免显示内容乱 if (hmi_update) { key_hmi_app(); menu_disp(); } pt->ReSend=0; pt->dWaitT=dTCounter; if(pt->tInit.flag&&(!pt->bVirLcd)) //需初始化lcd { pt->tContinue.head=pt->tContinue.tail=0; pt->tInstBuf.head=pt->tInstBuf.tail=0; pt->tLight.light=LIGHT_ON; _add_inst_frame(HMI_CMD_INIT_LCD,pt->tInit.para,10); //初始化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; 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_LCDRUN,(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 unsigned long us0; u8 led_st[4]; if(ustimer_delay_origin2(&us0,USTIMER_SEC)) { led_to_hmi(); // zhl TODO g_dw_led有两个,暂时先用一个测试 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); // 状态灯高位 _add_inst_frame(HMI_CMD_LED,led_st,4); //led点灯 } } } //组织报文 if(pt->tInstBuf.head!=pt->tInstBuf.tail) //组织报文 { _send_inst(); } else if(pt->tContinue.head!=pt->tContinue.tail) //组织报文 { _send_continue_datas(); pt->bClrflag = false; } else if(pt->b_init_OK && (ustimer_get_duration(us0) >= 1*USTIMER_SEC)) //无 发送数据,召唤 { _hmi_call(); pt->bCall = true; } } /************************************************************************** 函数名称: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: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ #define HMI_V2 #ifdef HMI_V2 static void _send_continue_datas_0(void) { int i; BYTE num=0,cnt=0,bytenum=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+=10; /*报文长度+报文头+命令码+数据区个数,共8个字节,从第7个字节开始数据*/ while(ptBuf->head!=ptBuf->tail) { BYTE len; CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail]; len=(pt->attrib&0x3f); for(cnt=ptBuf->index;cntdat[cnt]; if(pdat[0]>0xa0&&pdat[1]>0xa0) //是汉字 { BYTE FieldCode,BitCode; BYTE hzdot[32]; DWORD addr; FieldCode=pdat[0]-0xa1; //wjw 区码 BitCode=pdat[1]-0xa1; //wjw 位码 if(FieldCode>=15) //15~19 ASCII码的位置 { FieldCode-=4; } // 32:1个字所占的字节 // 区码:1个区有94个汉字,位码:即1个区中汉字的实际位置 addr=((DWORD)FieldCode*94+BitCode)*32;//wjw 计算出全字库的点阵地址 _get_hz_dot(hzdot,&hzk_table[addr]); *pd++=pt->x+cnt*8; *pd++=pt->y; *pd++=(pt->attrib&0x80)+32; for(i=0;i<32;i++) { *pd++=hzdot[i]; } num+=(32+3); cnt+=2; ptBuf->index+=2; } else { *pd++=pt->x+cnt*8; *pd++=pt->y; *pd++=(pt->attrib&0x80)+0x41; *pd++=pdat[0]; num+=(1+3); cnt+=1; ptBuf->index+=1; } bytenum++; if(num>200)break; } if(cnt>=len) { ptBuf->tail++; ptBuf->tail&=LCD_MAX_CONTINUE_MASK; ptBuf->index=0; } if(num>200)break; } pd=srcbuf; *pd++=HMI_CMD_WRITE_DATAS; //命令码 *pd++=bytenum; //数目 (void)protocol_packet(srcbuf, (int)num+2, MAIN_BOARD, HMI_BOARD, dstbuf); //添加到缓存区 Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf); } static void _send_continue_datas_1(void) { int i; BYTE num=0; // BYTE checksum=0; //BYTE *pd=g_tUartHMI.arrSendBuf; CONTINUE_DATA_BUF_DEF *ptBuf=&g_tLcdComm.tContinue; int offset=0;//offend=0; 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]; len=(pt->attrib&0x3f); *pd++=pt->x; *pd++=pt->y; *pd++=pt->attrib; printf("ptBuf->tail=%d, x=%02x, y=%02x, attrib=%02x\n", ptBuf->tail, pt->x, pt->y, pt->attrib); // zhl TODO 打印 for(i=0;idat[i]; } num+=(3+len); ptBuf->tail++; ptBuf->tail&=LCD_MAX_CONTINUE_MASK; if(num>200)break; } #if 0 pd=g_tUartHMI.arrSendBuf; *pd++=0x68; *pd++=num+6+offset; *pd++=num+6+offset; *pd++=0x68; *pd++=HMI_CMD_WRITE_DATAS; //命令码 *pd++=num; //数目 //计算校验和 pd=&g_tUartHMI.arrSendBuf[4]; for(i=0;ihead!=ptBuf->tail) { BYTE len; CONTINUE_DATA_DEF *pt=&ptBuf->tBuf[ptBuf->tail]; len=(pt->attrib&0x3f); for(cnt=ptBuf->index;cntdat[cnt]; if(pdat[0]>0xa0&&pdat[1]>0xa0) //是汉字 { BYTE FieldCode,BitCode; BYTE hzdot[32]; DWORD addr; FieldCode=pdat[0]-0xa1; //wjw 区码 BitCode=pdat[1]-0xa1; //wjw 位码 if(FieldCode>=15) //15~19 ASCII码的位置 { FieldCode-=4; } // 32:1个字所占的字节 // 区码:1个区有94个汉字,位码:即1个区中汉字的实际位置 addr=((DWORD)FieldCode*94+BitCode)*32;//wjw 计算出全字库的点阵地址 _get_hz_dot(hzdot,&hzk_table[addr]); *pd++=pt->x+cnt*8; *pd++=pt->y; *pd++=(pt->attrib&0x80)+32; for(i=0;i<32;i++) { *pd++=hzdot[i]; } num+=(32+3); cnt+=2; ptBuf->index+=2; } else { *pd++=pt->x+cnt*8; *pd++=pt->y; *pd++=(pt->attrib&0x80)+0x41; *pd++=pdat[0]; num+=(1+3); cnt+=1; ptBuf->index+=1; } bytenum++; if(num>200)break; } if(cnt>=len) { ptBuf->tail++; ptBuf->tail&=LCD_MAX_CONTINUE_MASK; ptBuf->index=0; } if(num>200)break; } pd=srcbuf; *pd++=HMI_CMD_WRITE_DATAS; //命令码 *pd++=bytenum; //数目 (void)protocol_packet(srcbuf, (int)num+2, MAIN_BOARD, HMI_BOARD, dstbuf); //添加到缓存区 Add_Uart_Frame(HMI_BOARD, (int)dstbuf[1] + 6, dstbuf); } #endif /****************************************************************************** 函数名称: _hmi_changehzk 函数版本: 01.01 创建作者: 钟务贵 创建日期: 2015-07-16 函数说明: 根据液晶点阵类型,转换字库,原始字库为横向正序 参数说明: type:液晶点阵类型 返回值: 无 修改记录: */ static 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; }; /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ /*------------------------------ 文件结束 ------------------------------------- */