热线电话:86-755-88864001 88864003

基于AVR的VGA显示和激光打印系统

发布时间: 2011-03-17 03:37 作者: 浏览次数: 91 字号:

来源:微计算机信息  作者:时永乐 王培勇


控制激光打印机实现了屏幕信息的打印输出。本设计克服了单片机系统显示和打印功能薄弱的缺点,为扩大其应用范围奠定了基础,同时也为其他嵌入式系统的信息输出提供了一种解决方案。


关键词:VGA控制器;PCL命令语言;激光打印;CPLD



随着集成电路制造技术的不断发展,MCU、ARM、DSP等微控制器、微处理器的性能急剧提高,但是输出功能,尤其是显示和打印功能仍然比较薄弱,与PC机相比有较大的差距。输出功能薄弱的缺点,限制了其应用范围的扩大。ATmega128是美国Atmel公司生产RISC 结构的高性能MCU芯片,含有ADC、I2C、SPI、PWM等多种资源 [1]。本论文以ATMEGA128单片机为例,结合CPLD和高速SRAM,介绍在VGA显示器上显示字符、图形信息和控制激光打印****印输出屏幕信息的方法。本设计克服了单片机系统信息输出功能薄弱的缺点, 为单片机和其他嵌入式系统的信息输出提供了一个解决方案,使得其应用范围更加广阔。系统结构如图1所示。


1  VGA显示控制器的实现


PC机在VGA的显示器(通常包括CRT和液晶显示器)上的信息显示是通过显卡完成的。单片机在VGA显示器上显示信息同样需要类似的模块来辅助,因此我们设计了和显卡功能相似的VGA显示控制器来辅助ATMEGA128单片机在VGA显示器上显示信息。下面介绍640×480分辨率、59.9HZ刷新率的通用VGA显示控制器的设计方法,并说明微控制器、微处理器如何在VGA接口的显示器上显示信息。


1.1 VGA时序产生模块的设计


要实现VGA显示控制器的功能,首先需要了解VGA信号的参数和时序。图2所示为640×480分辨率、59.9HZ刷新率的VGA时序图[2]。根据VGA时序图,本论文研究并实现了VGA显示控制器,所用硬件为Altera公司的EPM7128 CPLD和ISSI公司的高速SRAM。EPM7128的作用是通过编程产生VGA显示所需的时序信号,并协助微控制器实现对显存的读写操作。高速SRAM的作用是存储需要显示的数据信息,其读写周期为8ns,满足显示器刷新时对显存进行快速读写的时间要求。设计中用一个bit代表一个象素,640×480分辨率需要37.5K字节的显存。象素时钟频率的选择与VGA监视器的刷新频率和分辨率相关,59.9HZ刷新率时,象素时钟频率为25.175MHZ,其计算公式为:时钟频率=(行象素数+行消隐点数)×(一场行数+消隐行数)×刷新率。


根据VGA信号的要求,用VHDL语言对EPM7128芯片编程实现VGA时序产生模块。VGA时序产生模块包括:每行的象素数目计数器h_cnt、每场的行数目计数器v_cnt、行同步信号hs产生模块、场同步信号vs产生模块、消隐信号blank产生模块和并行输入串行输出模块等。其中, h_cnt的最大计数值是799, v_cnt的最计数值是是524。行同步信号产生模块根据h_cnt的计数值来产生行同步信号hs;场同步信号产生模块根据v_cnt的计数值来产生场同步信号vs。消隐信号产生模块根据h_cnt的计数值在行同步期间、行消隐前肩和行消隐后肩,把消隐信号blank置为低电平;根据v_cnt的计数值在每一场的场同步期间、场消隐前肩和场消隐后肩,把消隐信号blank置为低电平;其余时间消隐信号blank为高电平,表示此时为有效显示期。并行输入串行输出模块在有效显示期间从sram显存中并行读入数据,串行输出的显示器的红、绿、蓝信号线上。对该程序编译成功后用MaxplussII软件进行波形仿真,以验证设计的合理与否。最后设计完成的时序波形仿真如图3所示。




图 3 VGA显示控制器时序仿真图


从仿真波形图种可以看到每一显示行的时间为800个象素时钟周期,每场包括525行。行同步脉冲的宽度为96个象素时钟周期,场同步脉冲的宽度为2行。在行同步信号hs的行同步期间及其前肩和后肩,消隐信号blank为低电平,表示消隐期。在场同步信号vs的场同步期间及其前肩和后肩,消隐信号blank同样为低电平,表示消隐期。仿真结果符合VGA标准时序,项目实际应用也证明了此结果的正确性。


1.2 VGA显示底层函数的编写


要在屏幕上显示信息,除VGA显示控制器之外,还需要并在ATMEGA128单片机上设计底层绘图函数并建立字符库。通常编写画线、画圆函数时,确定一个点是否在直线或圆上,需要乘、除法和开方运算,而画线、画圆函数调用最为频繁,因此计算量将大到难以接受的程度,极大降低系统的性能。为了克服上述缺点,在编写底层绘图函数时采用了图形学上的Bresenham






void circle(unsigned int x0,unsigned int y0,unsigned int r,unsigned char color)


{    


register int x,y,deltax,deltay,d;


x=0;y=r;deltax=3;deltay=2-r-r;d=1-r;


       while(x<=y)


       {     drawpixel(x0+x,y0+y,color);


              drawpixel(x0-x,y0+y,color);               


              drawpixel(x0-x,y0-y,color);


              drawpixel(x0+x,y0-y,color);                     


              drawpixel(x0+y,y0+x,color);              


              drawpixel(x0-y,y0+x,color);


              drawpixel(x0-y,y0-x,color);


              drawpixel(x0+y,y0-x,color);


              if(d<0){


                     d+=deltax;      deltax+=2;


                     x++;


              }


              else  {


                     d+=(deltax+deltay);


                     deltax+=2;deltay+=2;


                     x++;y–;


              }


       }         


}

发表评论

您的昵称 *

您的邮箱 * (绝对保密)

您的网站