最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

热议:zynq基于DMA的串口传图

来源:博客园


(资料图片)

小梅哥的这个ZYNQ开发板上的DDR3位于PS侧,PL侧想要使用DDR3作为缓存的话,得通过HP接口来与PS侧的DDR3控制进行通信。本次实验在小梅哥OV5640工程的基础上,通过修改VDMA的S2MM端的模块而来的。将VMDA的帧缓存区设为1,关闭帧同步的功能后,其实和DMA差不多。

一、需要自定义的ip核

这里列出的为自己写的IP核。小梅哥的工程里还用到了其它的自定义的IP核,这里就不列出了。

1、串口接收图像数据模块

该模块调用了之前写的串口8位接收模块,详情可点击查看。此外,本模块还调用16位宽、深度为1024的带数据计数的普通FIFO核该模块主要的思想就是将接收到的两个8位的数据拼接位1个16位的数据并存入FIFO中,当存入的数据达到LINE_LENGTH(800)的时候,在收到从接口的准备信号时一次性写入VMDA中,再通过VMDA将数据写到DDR3中。此外该模块在应用的时候要封装成带AXI4_Stream 接口的IP核,具体封装过程可网上找教程。

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: GDUT// Engineer: Lclone// // Create Date: 2023/02/07 20:38:34// Design Name: // Module Name: Img_Rx// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module Img_Rx#   (parameter RX_BAUD = 115200,     parameter CLK_FQC = 50_000_000,     parameter LINE_LENGTH = 800)    (     input             Uart_Rx,     //---------------------------     input             m_clk,     input             m_axis_aresetn,     output     [15:0] m_axis_tdata,     output reg        m_axis_tlast,     input             m_axis_tready,     output reg        m_axis_tvalid    );        wire [7:0]  Uart_Data;    wire        Rx_done;    reg         Rx_done_r;    reg         Rx_done_cnt;        reg  [15:0] Uart_Data_16;        wire [9:0]  fifo_data_count;    reg  [9:0]  out_data_count;        reg         m_axis_tvalid_r;    reg  [18:0] cnt_1ms;        always @(posedge m_clk) Rx_done_r <= Rx_done;    always @(posedge m_clk) m_axis_tvalid <= m_axis_tvalid_r;        always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            Uart_Data_16 <= 0;        else if(Rx_done == 1)            Uart_Data_16 <= {Uart_Data_16[7:0],Uart_Data};    end        always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            Rx_done_cnt <= 0;        else if(Rx_done == 1)            Rx_done_cnt <= Rx_done_cnt + 1"b1;        else            Rx_done_cnt <= Rx_done_cnt;    end        always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            m_axis_tvalid_r <= 0;        else if(m_axis_tready == 1 & fifo_data_count >= LINE_LENGTH)            m_axis_tvalid_r <= 1"b1;        else if(fifo_data_count <= 1)            m_axis_tvalid_r <= 0;        else            m_axis_tvalid_r <= m_axis_tvalid_r;    end        always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            out_data_count <= 0;        else if(out_data_count == LINE_LENGTH - 1)            out_data_count <= 0;        else if(m_axis_tvalid_r & m_axis_tready)            out_data_count <= out_data_count + 1"b1;        else            out_data_count <= out_data_count;    end        always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            m_axis_tlast <= 0;        else if(out_data_count == LINE_LENGTH - 1)            m_axis_tlast <= 1;        else            m_axis_tlast <= 0;    end       always @(posedge m_clk or negedge m_axis_aresetn) begin        if(m_axis_aresetn == 0)            cnt_1ms <= 0;        else if(cnt_1ms == 500000 - 1)            cnt_1ms <= 0;        else            cnt_1ms <= cnt_1ms + 1"b1;    end         uart_byte_rx   # (        .RX_BAUD   (RX_BAUD),        .CLK_FQC   (CLK_FQC))    uart_byte_rx_inst    (        .Clk        (m_clk),        .Rst_n      (m_axis_aresetn),        .Uart_rx    (Uart_Rx),        .Data       (Uart_Data),        .Rx_done    (Rx_done)    );        fifo_generator_0  fifo_generator_0_inst (        .clk(m_clk),                             // input wire clk        .srst(~m_axis_aresetn),                  // input wire srst        .din(Uart_Data_16),                      // input wire [15 : 0] din        .wr_en(~Rx_done_cnt & Rx_done_r),        // input wire wr_en        .rd_en(m_axis_tvalid_r & m_axis_tready), // input wire rd_en        .dout(m_axis_tdata),                     // output wire [15 : 0] dout        .full(),                                 // output wire full        .empty(),                                // output wire empty        .data_count(fifo_data_count)             // output wire [9 : 0] data_count);endmodule

