图形液晶显示模块在嵌入式系统中的应用
图形点阵式液晶显示模块具有尺寸小、功耗低、寿命长、成本低、可显示各种图像与文本信息等优点,因此在各种仪器仪表、电子设备、移动通讯及家用电器中得到广泛的应用[1]。本文结合笔者在"便携式电力故障录波仪"项目中的实践经验,着重介绍如何把液晶显示模块应用做嵌入式DSP系统人机界面的问题,仅用四个按键相互配合,通过软件编程实现多层菜单和动态波形的显示。软件部分采用C语言编制,模块化设计,具有很强的可移植性,可以直接应用到其他的嵌入式系统中。
1. 模块的工作原理
1.1 基本功能
OCM4×8C液晶显示模块是128×64点阵的汉字图形型液晶显示模块,内置国标GB2312码简体中文字库(16×16点阵)、126个字符(8×16点阵)及32×128点阵显示RAM(GDRAM)。可与CPU直接接口,提供两种界面来连接微处理机:8位并行及串行两种连接方式。具有多种功能:光标显示、画面移位、睡眠模式、反白显示等。
1.2 引脚定义
OCM4x8c液晶显示模块的引脚说明如表1所示。该模块对液晶显示的控制和驱动都由模块内部的芯片及电路来完成,因此它与外部的连接只有数据线和控制线。主控CPU通过这些数据线和控制线来设置所需要的显示方式,其它功能均由模块自动完成。
1.3 指令系统
当ST7902在接受指令前,微处理器必须先确认ST7902内部处于非忙碌状态,即读取BF标志位时BF需为0,方可接受新的指令;如果在送入一个指令前并不检查BF标志,那么在前一个指令和这个指令中间必须延迟一段较长的时间,即等待前一个指令执行完成。
ST7902提供两套控制命令,基本指令和扩充指令,RE为基本指令与扩充指令集的选择控制位,当改变RE位后,往后的指令集将维持在最后的状态,除非再次改变RE,否则使用相同的指令集时,不需每次重设RE位。下面举例说明指令格式,如进入点设定(指令代码为0x02H):
CODE RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 功能:游标右移,DDRAM位址计数器(AC)加1 ST7920A提供硬体游标及闪烁控制电路,由地址计数器(address counter)的值来指定DDRAM中的游标或闪烁位置。 2. OCM4×8c和TMS320F2812并行接口设计 2.1 硬件电路设计[2,3] 利用F2812的PA口的PA0~PA10作为和ST7902并行连接的接口,其中PA0~PA7对应ST7902的八位数据线端口,PA8~PA10对应控制器的控制线端口,ST7902的复位端口 与F2812的复位端口XRS相连,背光灯的阳极LA接5V电源,负极LK接地,PSB管脚通过上拉电阻接高电平,使芯片工作在并行连接方式。利用F2812的PB口的低四位PB0~PB3作为与外部四个按健的接口,四个按键分别为返回,向上/下,确认。这四个按键相互配合可以实现多层菜单和数据、波形的动态显示。 包含DSP最小系统的时钟电路和复位电路,时钟电路由晶体和谐振电容组成,复位电路由RC充放电组成,为了便于调试,复位电路中增加了一个跳线器(J2),用于手动复位。笔者在设计过程中遇到一个问题,需要特别注意,液晶模块驱动器ST7902的工作电压为2.7~5.5V,但是OCM4×8c的工作电压为4.5~5.5V,所以两者配合的使用时电压需在4.5~5.5V之间,不然液晶显示将无法正常工作,所以不能为了方便用DSP芯片电源3.3V。 2.2软件程序设计[3-5] 下面给出与上述硬件电路配套的C语言显示子程序。包括初始化子程序、主程序、延时子程序、汉字、字符显示子程序、动态显示数据子程序、清屏子程序、按键扫描子程序等,多层菜单功能利用事件触发方式实现。可根据显示需要在主程序的相应位置调用,即可实现相应的显示功能,其主程序流程图如图所示。 初始化子程序: void init_lcd (void) { wr_lcd (COMM,0x30); /* 30---基本指令动作 */ delay(2000); wr_lcd (COMM,0x30); /* 30---基本指令动作 */ delay(1000); wr_lcd (COMM,0x0c); /* 开显示,关游标 */ delay(2000); wr_lcd (COMM,0x01); /* 清屏,地址指针指向00H */ delay(20000); wr_lcd (COMM,0x06); /* 光标的移动方向 */ } /*** 主程序 ***/ void main(void) { InitSysCtrl(); // Disable and clear all CPU interrupts: DINT; IER = 0x0000; IFR = 0x0000; // Initialize Pie Control Registers To Default State: InitPieCtrl(); // Initialize the PIE Vector Table To a Known State: InitPieVectTable(); InitGpio(); init_lcd(); for(o=0;o<10;o++) {welcome();} show_items(tab0,4,0); while(1) { display(); while(!key_scan()); key_server();} } 写数据或指令子程序: /* 写指令或数据 * data_comm : 1写数据,0写指令,data : 数据或指令内容 */ void wr_lcd (Uchar data_comm,Uchar data){ delay(50); GpioDataRegs.GPADAT.bit.GPIOA9=data_comm; /* 置rs=data_comm */ GpioDataRegs.GPADAT.bit.GPIOA8=0; /* 置rw=0 */ GpioDataRegs.GPADAT.all&=0xff00; /* 输入数据 */ data&=0x00ff; GpioDataRegs.GPADAT.all|=data; GpioDataRegs.GPADAT.bit.GPIOA10=1 ; /* e=1 */ delay(50); GpioDataRegs.GPADAT.bit.GPIOA10=0 ; /* e=0 */ } 清屏子程序: void clear(void){ wr_lcd(COMM,0x30); wr_lcd(COMM,0x01); } 汉字、字符显示子程序: void chn_disp (Uchar *chn,Uint16 rows,Uint16 cur_row) { int16 row_num,offset,i,j; clear(); row_num = (rows > 4) ? 4 : ((rows < 1) ? 1 : rows); /* 要显示的行数 */ if (cur_row >= rows) cur_row = rows-1; offset = (cur_row > 3) ? (cur_row-3)*16 : 0; /* 第一行数据的数组下标 */ wr_lcd (COMM,0x30); for(i=0; i<row_num;i++) { wr_lcd(COMM,addr[i]); for(j=0;j<16;j++) wr_lcd(DATA,chn[offset+j]); offset += 16; } wr_lcd (COMM,0x0c); delay(50000); } /* 动态显示数据 * tab :要显示的数据数组 */ void dyna_disp_value(Uchar *tab,float *tf,float factor){ while(1){ clear_tab(tab,16,64); /* 清除数值,但保留屏幕第一行的提示信息 */ float_to_char(tab,16,(*tf)*factor); /* 将动态数值存入数组 */ chn_disp(tab,4,0); delay(5000); if(key_scan() && (GpioDataRegs.GPBDAT.all|0xFFF0)==0xFFF8) break; /* 监听返回键 */ } disp_menu(); /* 显示主菜单 */ } 延时子程序: void delay (Uint16 us) { Uint16 i,j; for(i=0;i<us;i++) for(j=0;j<50;j++); } 按键扫描子程序: int key_scan(void) { int16 i; if((GpioDataRegs.GPBDAT.all|0xFFF0) == 0xFFF0) return 0 ; /* 没有按键被按下 */ for(i=2000; i>0; --i); /* 延时消除按键抖动 */ return (((GpioDataRegs.GPBDAT.all|0xFFF0) == 0xFFF0) ? 0 : 1); } |
- 全面解读 嵌入式DSP上的视频编解码(08-19)
- 基于ADSP-TS201S的图像采集处理系统(08-12)
- 基于Blackfin533的H.264编码(08-18)
- 基于DSP和FPGA的电视观瞄系统设计(09-02)
- TI手提多媒体设备解决方案(09-23)
- DSP片外高速海置SDRAM存储系统设计(10-02)