淘宝地址:https://shop259121138.taobao.com/?spm=2013.1.1000126.d21.4b556901wuYhcM
最近学习FPGA设计,学习了VGA驱动电脑显示屏的驱动方式、硬件设计、程序设计、数据转换工具设计等。主要包括VGA时序、驱动写入、数据处理等
一、VGA时序
1、VGA时序在网上有很多博客都写了其时序方式,在这里我就不详细说明了,其行时序主要包括行段的A、B、C、D四段,工作过程中A段拉低,其他三段拉高,进行行同步信号;场时序包括O、P、Q、R工作过程中O段拉低,其他三段拉高,进行场同步信号;
2、频率设计,根据每一段的总时钟数,F=H_CLK*VCLK*60,即60帧的数据即可得到稳定的人眼可识别图像。
二、程序设计
1、驱动设计(.v)
设计VGA驱动
时钟频率12M,利用PLL增频率到40M,采用VGA_800X600_60Hz
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Module: VGA_module
//
// Author: Jun
//
// Description: VGA_module
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date: |Changes Made:
// V1.1 |2017/5/7 |Initial ver
// --------------------------------------------------------------------
module VGA_module
(
input clk_in, //system clock pin 40MHz
input rst_n_in, //system reset pin,active low
output reg sync_v, //V_Fild signal
output reg sync_h, //H_Fild signal
output reg [2:0] vga_data //vga data,[R,G,B]
);
reg [15:0] x_cnt;
reg [15:0] y_cnt;
reg vga_valid;
reg [7:0] Rom_address;
wire [127:0] Rom_data;
My_Rom u_My_Rom
(
.Address(Rom_address),
.Data(Rom_data)
);
//reg [9:0] IP_Rom_address;
//wire [63:0] IP_Rom_data;
//Rom u_Rom
//(
// .address(IP_Rom_address),
// .clock(clk_in),
// .q(IP_Rom_data)
//);
//accumulate the num of row num
always @(posedge clk_in or negedge rst_n_in)
begin
if(!rst_n_in) x_cnt<=16'd0; //reset signal
else if(x_cnt >= `HSYNC_D) x_cnt<=16'd0; //clear x_cnt
else x_cnt<=x_cnt+1'b1; //accumulate x_cnt
end
//accumulate the num of coum num
always @(posedge clk_in or negedge rst_n_in)
begin
if(!rst_n_in) y_cnt<=16'd0; //reset signal
else if(x_cnt == `HSYNC_D) //x_cnt come to the end
begin
if(y_cnt>=`VSYNC_R) y_cnt <= 16'd0; //clear y_cnt
else y_cnt <= y_cnt+1'b1; //accumulate y_cnt
end
else y_cnt <= y_cnt;
end
//change the lever of HSYNC Signal
//A->low BCD->High
always @(posedge clk_in ,negedge rst_n_in)
begin
if(!rst_n_in) sync_h<=1'b1; //reset signal
else if(x_cnt < `HSYNC_A) sync_h <= 1'b0; //A low lever
else sync_h <= 1'b1; //BCD high lever
end
//change the lever of VSYNC Signal
//O->low PQR->High
always @(posedge clk_in ,negedge rst_n_in)
begin
if(!rst_n_in) sync_v<=1'b1; //reset signal
else if(y_cnt < `VSYNC_O) sync_v <= 1'b0; //O low lever
else sync_v <= 1'b1;
end
//judge availability of vga_valid
always @(posedge clk_in ,negedge rst_n_in)
begin
if(!rst_n_in) vga_valid<=1'b0; //reset ,unvalid
//x_cnt between B_C,,y_cnt between P_Q
else if((x_cnt > `HSYNC_B) && (x_cnt <`HSYNC_C) && (y_cnt > `VSYNC_P) && (y_cnt < `VSYNC_Q))
vga_valid <= 1'b1; //valid
else vga_valid <=1'b0; //unvalid
end
always @(posedge clk_in ,negedge rst_n_in)
begin
if(!rst_n_in) vga_data=3'b000;
else if(vga_valid)
begin
// display the color block
// if((x_cnt > `HSYNC_B) && (x_cnt <= `HSYNC_B + 10'd100))
// vga_data = 3'b100; //红色
// else if((x_cnt > `HSYNC_B + 10'd100) && (x_cnt <= `HSYNC_B + 10'd200))
// vga_data = 3'b010; //黄色
// else if((x_cnt > `HSYNC_B + 10'd200) && (x_cnt <= `HSYNC_B + 10'd300))
// vga_data = 3'b001; //黄色
// else if((x_cnt > `HSYNC_B + 10'd300) && (x_cnt <= `HSYNC_B + 10'd400))
// vga_data = 3'b110; //黄色
// else if((x_cnt > `HSYNC_B + 10'd400) && (x_cnt <= `HSYNC_B + 10'd500))
// vga_data = 3'b101; //黄色
// else if((x_cnt > `HSYNC_B + 10'd500) && (x_cnt <= `HSYNC_B + 10'd600))
// vga_data = 3'b011; //黄色
// else if((x_cnt > `HSYNC_B + 10'd600) && (x_cnt <= `HSYNC_B + 10'd700))
// vga_data = 3'b111; //蓝色
// else if((x_cnt > `HSYNC_B + 10'd700) && (x_cnt <= `HSYNC_B + 10'd800))
// vga_data = 3'b000; //绿色
// else
// vga_data = 3'b111; //黑色
//display the picture
//0-544 comu data 0-63 raw data
if((x_cnt > `HSYNC_B+10'd100) && (x_cnt <= `HSYNC_B+10'd100 + 10'd127)&&(y_cnt > `VSYNC_P+10'd100)&&(y_cnt < `VSYNC_P+10'd100 + 10'd127))
begin
Rom_address[7:0] <= x_cnt - `HSYNC_B -10'd100;
if(Rom_data[10'd127-(y_cnt - `VSYNC_P-10'd100)]) vga_data<=3'b110;
else vga_data<=3'b000;
end
else vga_data<=3'b000;
end
else vga_data<=3'b000;
end
endmodule
2、数据处理设计
改数据处理用到三个软件,包括字膜处理软件、Mif生成软件以及自己开发的一款直接把MIF文件转换成.v文件的软件
1.字模软件设置
2.Mif生成软件(用管理员身份运行)
3.自己写的转换软件
4.如果需要图像显示,只能显示二进制图像,需要用软件将普通图片转换成二值化图像,可以用MATLAB实现
I = imread('C:\Users\Jun\Desktop\5555.bmp');
imshow(I);
I3=im2bw(I);
imshow(I3);
I4=imresize(I3,[128 128]);
imwrite(I4,'C:\Users\Jun\Desktop\6666.bmp');
经过这些步骤即可得在显示屏中设计出自己想看到的图片
如果有什么问题,可以讨论[email protected]邮件联系