VGA显示器字符显示

实验目标

在640 * 480 @60模式下显示汉字,与彩条显示是一样的,点阵大小是64 * 64,字符大小56 * 56

字符取模

平时我们在广告屏、LED显示屏上看到的字符本质都是点阵,点阵看作是纸,点阵中的字符就是笔顺,将点阵和字符分别设置两种颜色,这样的色差就能实现字符的显示,点阵的大小决定着显示区域的大小,也决定着字符的大小和清晰度,一般使用01组合描述点阵

点阵中的每一个数据都表示一个像素点,如果用单比特,那么点阵就不包含色彩信息,只是区别背景和字符信息

取模用PCtoLCD进行,默认生成的字模是分开的
在这里插入图片描述
设置一下,就能将四个字符生成一个整体的字模:

  1. 先BMP格式保存,重新打开bmp文件,可以看到四个字符合成了整体的字符
    在这里插入图片描述

  2. 用PCtoLCD中打开bmp文件,就看到四个独立的字符合成了整体
    在这里插入图片描述

  3. 打开设置,对字模的格式重新设置,然后确定,重新生成字模
    在这里插入图片描述

  4. txt格式保存字模,此时的字模点阵大小是256*64,
    在这里插入图片描述

模块设计

在这里插入图片描述

  • clk_gen
    调用PPL锁相环,25MHz时钟生成模块
  • vga_pic
    图像生成模块,产生要显示的图像数据
  • vga_ctrl
    vga控制模块,在25MHz工作时钟下,产生横纵坐标信号(pix_x, pix_y),(0, 0)~(639, 479),传送给vga_pic模块,并且生成行场同步信号hsync和sync,再将vga_pic模块传过来的像素点信息pix_data输出到rgb端口

如何将字符显示在一帧图像的中间位置,可以类比坐标信号(pix_x, pix_y)的生成方式,当pix_x扫描到A部分,pix_y扫描到B部分,那么就可以给字符坐标信号(char_x, char_y)进行赋值(0 ,0)~(255, 63),然后根据字符坐标给对应的字符点阵进行像素数据赋值
在这里插入图片描述
在这里插入图片描述

vga_pic模块以及测试

这个相对于前面的彩条显示,多了一些条件,拿到(pix_x, pix_y)后,先找到256*64大小的点阵显示区域,然后在的点阵范围内,根据字模数据,给对应的像素点赋值像素数据

module vga_pic(
	input	wire			vga_clk,
	input	wire			sys_rst_n,
	input	wire	[ 9: 0]	pix_x,
	input	wire	[ 9: 0]	pix_y,
	
	output	reg		[15: 0]	pix_data
);
	
	// 定义(char_x, char_y)相对与(pix_x, pix_y)的开始坐标
	parameter	CHAR_B_H	=	10'd192,
				CHAR_B_V	=	10'd208;
	
	parameter	CHAR_W		=	10'd256,
				CHAR_H		=	10'd64;
	
	parameter	BLACK		=	16'h0000,
				GOLDEN		=	16'hFEC0;
	
	wire	[ 9: 0]	char_x;
	wire	[ 9: 0]	char_y;
	
	assign	char_x	=	(((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
						&& ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
						? (pix_x - CHAR_B_H) : 10'h3ff;

	assign	char_y	=	(((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
						&& ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
						? (pix_y - CHAR_B_V) : 10'h3ff;

	// 引入字模数据                                
	reg		[255:0]	char	[63:0];		// 256 * 64
	
	always @ (posedge vga_clk)
		begin
			char[ 0]	<=	256'h0000000000000000000000000000000000000000000000000000000000000000;
			char[ 1]	<=	256'h0000000000000000000000000000000000000000000000000000000000000000;
			... ...
			char[61]	<=	256'h0000000000000000000000000000000000000000000000000000000000000000;
			char[62]	<=	256'h0000000000000000000000000000000000000000000000000000000000000000;
			char[63]	<=	256'h0000000000000000000000000000000000000000000000000000000000000000;
		end


/*
	判断条件不能直接使用char_x和char_y,因为pix_data是一个时序逻辑,到时候pix_data会滞后插入坐标一个节拍
	
	对pix_x的范围前推一个,代表提前一个节拍
	如果对pix_y的范围推前一个,代表超前一行,不可取
	
*/
	always @ (posedge vga_clk or negedge sys_rst_n)
		if (sys_rst_n == 1'b0)
			pix_data	<=	BLACK;
		else	if ((((pix_x >=	(CHAR_B_H - 1'b1)) 
					&& (pix_x < (CHAR_B_H + CHAR_W - 1'b1)))
					&& ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
					&& (char[char_y][10'd255 - char_x] == 1'b1))
//					&& (char[char_x][char_y] == 1'b1))
			pix_data	<=	GOLDEN;
		else
			pix_data	<=BLACK;

endmodule

在这里插入图片描述

下板总结

第一次下板:妙啊,是个倒像,能用手机前置看
在这里插入图片描述

显示图像是倒着的,从每一行的最右边开始显示,而且字的下面几行有些多余的行也显示了
这是因为vga_pic模块里面是否要给pix_data的赋值的组合逻辑判断条件(char[char_x][char_y] == 1’b1),把x和y弄翻了,而且忘了给pix_x < (CHAR_B_H + CHAR_W)这个加括号
在这里插入图片描述

彩条显示范围是pix_x、pix_y的(0, 0) ~ (639, 479),现在显示字符的是char_x、char_y的(0, 0) ~ (255, 63)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值