2、模块仿真

(1)仿真激励

`timescale 1ns / 1psmodule rx_img_test();    reg clk_50m;initial clk_50m <= 1;always #10 clk_50m <= ~clk_50m;reg rst_n;initial begin    rst_n <= 0;    #200    rst_n <= 1;end   wire [15:0] m_axis_tdata;wire        m_axis_tlast;wire        m_axis_tready;wire        m_axis_tvalid;wire [15:0] out_axis_tdata;wire        out_axis_tlast;wire        out_axis_tready;wire        out_axis_tvalid;reg         Uart_Rx;reg  [ 7:0] Uart_Data;Img_Rx #(    .RX_BAUD(2_000_000),    .CLK_FQC(100_000_000),    .LINE_LENGTH(16)) Img_Rx_inst (  .Uart_Rx(Uart_Rx),                // input wire Uart_Rx  .m_clk(clk_50m),                    // input wire m_clk  .m_axis_aresetn(rst_n),  // input wire m_axis_aresetn  .m_axis_tdata(m_axis_tdata),      // output wire [15 : 0] m_axis_tdata  .m_axis_tlast(m_axis_tlast),      // output wire m_axis_tlast  .m_axis_tready(m_axis_tready),    // input wire m_axis_tready  .m_axis_tvalid(m_axis_tvalid)    // output wire m_axis_tvalid);    axis_data_fifo_0 axis_data_fifo_0_inst (  .s_axis_aresetn(rst_n),  // input wire s_axis_aresetn  .s_axis_aclk(clk_50m),        // input wire s_axis_aclk  .s_axis_tvalid(m_axis_tvalid),    // input wire s_axis_tvalid  .s_axis_tready(m_axis_tready),    // output wire s_axis_tready  .s_axis_tdata(m_axis_tdata),      // input wire [15 : 0] s_axis_tdata  .s_axis_tlast(m_axis_tlast),      // input wire s_axis_tlast  .m_axis_tvalid(out_axis_tvalid),    // output wire m_axis_tvalid  .m_axis_tready(out_axis_tready),    // input wire m_axis_tready  .m_axis_tdata(out_axis_tdata),      // output wire [15 : 0] m_axis_tdata  .m_axis_tlast(out_axis_tlast)      // output wire m_axis_tlast);initial begin    Uart_Rx <= 1;    Uart_Data <= 0;    #200    repeat (256) begin        data_deliver(Uart_Data);        Uart_Data = Uart_Data + 1;    end    $stop;endtask data_deliver;        input [7:0]test_data;        begin            Uart_Rx <= 1"b0;            #1000                         Uart_Rx <= test_data[0];            #1000                         Uart_Rx <= test_data[1];            #1000                       Uart_Rx <= test_data[2];            #1000                      Uart_Rx <= test_data[3];            #1000                     Uart_Rx <= test_data[4];            #1000                      Uart_Rx <= test_data[5];            #1000                     Uart_Rx <= test_data[6];            #1000                     Uart_Rx <= test_data[7];            #1000                       Uart_Rx <= 1"b1;            #1000;        endendtaskassign out_axis_tready = 1;endmodule

(2)仿真结果

可见该模块能够正确地将16个两字节的数据正确的输出,并在最后一个数据的位置基于一个tlast信号。

二、工程修改

打开小梅哥的ACZ7020的OV5640_LCD工程,然后将红框部分的模块删除,加入自定义的串口接收图像数据模块。并修改下列IP核的参数将频率修改为如下:将帧缓存区设为1Fsync Options选择None,关掉帧同步功能在约束文件中,加入串口的管脚约束在SDK中,将OV5640的初始化函数删除,将PS_IIC和OV5640库删除同时也将PS_IIC和OV5640库的路径删除掉然后就可以下载程序到开发板上了

三、上板验证

将程序下载进开发板,然后打开img2lcd软件,读取一个800*480大小的BMP文件,并按如下设置:然后在输出的文件中进行修改删除首行删除末尾符号使用软件的查找替换功能,将所有的0X删掉,并将","换为空格符,然后使用行操作里面的行合并去除掉每一行末尾的回车符。最后就得到传输的图像数据:打开友善串口调试助手,将图像数据复制进去,打开串口端口,设置好波特率,然后发送,确保TX发送了768000个字节,否则图像会错位;确保底下绿色的字显示的波特率为115200,否则数据无法正确传输。传输数据后,发现图像能够正确显示在LCD上实验成功。本随笔还有许多小细节没有给出,如果遇到问题,可以评论询问。

关键词: