fpga项目 : 原子与野火RGB屏显示 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
1) 简介
- 原子4.3寸RGB屏,分辨率为480x800,根据porch参数简单计算后得知,tft_clk需要30MHz
- 设置tang-nano 20k的si5351 pll_clk O0=30MHz
- 注意这款RGB屏需要5V电源(板子有5V-3V LDO),我们的扩展板没法直接支持5V。我们通过灰排线,把灰排线剪断PIN-0和PIN-1,然后连接一个排针去插5V电源。
- 注意不要直接把引脚接5V电源,这样会把FPGA引脚过压烧了!!
野火与原子的引脚排布如下(原子使用反向fpc排线,野火使用同向fpc排线)
2) tang nano 20k引脚分配(原子fpc接口)
原子接口注意要使用反向排线
采用原子的口,程序可以下载到SRAM或者MSPI-FLASH都没有问题,因为MSPI接口没有被跳线帽拉死。
//1,2引脚由灰色排线接5V
//11,29,20引脚接GND
//34引脚接3V3
IO_LOC "sys_clk" 10; //用si5351 pll_clk_0
IO_LOC "sys_rst" 88;
IO_LOC "r[7]" 41; //r7
IO_LOC "r[6]" 15; //r6
IO_LOC "r[5]" 42; //r5
IO_LOC "r[4]" 77; //r4
IO_LOC "r[3]" 80; //r3
IO_LOC "r[2]" 85; //r2
IO_LOC "r[1]" 76; //r1
IO_LOC "r[0]" 75; //r0
IO_LOC "g[7]" 26; //g7
IO_LOC "g[6]" 48; //g6
IO_LOC "g[5]" 25; //g5
IO_LOC "g[4]" 51; //g4
IO_LOC "g[3]" 28; //g3
IO_LOC "g[2]" 54; //g2
IO_LOC "g[1]" 27; //g1
IO_LOC "g[0]" 56; //g0
IO_LOC "b[7]" 20; //b7
IO_LOC "b[6]" 17; //b6
IO_LOC "b[5]" 79; //b5
IO_LOC "b[4]" 31; //b4
IO_LOC "b[3]" 86; //b3
IO_LOC "b[2]" 30; //b2
IO_LOC "b[1]" 49; //b1
IO_LOC "b[0]" 29; //b0
IO_LOC "hsync" 18;
IO_LOC "vsync" 71;
IO_LOC "tft_clk" 72;
IO_LOC "tft_de" 53;
3) tang nano 20k引脚分配(野火fpc接口)
野火接口注意要使用同向排线(目的是让5V引脚映射到PIN1/2,这2个脚我们通过灰排线接5V)
采用野火的接口,程序只能下载到SRAM,因为MSPI-FLASH接口被跳线帽拉死了,程序烧不进去/读不出来。
//1,2引脚由灰色排线接5V
//3,4引脚接3V3
//5引脚接GND
//34,35引脚接3V3
IO_LOC "sys_clk" 10;
IO_LOC "sys_rst" 88;
IO_LOC "r[0]" 80;
IO_LOC "r[1]" 77;
IO_LOC "r[2]" 42;
IO_LOC "r[3]" 15;
IO_LOC "r[4]" 41;
IO_LOC "r[5]" 16;
IO_LOC "r[6]" 56;
IO_LOC "r[7]" 27;
IO_LOC "g[0]" 54;
IO_LOC "g[1]" 28;
IO_LOC "g[2]" 51;
IO_LOC "g[3]" 25;
IO_LOC "g[4]" 48;
IO_LOC "g[5]" 26;
IO_LOC "g[6]" 55;
IO_LOC "g[7]" 29;
IO_LOC "b[0]" 49;
IO_LOC "b[1]" 30;
IO_LOC "b[2]" 86;
IO_LOC "b[3]" 31;
IO_LOC "b[4]" 79;
IO_LOC "b[5]" 17;
IO_LOC "b[6]" 20;
IO_LOC "b[7]" 19;
IO_LOC "tft_clk" 72;
IO_LOC "hsync" 18;
IO_LOC "vsync" 71;
IO_LOC "tft_de" 53;
//IO_LOC "DISP" 52; //这个脚注释,在扩展板上接3V3
//IO_LOC "tft_bl"; //这个脚注释,在扩展板上接3V3
4) colorbar显示代码
- 程序是在野火的例子上改写的,做了如下改动:
- 原始分辨率是272x480,我们改成480x800后,cnt_h/cnt_v计数器从10bits增加到11bits
- 将接口从tfr_rgb[15:0]修改为r[7:0],g[7:0],b[7:0],这样方便分配引脚
- vsync/hsync/te修改为低电平有效(插入反相器)
`timescale 1ns/1ns
module tft_colorbar
(
input wire sys_clk ,
input wire sys_rst ,
output wire [7:0] r ,
output wire [7:0] g ,
output wire [7:0] b ,
output wire hsync ,
output wire vsync ,
output wire tft_clk ,
output wire tft_de ,
output wire tft_bl
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//wire define
wire tft_clk_9m ; //TFT����ʱ��,Ƶ��9MHz
wire locked ; //PLL locked�ź�
wire rst_n ; //TFTģ�鸴λ�ź�
wire [10:0] pix_x ; //TFT��Ч��ʾ����X������
wire [10:0] pix_y ; //TFT��Ч��ʾ����Y������
wire [15:0] pix_data ; //TFT���ص�ɫ����Ϣ
wire clk_reg ;
//rst_n:TFTģ�鸴λ�ź�
assign rst_n = ~sys_rst;
assign vsync=~vsync_n;
assign hsync=~hsync_n;
assign tft_de=~tft_de_n;
wire [15:0] rgb_tft;
assign r={rgb_tft[15:11],3'b000};
assign g={rgb_tft[10:5],2'b00};
assign b={rgb_tft[4:0],3'b000};
//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//
assign tft_clk=~tft_clk_9m;
assign tft_clk_9m=sys_clk;
//------------- tft_ctrl_inst -------------
tft_ctrl tft_ctrl_inst
(
.tft_clk_9m (tft_clk_9m), //����ʱ��,Ƶ��9MHz
.sys_rst_n (rst_n ), //ϵͳ��λ,�͵�ƽ��Ч
.pix_data (pix_data ), //����ʾ����
.pix_x (pix_x ), //����TFT��Ч��ʾ�������ص�X������
.pix_y (pix_y ), //����TFT��Ч��ʾ�������ص�Y������
.rgb_tft (rgb_tft ), //TFT��ʾ����
.hsync (hsync_n ), //TFT��ͬ���ź�
.vsync (vsync_n ), //TFT��ͬ���ź�
.tft_clk (clk_reg ), //TFT����ʱ��
.tft_de (tft_de_n ), //TFT����ʹ��
.tft_bl (tft_bl ) //TFT�����ź�
);
//------------- tft_pic_inst -------------
tft_pic tft_pic_inst
(
.tft_clk_33m (tft_clk_9m), //���빤��ʱ��,Ƶ��9MHz
.sys_rst_n (rst_n ), //���븴λ�ź�,�͵�ƽ��Ч
.pix_x (pix_x ), //����TFT��Ч��ʾ�������ص�X������
.pix_y (pix_y ), //����TFT��Ч��ʾ�������ص�Y������
.pix_data (pix_data ) //�������ص�ɫ����Ϣ
);
endmodule
`timescale 1ns/1ns
module tft_ctrl
(
input wire tft_clk_9m , //����ʱ��,Ƶ��9MHz
input wire sys_rst_n , //ϵͳ��λ,�͵�ƽ��Ч
input wire [15:0] pix_data , //����ʾ����
output wire [10:0] pix_x , //����TFT��Ч��ʾ�������ص�X������
output wire [10:0] pix_y , //����TFT��Ч��ʾ�������ص�Y������
output wire [15:0] rgb_tft , //TFT��ʾ����
output wire hsync , //TFT��ͬ���ź�
output wire vsync , //TFT��ͬ���ź�
output wire tft_clk , //TFT����ʱ��
output wire tft_de , //TFT����ʹ��
output wire tft_bl //TFT�����ź�
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter H_SYNC = 11'd1 , //��ͬ��
H_BACK = 11'd46 , //��ʱ������
H_VALID = 11'd800 , //��������
H_FRONT = 11'd210 , //��ʱ��ǰ��
H_TOTAL = H_SYNC+H_BACK+H_VALID+H_FRONT ; //��ɨ������
parameter V_SYNC = 11'd1 , //��ͬ��
V_BACK = 11'd23 , //��ʱ������
V_VALID = 11'd480 , //��������
V_FRONT = 11'd22 , //��ʱ��ǰ��
V_TOTAL = V_SYNC+V_BACK+V_VALID+V_FRONT ; //��ɨ������
//wire define
wire rgb_valid ; //VGA��Ч��ʾ����
wire pix_data_req ; //���ص�ɫ����Ϣ�����ź�
//reg define
reg [10:0] cnt_h ; //��ɨ��������
reg [10:0] cnt_v ; //��ɨ��������
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//tft_clk,tft_de,tft_bl��TFT����ʱ�ӡ�����ʹ�ܡ������ź�
assign tft_clk = tft_clk_9m ;
assign tft_de = rgb_valid ;
assign tft_bl = sys_rst_n ;
//cnt_h:��ͬ���źż�����
always@(posedge tft_clk_9m or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_h <= 11'd0 ;
else if(cnt_h == H_TOTAL - 1'd1)
cnt_h <= 11'd0 ;
else
cnt_h <= cnt_h + 1'd1 ;
//hsync:��ͬ���ź�
assign hsync = (cnt_h <= H_SYNC - 1'd1) ? 1'b1 : 1'b0 ;
//cnt_v:��ͬ���źż�����
always@(posedge tft_clk_9m or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_v <= 11'd0 ;
else if((cnt_v == V_TOTAL - 1'd1) && (cnt_h == H_TOTAL-1'd1))
cnt_v <= 11'd0 ;
else if(cnt_h == H_TOTAL - 1'd1)
cnt_v <= cnt_v + 1'd1 ;
else
cnt_v <= cnt_v ;
//vsync:��ͬ���ź�
assign vsync = (cnt_v <= V_SYNC - 1'd1) ? 1'b1 : 1'b0 ;
//rgb_valid:VGA��Ч��ʾ����
assign rgb_valid = (((cnt_h >= H_SYNC + H_BACK)
&& (cnt_h < H_SYNC + H_BACK + H_VALID))
&&((cnt_v >= V_SYNC + V_BACK)
&& (cnt_v < V_SYNC + V_BACK + V_VALID)))
? 1'b1 : 1'b0;
//pix_data_req:���ص�ɫ����Ϣ�����ź�,��ǰrgb_valid�ź�һ��ʱ������
assign pix_data_req = (((cnt_h >= H_SYNC + H_BACK - 1'b1)
&& (cnt_h < H_SYNC + H_BACK + H_VALID - 1'b1))
&&((cnt_v >= V_SYNC + V_BACK)
&& (cnt_v < V_SYNC + V_BACK + V_VALID)))
? 1'b1 : 1'b0;
//pix_x,pix_y:VGA��Ч��ʾ�������ص�����
assign pix_x = (pix_data_req == 1'b1)
? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 11'h7ff;
assign pix_y = (pix_data_req == 1'b1)
? (cnt_v - (V_SYNC + V_BACK )) : 11'h7ff;
//rgb_tft:�������ص�ɫ����Ϣ
assign rgb_tft = (rgb_valid == 1'b1) ? pix_data : 16'b0 ;
endmodule
`timescale 1ns/1ns
module tft_pic
(
input wire tft_clk_33m , //输入工作时钟,频率33MHz
input wire sys_rst_n , //输入复位信号,低电平有效
input wire [10:0] pix_x , //输入TFT有效显示区域像素点X轴坐标
input wire [10:0] pix_y , //输入TFT有效显示区域像素点Y轴坐标
output reg [15:0] pix_data //输出像素点色彩信息
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
parameter H_VALID = 11'd800 , //行有效数据
V_VALID = 11'd480 ; //场有效数据
parameter RED = 16'hF800, //红色
ORANGE = 16'hFC00, //橙色
YELLOW = 16'hFFE0, //黄色
GREEN = 16'h07E0, //绿色
CYAN = 16'h07FF, //青色
BLUE = 16'h001F, //蓝色
PURPPLE = 16'hF81F, //紫色
BLACK = 16'h0000, //黑色
WHITE = 16'hFFFF, //白色
GRAY = 16'hD69A; //灰色
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge tft_clk_33m or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pix_data <= 16'd0;
else if((pix_x >= 0) && (pix_x < (H_VALID/10)*1))
pix_data <= RED;
else if((pix_x >= (H_VALID/10)*1) && (pix_x < (H_VALID/10)*2))
pix_data <= ORANGE;
else if((pix_x >= (H_VALID/10)*2) && (pix_x < (H_VALID/10)*3))
pix_data <= YELLOW;
else if((pix_x >= (H_VALID/10)*3) && (pix_x < (H_VALID/10)*4))
pix_data <= GREEN;
else if((pix_x >= (H_VALID/10)*4) && (pix_x < (H_VALID/10)*5))
pix_data <= CYAN;
else if((pix_x >= (H_VALID/10)*5) && (pix_x < (H_VALID/10)*6))
pix_data <= BLUE;
else if((pix_x >= (H_VALID/10)*6) && (pix_x < (H_VALID/10)*7))
pix_data <= PURPPLE;
else if((pix_x >= (H_VALID/10)*7) && (pix_x < (H_VALID/10)*8))
pix_data <= BLACK;
else if((pix_x >= (H_VALID/10)*8) && (pix_x < (H_VALID/10)*9))
pix_data <= WHITE;
else if((pix_x >= (H_VALID/10)*9) && (pix_x < H_VALID))
pix_data <= GRAY;
else
pix_data <= BLACK;
endmodule
5) char显示代码
- 显示内容为“野火科技”
- 只是tft_pic.v不同,其它与上面的同
`timescale 1ns/1ns
////////////////////////////////////////////////////////////////////////
// Author : EmbedFire
// Create Date : 2020/03/20
// Module Name : tft_pic
// Project Name : tft_char
// Target Devices: Xilinx XC6SLX16
// Tool Versions : ISE 14.7
// Description : 图像数据生成模块
//
// Revision : V1.0
// Additional Comments:
//
// 实验平台: 野火_踏浪Pro_FPGA开发板
// 公司 : http://www.embedfire.com
// 论坛 : http://www.firebbs.cn
// 淘宝 : https://fire-stm32.taobao.com
////////////////////////////////////////////////////////////////////////
module tft_pic
(
input wire tft_clk_33m , //输入工作时钟,频率33MHz
input wire sys_rst_n , //输入复位信号,低电平有效
input wire [10:0] pix_x , //输入TFT有效显示区域像素点X轴坐标
input wire [10:0] pix_y , //输入TFT有效显示区域像素点Y轴坐标
output reg [15:0] pix_data //输出像素点色彩信息
);
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
parameter H_VALID = 11'd800 , //行有效数据
V_VALID = 11'd480 ; //场有效数据
parameter CHAR_B_H= 10'd272 , //字符开始X轴坐标
CHAR_B_V= 10'd208 ; //字符开始Y轴坐标
parameter CHAR_W = 10'd256 , //字符宽度
CHAR_H = 10'd64 ; //字符高度
parameter BLACK = 16'h0000, //黑色
GOLDEN = 16'hFEC0; //金色
//wire define
wire [10:0] char_x ; //字符显示X轴坐标
wire [10:0] char_y ; //字符显示Y轴坐标
//reg define
reg [255:0] char [63:0] ; //字符数据
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//字符显示坐标
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) : 11'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) : 11'h3FF;
//char:字符数据
always@(posedge tft_clk_33m)
begin
char[0] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[1] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[2] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[3] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[4] <= 256'h00000000003C0000000000000000000000000000000070000000000000000000;
char[5] <= 256'h0000000E003E00000000000000000000000000000000F0000000000000000000;
char[6] <= 256'h000000FF001F00000000000000000000000000000001F0000000000000400000;
char[7] <= 256'h000007FF000F00000000000000000000000010000001F8000000000000E00000;
char[8] <= 256'h00007FFE000F000000000000000000000003FE000001F8000000000000F00000;
char[9] <= 256'h0000FE7E003F00000000000000000000000FFF800001F80000003E0000F00000;
char[10] <= 256'h0000E07C01F8000000000000000000000007FF81F801FC0000003F0000F00000;
char[11] <= 256'h0000E0F80380000000000000000000000003FF80FE00780000003F0001E00000;
char[12] <= 256'h0000E0F80380000000000000000000000001FF80FF00780000003F0001E00000;
char[13] <= 256'h0780E1F003FC000000000000000000000000FF80FF80780000003E0001E00000;
char[14] <= 256'h07C0FFF003FE0000000000020000000000003F007F80780000003E0001E00000;
char[15] <= 256'h07E0FFE001FE0000000000070000000000000E007F00780000003C0001FF0000;
char[16] <= 256'h07F3FFE0000E00000000000700000000000000007E00F80000003C0001FF0000;
char[17] <= 256'h07F9FFC0000E00000000000F0000000000003E00CC01F80000007C0003FE0000;
char[18] <= 256'h03F9FFC0001C03E00000000F8000000000003F010001F80000007E0003F80000;
char[19] <= 256'h03F9FF8000781FF80000001F8000000000007F038001F8000000FF0007F00000;
char[20] <= 256'h03F9FF8001F07FF80000001F878000000000FE078001F8000000FF000FE00000;
char[21] <= 256'h03FDFF0007C3FFF00000003FFFC000000001FC07C001F8000001FF003FE00000;
char[22] <= 256'h03FDFF000F9F8FF00001C03FFFC000000007F807F001F8000007FE003FC00000;
char[23] <= 256'h03FFFE001FFF8FE00001E07FFFC00000001FF807FC01F800000FFC0003C00000;
char[24] <= 256'h01FFF0007FFF8FC00003E07FFC000000067FF007FE01FC00001FF80003800000;
char[25] <= 256'h01FFC000FFEF9F800003E0FE000000000FFFF003FC01FE00007FF00007800000;
char[26] <= 256'h01FF8001FF8F9F000007E0FE000000000FFFF041F803FC0000FFE00007800000;
char[27] <= 256'h01FF8007FC1F9E00001FE0FE000000000FFFF180F00FFC000001E00007000000;
char[28] <= 256'h00FF8007F01F3C00003FE1FC00000000007FF601E01FF8000001E000071C0000;
char[29] <= 256'h00FF8007C01FFC00003FE1FC00000000001FFC03C0FFF8000001E0000F3E0000;
char[30] <= 256'h00030002001FF800003FC3FC00000000003FF807C3FFF8000001E7800FFE0000;
char[31] <= 256'h00070000001FF000007FC3F800000000003FF80F9FFFF0000001FF000FFE0000;
char[32] <= 256'h0007F000001FE000007F83F800000000007FF01FFFC3F0000001FE000FFE0000;
char[33] <= 256'h001FF000001FC000003F83F00000000000FFF01FFE03F0000001FC001FFE0000;
char[34] <= 256'h007FE000001F8000003F07F00000000000FFE03FF003F0000003F8001F3E0000;
char[35] <= 256'h007FC000001F8000001807F00000000001FFE03F8003F0000003F0001F3C0000;
char[36] <= 256'h00078600001F000000000FF80000000003FFC07E0003F0000003F0001E3C0000;
char[37] <= 256'h000F1E00001F000000000FFC0000000007FFC0180003F0000007E003843C0000;
char[38] <= 256'h003FFC00001F800000001FDE0000000007FFC0000003F000000FF001E03C0000;
char[39] <= 256'h007FF800001F800000003FDF8000000007C7C0000003F00000FFF000F83C0000;
char[40] <= 256'h00FFF000001F800000007F9FF00000000787C0000003F00007FFF0007F3C0000;
char[41] <= 256'h01FFE000001F80000000FF0FFE0000000707C0000003F0001FF1F8003FFC0000;
char[42] <= 256'h03FF8000001F80000001FE0FFFE000000003C0000003F0003F81F8001FFC0000;
char[43] <= 256'h07FF0000003F80000003FC07FFFE0000000300000003F0003E01FC000FFE0000;
char[44] <= 256'h07FC0000003F80000007F803FFFFE000000000000003F0001F83FC0007FFF000;
char[45] <= 256'h07F80000003F8000000FF001FFFFFF80000000000003F0000FFFFC0003FFFF80;
char[46] <= 256'h03E00000007F8000001FC0007FFFFFC0000000000003F00003FFFE0007FFFFF0;
char[47] <= 256'h0000000000FF8000007F80001FFFFFE0000000000003F000007FFE003FBFFFF8;
char[48] <= 256'h0000000001FF800000FE000007FFFFE0000000000003E000000FFC03FE0FFFF8;
char[49] <= 256'h0000000007FF800001F8000001FFFFF0000000000003E0000000F8FFC003FFF8;
char[50] <= 256'h000000007FFF000003E00000001FFFC0000000000003C0000000000000007FF8;
char[51] <= 256'h00000007FFFE0000070000000001FFC0000000000003C0000000000000000FF0;
char[52] <= 256'h0000000200F800000000000000000F8000000000000300000000000000000060;
char[53] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[54] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[55] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[56] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[57] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[58] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[59] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[60] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[61] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[62] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
char[63] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
end
//pix_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge tft_clk_33m or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pix_data <= BLACK;
else if(((pix_x >= CHAR_B_H) && (pix_x < (CHAR_B_H + CHAR_W)))
&& ((pix_y >= CHAR_B_V) && (pix_y < (CHAR_B_V + CHAR_H))))
begin
if(char[char_y][10'd255 - char_x] == 1'b1)
pix_data <= GOLDEN;
else
pix_data <= BLACK;
end
else
pix_data <= BLACK;
endmodule