rs232_lcd显示

与上一次写学习总结相隔时间有点久,因为最近比较忙,一直干一些有的没的杂活,学习时间较少,而且第一次用Xilinx的FPGA不熟悉vivado开发环境和流程。以往的学习都是用Altera的芯片,实验室有了一块闲置的正点原子达芬奇开发板,刚好用来学习Xilinx开发流程。

目录

一、实验目的

二、内容

三、相关程序

四、结果

五、遇到的问题

六、总结


 

一、实验目的

实验内容为LED显示,跟着正点原子LED彩条实验教程学习,但毕竟已经有了一点基础,就将实验稍做改进。具体为:rs232协议串口传入RGB888的彩色图;将R、G、B三通道三个字节的数据组成一个24位像素的数据,传入LCD驱动模块;另外设置一个LCD背光控制模块,PWM调光设置4个等级,由按键控制输出。

二、内容

下图是正点原子实验的各模块视图

09836c7d36b440628edd04d66af7ca4d.png

 

下图是此次实验修改的各模块视图:

34b5424acbe14f018746e3574f4a72e8.png

各模块功能如下:

uart_rx:串口接收模块,输出为并行8位数据以及一个数据标志信号;

bit_wide_conver:将串口接收模块输出的8位数据转换成24位RBG888数据,并带有数据标志信号。

rd_in:读lcd ID,将其输出到config_gen模块;

config_gen:根据输入的LCD ID产生后续lcd_pic、lcd_driver模块的配置信号,包括:时钟、 行同步信号时钟数、行后沿时钟数、行像素显示时钟数、行后沿时钟数以及场的各信息。与正点原子不同的是,将时钟、显示参数单独设置为一个模块。

lcd_pic:图像数据生成模块,将输入的RGB888缓存到ram ip核中,然后根据lcd_driver模块输入的显示坐标信息,将RGB888图像与彩条像素数据整合,使得输出的一帧图像串口输入的图像在LCD的中央。

lcd_driver:驱动LCD,采用的模式与VGA一样,只是多了一个使能信号、驱动时钟。

key_filter:按键消抖模块,每次按一下按键产生一个时钟的低电平。

bl_ctrl:控制lcd屏亮度,PWM调光设置4个等级,由按键控制输出,按一次按键转换一次亮度(循环)。

三、相关程序

串口输入的RBG888图像数据由MATLAB生成,R、G、B通道数据分开传送。代码为

clc;
clear;
close all;
RGB24 = imread("C:\Users\zxy\Pictures\1.png");
R = uint32(RGB24(:,:,1));
G = uint32(RGB24(:,:,2));
B = uint32(RGB24(:,:,3));
r = R';
g = G';
b = B';

a = r(101);%用于测试正确写入文件数据的顺序
%测试发现MATMAB数组顺序索引时,按列输出,所以先转置
fid=fopen('rgb111.txt','w+'); 
for i=1:10000
fprintf(fid,'%02x ',r(i));  
fprintf(fid,'%02x ',g(i)); 
fprintf(fid,'%02x ',b(i)); 
end

bit_wide_conver代码如下所示,主要思想就是对串口传入的数据计数,计数最大值为2。计数器为0时,输入数据赋予中间24位数据最高的8位;为1时,数据赋予输出数据中间8位;为2时,赋予低8位。一个像素的赋值后,将中间变量24位数据赋予输出的RGB888 24位输出数据,并且输出一个数据标志信号。

module bit_wide_conver (
    input             sys_clk,
    input             sys_rst_n,
    input  [7:0]      pi_data,
    input             pi_flag,

    output reg        po_flag,
    output reg [23:0] po_data
);

reg [1:0]  cnt_byte;
reg [23:0] data;
reg        pi_flag_reg;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) cnt_byte <= 2'd0;
    else if(pi_flag == 1'b1 && cnt_byte == 2'd2) cnt_byte <= 2'd0;
    else if(pi_flag == 1'b1) cnt_byte <= cnt_byte + 1'b1;
    else cnt_byte <= cnt_byte;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) data <= 24'd0;
    else if(pi_flag == 1'b1) begin
        case(cnt_byte)
            2'd0:data[23:16] <= pi_data;
            2'd1:data[15:8]  <= pi_data;
            2'd2:data[7:0]   <= pi_data; 
            default:data <= 24'hffffff;
        endcase
    end
    else data <= data;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) pi_flag_reg <= 1'b0;
    else pi_flag_reg <= pi_flag;
end
    
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) po_data <= 24'd0;
    else if(pi_flag_reg == 1 && cnt_byte == 2'd0)
         po_data <= data;
    else po_data <= po_data;
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) po_flag <= 1'b0;
    else if(pi_flag_reg == 1 && cnt_byte == 2'd0)
         po_flag <= 1'b1;
    else po_flag <= 1'b0;
end

endmodule

其余模块代码虽说是本人一个一个字母敲上的,但都只在野火以及正点原子教程的思想修改而来,没什么原创性。

PS:有一说一,个人感觉野火讲的课程比正点原子好得多,只是野火Xilinx教程资料不足。

四、结果

最终PWM调光方案

aa8879a64bcd4d8ca49acfb6f9d6469a.gif

 

五、遇到的问题

(1)配置锁相环时一直报错,出错原因显示什么什么反馈,对FPGA原理不清楚就不会通透,报错原因根本就理解不了,得加强对FPGA。后面改成自动就好了。

(2)锁相环生成时钟正确,可是config_gen选择时钟输出时,时钟周期却错误,仔细观察发现输出时钟上升沿总是与50M系统时钟同步(33.3M输出时钟),这没道理。锁相环又设置半天没啥改变,突然脑子一激灵意识到选择输出是用的always语言,有问题,将锁相环生成时钟寄存了,导致输出时钟与系统时钟同步,应该变为always@(*)。

(3)串口发送数据位宽8位,一开始认为调试助手会将txt文件中16进制自动识别输出。例如acbc 11aa,会自动分成ac、bc、11、aa输出,然而并不是,所以MATLAB中将各通道依次写在txt文件中(之前是合成24位数据写入)。

(4)MATLAB报错打开文件过多,第一次遇见这问题,开始以为电脑太垃圾内存不够,自己看看发现原因是将fopen写在循环内部。我真是呆逼。

(5)关于串口发送数据,最先的想法是根据rs232的原理一次直接发送24位数据,这是可行的。打开串口调试软件发现根本选择不了一次发送24位。修改为一次发送8位数据,再将数据转换位24位。

(6)PWM调光,占空比设置为1/4、2/4、3/4、1屏幕亮度改变不明显,后面设置为1/8,2/8,3/8,4/8,1改变也不大。最终方案为0,4/16,7/16,8/16,1。此外,发现供电功率也会对调光效果产生影响,usb供电的效果比电源适配器供电的效果好。

六、总结

(1)对一些基本的知识掌握不够,比如FPGA原理、Xilinx的芯片详细等等。

(2)对Verilog掌握深度不够,后续要回顾相关书籍。相比初次学习Verilog语言,现今有更深的知识深度,回顾学习应该有新的收获。

(3)对Xilinx的开发流程有了一定了解,好耶!后续目标是摄像头采集图像数据到LCD or 显示器上显示。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值