基于SOPC的通用字符VGA显示电路设计
扫描二维码
随时随地手机看文章
摘要:文章介绍了基于Nios II的SOPC的通用字符显示电路的设计,通过实时读取点阵字库信息并输出到VGA端口的方法实现。与传统方法相比,具有简单易行、便于二次开发的特点。以本方法进行了电子万年历的设计,并在基于EP2C35F672C6的DE2开发板上下载验证,结果表明本方法切实可行,适合于实时信息显示。
关键词:SOPC;视频图形阵列字符显示;Nios II
0 引言
VGA(视频图形阵列)是IBM于1987年提出的图形显示标准,虽然早己不是先进的显示标准,但由于其技术和工艺成熟、成本低廉等优势,目前仍有着广泛的应用。
现有基于FPGA的VGA显示系统需要显示字符,尤其是汉字时,通常方法是首先获取所用字符的字模,加入到HDL或C代码中调用。这种方法过程繁琐,且系统通用性不强。本设计以任意字符显示为特点,通过实时读取点阵字库实现字符显示,对存储空间利用率高,且灵活性好,便于进行二次开发。
1 系统硬件设计
本设计使用的是基于EP2C35F672C6的DE2开发板。在SOPC Builder中,将系统命名为system_0,目标板设定为预定义过的“DE2 Board”,加入NIOSII/s软核处理器,在时钟列表中添加50MHz的外部时钟,在组件列表中添加所需组件,如图1所示。
由于本设计的Nios II程序及所使用的字库需要存储在Flash中,因此添加了CFI Flash控制器以及三态Avalon总线,EPCS控制器用于存放FPGA配置信息。LED及JTAG UART组件用于调试中状态反馈,按钮和开关组件用于人机交互,SDRAM组件是本系统的运行内存,最后是VGA显示IP核。
本设计中所用VGA显示IP核符合Avalon总线规范,实现的功能为单色显示,即前景色和背景色各为预先指定的一种颜色,系统启动时核内显存读入一幅单色图像作为初始显示画面。编程时分别以VGA_Set_Pixel或VGA_Clr_Pixel指令将某一像素置为前景色或背景色。此IP核的结构原理如图2所示。
[!--empirenews.page--]
在整个工程的顶层文件中例化生成的system_0模块,用锁相环模块产生VGA所需的25MHz时钟信号并作为VGA模块iCLK 25信号输入。由于SOPC的CPU RESET信号只能锁定在实际器件中的按钮上作为输入,而DE2开发上的4个按钮在后面的实例都需要用到,因此在顶层文件中将CPU RESET信号直接置1。system_0的其他的输入输出信号根据开发板的相应资源进行定义和管脚锁定。
本设计的FPGA配置信息(sof文件)写入EPCS器件中,Nios II程序(elf文件)写入CFI Flash模块中,所用到的两个字库也写入CFI Flash中,字库起始偏移地址分别为0x80000和0x1000000。
2 字符显示原理
调用点阵字库实现任意数字和汉字的实时显示是本设计的基本方法。本设计中分别采用ASC16和HZK16字库作为ASCII码和汉字的点阵字库,这两个字库最早在UCDOS系统中被使用。
ASC16字库含有256个ASCII码字符,每个ASCII码字符均以16×8的点阵表示,点阵信息以行优先的方式存储,每个字符占用128个存储位(16字节),按照ASCII码的编码顺序存储,故一个字符的ASCII码值乘16就是它在ASC16字库中的偏移地址。
HZK16是依据GB2312编码存储的点阵字库,每个汉字用16×16的点阵表示,每个字符占用256个存储位(32字节),点阵信息同样以行优先方式存储。
HZK16字库内汉字按照内码顺序存储,每个汉字的内码由两个字节组成,高位字节为区号,低字节为位号,两字节的范围均为0xA1~0xFE共94个取值。将汉字的两个字节分别减去0xA1,即可得到该汉字的区号和位号。设某个汉字编码的两个字节分别为0xMM和0xNN,则该汉字在HZK16字库中对应的偏移地址为:
OFFEST=[94×(0xMM-0xA1)+(0xNN-0xA1)]×32
定位了ASCII码字符或汉字在点阵字库中的位置后,读出其所对应的16字节或32字节数据,用按位与运算和左移运算对每个字节的8个位逐一测试,将测试结果为1的位的对应像素填充为前景色,否则将像素填充为背景色,实现设定字符的显示。
3 SOPC中相关函数的定义
根据上述原理,以C语言编写适用于上述SOPC的字符显示函数,并以Nios II HAL系统库为基础。
3.1 ASCII码字符显示函数show_asc
此函数用于在VGA输出画面的(x,y)坐标处显示单个ASCII码字符asc,主要代码如下:
[!--empirenews.page--]
3.2 汉字字符显示函数show_hz
此函数用于在VGA输出画面的(x,y)坐标处显示单个汉字字符hz,主要代码如下:
3.3 字符串显示函数show_str
此函数用于在VGA输出画面的(x,y)坐标处显示长度为len的字符串str,内容可以由ASCII码及汉字混合组成,其主要代码如下:
4 实例应用
基于以上的软硬件设计,这里以万年历作为其应用的一个实例。以往基于FPGA的万年历设计多使用LCD或七段数码管作为输出,显示基本的数字和符号尚可,但若要加入问候语、纪念日等中文信息则难于实现,基于本电路设计的万年历则可以解决这一问题。
从功能上划分,此万年历设计可分为3个模块:
(1)时间日期生成模块。此模块包含年、月、日、星期、时、分、秒共7个变量的输出,每个变量都有各自的子模块,每个子模块都包含预置、计数、进位和显示的功能。其中星期的确定方法是计算当前日期与1990年1月1日(星期一)之间间隔的天数,将此天数对7取模并加1,即得到当前星期的数字。
系统启动时,首先将预置的初始时间日期传递给显示函数,由显示函数在预定位置分别显示7个数据,将数字加上0x30便得到其对应的ASCII码值,其中星期是将1~7的数字按星期一~星期日的汉字显示。
随后进入系统的主循环,以1秒钟为循环间隔,当前级数字到达最大值时向下一级数字进位。其中日进位时需判断月份类型(大月、小月或2月),当前月为2月时还需判断年份类型(是否闰年),以确定日的进位数值。其他数字的进位值是固定的,其中年的范围设定为1990~2099。[!--empirenews.page--]
(2)时间日期调整模块。除星期外,其他6个数字均可被调整。时间和日期的调整需要用到开发板上的4个按钮,对应功能分别为切换日期/时间(KEY0)、在年月日和时分秒间切换(KEY3)、数字减(KEY1)和数字加(KEY2)。用两个变量pos与dot表示当前的活动数字,其对应关系如表1所示。
在程序上,此模块由按下按钮所触发的中断服务函数实现。按钮按下时产生下降沿,读取边沿捕获寄存器的值即可判断哪一按钮被按下。按下KEY0或KEY3时,当前活动数字发生改变;按下KEY1或KEY2时,根据当前活动数字的不同进入6个分支,以各自数字的进位规则得到调整后的数字。
为了显示直观,在当前被调整的数字下方有实心原点作为指示标志,此圆点以ASCII码字符0x07表示。
(3)其他信息显示模块。此模块的作用是在未被时间日期信息占用的区域显示自定义的信息,如不同时刻的问候语、纪念日信息等。除了使用字符显示的方法外,还可对VGA输出的初始画面进行定制,如加入自定义的图案标志等。此外,由于所用到两个字库均为单一字体,其他特殊字体的文字也可以加入到此初始图像中进行显示。
5 测试与评价
将以上万年历实例设计下载到DE2开发板上运行,经测试,实现了所有预定功能,ASCII码字符及汉字字符显示正确,计时稳定、准确。运行时的一个画面如图3所示。
本电路采用基于Altera Nios II的SOPC平台,实现了通用字符VGA显示的功能,设计上灵活高效,系统资源利用度高。以本设计的通用平台为基础加以开发,可应用于诸多需要实时信息显示的场合。