第40章、基于RS232的VGA图像显示(串口+ram)
【实战】
使用 PC机 通过 UART串口 传输图片像素数据(txt文件)给FPGA,FPGA将 图片数据 缓存到内部RAM中,再利用vga控制模块读取,在VGA显示器中心位置显示缓存到RAM中的图片。VGA显示模式为 640x480@60;图片大小为100x100。
基于RS232的VGA图像显示工程的工作流程:
(1) 系统上电后,板卡传入系统时钟(sys_clk)和复位信号(sys_rst_n)到顶层模块;
(2) 系统时钟直接传入 时钟生成模块(clk_gen),分频产生 VGA工作时钟(vga_clk),作为图像数据生成模块(vga_pic)和VGA时序控制模块(vga_ctrl)的工作时钟;产生串口接收模块工作时钟(rx_clk),作为串口接收模块(uart_rx)的工作时钟。
(3) 使用PC机中的 上位机软件 向FPGA发送 图片数据,串口接收模块(uart_rx)将接收到的图片数据写入 图像数据生成模块(vga_pic) 中调用IP核生成的RAM中。
(4) 图像数据生成模块 以 VGA时序控制模块传入的像素点坐标(pix_x,pix_y)为约束条件,生成背景信息的待显示图像的色彩信息(pix_data);在图片显示区域读取存储于RAM的图片数据;两者数据结合生成VGA显示图像数据pix_data_out传入VGA时序控制模块。
(5) 图像数据生成模块生成的 图像色彩信息pix_data_out 传入 VGA时序控制模块,在模块内部使用使能信号滤除掉非图像显示有效区域的图像数据,产生 RGB色彩信息(rgb),在行、场同步信号(hsync、vsync)的同步作用下,将RGB色彩信息扫描显示到VGA显示器,实现图片显示。
【图像数据生成模块(vga_pic)】
【图片预处理】
图片不能直接通过串口收发,需要通过处理将图片转化为 指示像素信息的数据格式:
①、图片大小:本次实验显示图片大小为100*100,若图片满足要求,无需处理。图片大小的预处理方法可参阅“基于ROM的VGA图像显示”章节的相关部分,此处不再赘述。
②、图片格式:串口传输数据 位宽要求为8bit,要将像素的色彩格式转换为 RGB332 格式,这样既能通过串口传输,也能表示图片信息,但图片清晰度会降低。
使用Matlab对图片进行处理,将图片色彩模式转换为RGB332,并保存为十六进制文本格式的*.txt文件,具体见代码。
【.txt文件生成】
- 在vga_uart_pic文件夹下创建matlab文件夹,并添加图片
- 画图工具打开,修改像素为100*100,修改图片大小;
- matlab创建 vga_uart_pic.m 文件,运行代码,修改图片格式为 RGB332 ,并提取图像像素点信息,输出 “.txt” 格式文件
clc; %清理命令行窗口 clear all; %清理工作区 RGB=imread('logo.bmp'); %使用imread函数读取图片数据 [ROW,COL,D]=size(RGB); %图片行,列,维度 R=RGB(:,:,1); %提取图片中的红色分量 G=RGB(:,:,2); %提取图片中的绿色分量 B=RGB(:,:,3); %提取图片中的蓝色分量 imgdata=zeros(1,ROW*COL); %定义一个初值为0的数组,存储转换后的图片数据
%转换为RGB332格式
for r=1:ROW
for c=1:COL
imgdata((r-1)*COL+c)=bitand(R(r,c),224)+bitshift(bitand(G(r,c),224),-3)+bitshift(bitand(B(r,c),192),-6);
end
end
%打开或生成txt文件,将格式转换完成的数据写入txt文件
fidc=fopen('data_logo.txt','w+');
for i =1:ROW*COL
fprintf(fidc,'%02x ',imgdata(i));
end
fclose(fidc);
设计本模块的目的是产生 VGA彩条背景像素点色彩信息 和 读出RAM存储的图片数据。模块内部实例化RAM IP核,有6路输入,1路输出,输入信号为数据写时钟、数据写使能、数据写地址、写入数据、数据读时钟、数据读地址,输出为数据读地址对应图片数据。
输入信号:
- 时钟信号vga_clk :频率为25MHz,为VGA显示器工作时钟,由分频模块产生并输入;
- RAM数据写时钟 :频率为50MHz,由分频模块产生并输入,与 数据接收模块 的工作时钟为同一时钟;
- 复位信号sys_rst_n :为顶层模块的rst_n信号输入,低电平有效;pi_flag、pi_data两信号成对出现,由串口数据接收模块产生并传入,分别作为RAM数据写使能信号和数据写入信号;
- (pix_x,pix_y) :VGA有效显示区域像素点坐标,由VGA时序控制模块生并输入。
输出信号:
- pix_data_out :图像像素点色彩信息,在有效显示区域像素点坐标(pix_x,pix_y)约束下生成,传输到VGA时序控制模块。
第一部分:RAM数据写地址wr_addr信号波形
- 想要将串口传入的图像数据 写入RAM 中,时钟、使能、地址和数据信号缺一不可。时钟、使能和数据信号均由外部传入,地址信号内部声明。
- 使用输入的数据 写使能信号 pi_flag 作为 数据写地址的wr_addr的自加条件,数据写地址wr_addr赋初值为数据写入首地址,本实验的首地址0,pi_flag信号每拉高一次,地址信号加1。要注意的是,数据写地址使用的时钟要与RAM数据写时钟相同。
第二部分:彩条背景色彩信息(pi_data)波形图
- 根据输入像素点坐标(pix_x,pix_y),在有效显示区域,将pix_x计数范围十等分,在不同的计数部分给pix_data赋值对应的色彩信息,因为采用时序逻辑的赋值方式,pix_data滞后pix_x、pix_y信号一个时钟周期。
第三部分:RAM读使能(rd_en)、RAM地址(rd_addr)和读出图片数据(pic_data)波形图
- 将要显示的的图片数据通过串口写入RAM,写入图片分辨率为100*100。要想将存储在RAM的图片数据 读取出来,数据读时钟、读使能信号和地址信号必不可少,数据读时钟由外部传入,所以模块内部要声明 RAM读使能信号(rd_en) 和 RAM地址(ram_addr)信号。
- 在图片显示区域拉高使能信号,将要读取数据地址写入 RAM地址端口,读取地址对应图像数据。读地址信号以读使能信号为约束条件,在数据读时钟信号同步下,初值为0,当读使能信号为高电平时,每一个时钟周期自加1。但要注意,自RAM读取的数据是 滞后 使能信号和地址信号一个时钟周期的(比如,当使能信号为高电平,地址写入为999,但与地址999同步输出的数据为地址998的数据,所以RAM读使能信号(rd_en)和RAM地址(rd_addr)信号均要超前图片显示区域一个时钟周期)。
第四部分:图片显示有效信号(pic_valid)、待显示图像数据(pic_data_out)波形图
- 声明一个内部信号,那就是图片显示有效信号(pic_valid)。在有效信号为高电平时,将自RAM读出的图片数据赋值给待显示图像数据(pic_data_out),覆盖彩条背景。
- 利用RAM读使能信号(rd_en)信号 延迟一个时钟周期生成 图片显示有效信号(pic_valid)(RAM读使能信号(rd_en)超前图片显示区域一个时钟周期);
- 在有效信号为高电平时,将自ROM读出的图片数据赋值给待显示图像数据(pic_data_out),覆盖彩条背景。