项目:串口接收—ram存储—TFT显示(完整设计)

该博客详细描述了一个FPGA系统如何通过UART串口接收RGB565像素数据,然后将其存储到内部RAM中,再根据TFT显示屏的控制器请求,从RAM读取数据并在显示屏上按指定区域显示。设计中包含了串口接收模块、数据写入RAM模块、从RAM读取数据模块以及TFT显示屏控制模块,同时考虑了显示屏的分辨率限制和数据传输延迟。

目的:

1.使用uart串口接收模块接收待显示的串行数据(像素RGB值)。

2.把待显示的数据写入ram中。

3.从ram中读取像素值到TFT显示屏中显示,并对应输出该像素的坐标值。

注意:

1.遵循uart协议的一个数据位宽为8,一个RGB565像素值位宽为16,所以接收两个再存入RAM中的一个存储单元。

2.由显示屏控制器发出读取数据的请求信号,再从ram中读出数据,传输到显示屏显示,总共慢了两拍,因此请求信号应该提前两拍发出。

3.在读取ram模块中可以控制在显示屏中显示的区域。用参数划定区域,然后区域内读取ram值并输出显示,区域外不读数据,输出0(黑屏)。

4.由于每个fpga芯片上的ram存储资源是有限的,只能存储定量的像素值,所以如果显示屏的分辨率太高,只能显示一部分区域。

5.ram资源的查找方法:①看fpga芯片有几个块ram资源

            ②到手册上查看该芯片上每个ram的存储容量。

            ③两个值相乘即是最大容量。

6.把两位低位宽数据存储成一位高位宽数据,可以利用计数器的奇偶,或者取它的高位。如:

  

框图:

实现:把之前的模块进行连线,并增加写入模块和读出模块。(为了相互适配,旧模块在本次设计中代码有所调整)

`timescale 1ns /1ns
module uart_ram_TFT_send_tb(   );

    reg clk ;
    reg reset ;
    reg uart_tx ;
    wire [15:0]RGB565_data ;
    wire [15:0]vish_axis ;//显示的行坐标
    wire [15:0]visv_axis ;//显示的列坐标   
    reg [7:0] rand;
    reg [16:0]input_cnt ;
    uart_ram_TFT uart_ram_TFT_sim_send(//顶层连线
    clk,//50MHz
    reset,
    uart_tx ,
    RGB565_data,//输出的内容数据
    vish_axis ,//显示的行坐标
    visv_axis //显示的列坐标
    );
    
    initial clk = 1 ;
    always #10 clk = ! clk ;
    initial begin
    reset = 0 ;
    uart_tx = 1;
    input_cnt = 0 ;
    rand = 0 ;
    input_cnt = 0 ;
    #201 ;
    reset = 1 ;
    #800000;
    repeat(65536)begin
        #20 ;
        rand = {$random} % 255;
        #20 ;
        uart_input(rand);   
        input_cnt = input_cnt + 1 ;           
        end
    #1000 ;
    $stop ;
    end

    
    task uart_input ;//设定一个任务uart_inpt,有一个输入端uart_tx_data_stm 。在这个task里可以对task外的变量进行赋值
        input [7:0]uart_tx_data_stm ;//不返回值,所以不能用x=uart_input。而是直接uart_input。
        begin   //结构简单的begin-end
        uart_tx = 1 ;
        #20 ;
        uart_tx  = 0 ;
        #8640 ;
        uart_tx = uart_tx_data_stm[0] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[1] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[2] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[3] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[4] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[5] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[6] ;
        #8640 ;
        uart_tx = uart_tx_data_stm[7] ;
        #8640 ;
        uart_tx  = 1 ;
        #8640 ;
        end     
    endtask
    
    
endmodule
module uart_ram_TFT(//顶层连线模块
    clk,//50MHz
    reset,
    uart_tx ,
    RGB565_data,//输出的内容数据
    vish_axis ,//显示的行坐标
    visv_axis //显示的列坐标
    );
  
  input clk ;
  input reset ;
  input uart_tx ;
  output [15:0]RGB565_data ;
  output [15:0]vish_axis ;//显示的行坐标
  output [15:0]visv_axis ;//显示的列坐标 
  
  //内部变量
  wire [7:0]parallel_data ;//串口接收模块接收的并行数据8位
  wire rx_done ;//串口接收模块接收8位数据结束信号
  
  
  //uart接收模块
  uart_receive_1 uart_receive(//串口接收模块
    .clk(clk) ,
    .reset(reset) ,
    .baud_rate(5) ,
    .uart_tx(uart_tx), 
    .data(parallel_data) ,
    .rx_done(rx_done)   
    );  
  
  
  //内部变量
  wire [15:0]addr_write ;//串口接收模块接收的并行数据8位
  wire [15:0]data_write ;//串口接收模块接收8位数据结束信号
  wire write_enable ;//写入使能信号
  
  //uart接收的数据存入ram模块
  uart_to_ram uart_to_ram(//将uart串口接收模块输出的数据写入ram中
    .clk(clk) ,
    .reset(reset) ,
    .data(parallel_data),
    .rx_done(rx_done),
    .addr(addr_write) ,
    .dout(data_write) ,
    .wenable(write_enable )    
    ); 
  
  //内部变量
  wire clk_b ;//串口接收模块接收的并行数据8位
  wire [15:0]addr_read ;
  wire read_ram_request ;
  wire [15:0]read_data ;
  
  //ram存储模块
  RAM_DISPLAY RAM (
  .clka(clk),    // input wire clka
  .ena(1),      // input wire ena
  .wea(write_enable),      // input wire [0 : 0] wea
  .addra(addr_write),  // input wire [15 : 0] addra
  .dina(data_write),    // input wire [15 : 0] dina
  .clkb(clk_b),    // input wire clkb
  .enb(read_ram_request),      // input wire enb
  .addrb(addr_read),  // input wire [15 : 0] addrb
  .doutb(read_data)  // output wire [15 : 0] doutb
);
  
   //内部变量
  wire disp_request ;
  wire [15:0]disp_data ;
  
  //从ram读数据模块
  ram_to_display ram_to_display(//读ram数据到显示屏模块
    .clka(clk),//输入时钟
    .reset(reset),//复位
    .data(read_data),//ram读出的数据16位
    .data_request(disp_request),//显示屏控制的的数据请求信号
    .h_axis(vish_axis) ,//行坐标
    .v_axis(visv_axis) ,//列坐标
    .clkb(clk_b),//显示屏控制器的输入时钟
    .addr_read(addr_read),//读ram的地址
    .read_ram_request(read_ram_request),//读ram请求信号 
    .display_data(disp_data)//显示屏控制器的数据输入信号    
    );
    
  //屏幕显示器控制模块
  VGA TFT_control(
    .clk(clk_b),
    .reset(reset),
    .content_data_request(disp_request),//数据请求信号
    .content_data(disp_data),//要显示的内容数据
    .RGB_data(RGB565_data),//输出的内容数据
    .vis_h_axis(vish_axis) ,//显示的行坐标
    .vis_v_axis(visv_axis) ,//显示的列坐标
    .vis_sig()//内容显示同步信号(高电平时显示)
    );  
    
    
en
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值