UART串口传图LCD显示----图像处理
UART串口傳圖LCD顯示----圖像處理
設計介紹
首先需要準備一個txt文本,里面存儲一個16進制200* 200的圖片數據,通過串口調試助手使用串口傳輸一個200* 200圖片,然后通過開發板上的480* 272LCD屏幕顯示此圖片(數據格式為RGB565)。本篇博客也是圖像處理的基礎篇,在此基礎上可以做一些圖像處理項目然后通過LCD屏幕觀察實驗效果。整體效果如下圖所示,因為圖片大小為200* 200而顯示屏為480* 272,所以剩余部分填充為黑色。
設計思路
通過串口接收模塊輸出的po_flag信號高電平作為寫使能,po_data信號作為寫數據,往lcd顯示模塊中的RAMIP核中寫入200*200個圖片數據,然后通過po_flag信號低電平作為讀使能從RAMIP核中讀出數據,通過LCD屏幕顯示(這里為了方便,寫使能和讀使能采用一個數據線的高低電平,要是不理解可以看一下RAMIP核的使用方法)。下圖為整體設計流程框圖。
工程生成rtl視圖如下所示。
具體設計步驟
下面代碼所實現的就是把一個500* 500RGB888格式圖片轉換為200* 200RGB332格式的圖片(數據位寬為8位)然后生成TXT文本,為什么要轉換成RGB332格式而不是RGB565格式的呢,因為怕麻煩哈哈,RGB332格式數據為8位,串口一字節就傳輸過去了,要是RGB565格式的數據為16位,需要串口傳輸兩個字節的數據然后進行拼接。在LCDdisplay模塊將串口輸出的RGB332格式得8位數據轉換成RGB565格式得16位數據然后傳遞給下一模塊。
500* 500RGB888轉換為200* 200RGB332代碼如下(不懂可以看注釋很詳細哈哈)
clc; clear; img = imread('cat.jpg'); i = imresize(img,[200,200]); %把500*500的圖片裁剪為200*200的圖片R1 = i(:,:,1); G1 = i(:,:,2); B1 = i(:,:,3); R2 = R1/32 - 1 ; %把8位的R分量數據按比例轉換為3位數據,以數據255為例255/32-1=6.968取整為7 G2 = G1/32 - 1 ; %把8位的G分量數據按比例轉換為3位數據 B2 = B1/64 - 1 ; %把8位的B分量數據按比例轉換為2位數據 b = uint8(zeros(200,200)); %產生一個大小200*200數據位寬為8位的全零矩陣b b = bitor(bitand(bitshift(R2, 5),224),b); %十進制 224 為二進制 1110 0000 %上一條語句執行的操作如下條注釋 %以R2的數據為7(二進制位111)為例 左移五位為1110_0000然后和28(二進制位1110_0000)相與然后再和0000_0000相或最后結果為1110_0000 b = bitor(bitand(bitshift(G2, 2),28),b); %十進制 28 為二進制 0001 1100 b = bitor(bitand(bitshift(B2, 0), 3),b); %十進制 3 為二進制 0000 0011fid=fopen('data_2.txt','w+'); %打開data_2.txt文件返回句柄 fprintf(fid,'%02x ',b') ; %將圖像轉置行列對換(默認matlab 是1列1列打印會導致圖像豎著的),向文件中寫入16進制字符數據兩個數據間加空格,為了串口發送做準備figure(1) subplot(1,3,1);imshow(img),title('原始圖像'); %顯示原始圖像500*500*3 subplot(1,3,2);imshow(i),title('裁剪后圖像'); %顯示裁剪后圖像200*200*3 subplot(1,3,3);imshow(b),title('修改后圖像'); %顯示裁剪后圖像200*200*1最后生成的TXT文本如下所示,其中就是8位的16進制圖像數據。(只截取了一部分)
串口輸出數據寫入LCDdisplay模塊的RAM中程序設計
這里就不一點點寫代碼了全部代碼可以上資源里下載免費的哦,思路就是使用串口輸出的po_flag信號的高電平作為RAM的寫使能,低電平作為RAM的讀使能。
寫地址部分代碼
//產生寫地址 always @(posedge clk_50 or negedge sys_rst_n) beginif (sys_rst_n == 1'b0) begin// resetaddra <= 'd0;endelse if (pi_flag == 1'b1 && addra == 'd39999) beginaddra <= 'd0;endelse if (pi_flag == 1'b1) beginaddra <= addra + 1'b1;end end讀地址部分代碼
//當前像素點坐標位于圖案顯示區域內時,讀RAM使能信號拉高 assign ram_rd_en = (pixel_xpos >= POS_X) && (pixel_xpos < POS_X + WIDTH)&& (pixel_ypos >= POS_Y) && (pixel_ypos < POS_Y + HEIGHT)? 1'b1 : 1'b0;//控制讀地址 always @(posedge s_clk or negedge sys_rst_n) begin if (!sys_rst_n) beginram_addr <= 16'd0;endelse if(ram_rd_en) beginif(ram_addr < TOTAL - 1'b1)ram_addr <= ram_addr + 1'b1; //每次讀ROM操作后,讀地址加1elseram_addr <= 1'b0; //讀到ROM末地址后,從首地址重新開始讀操作endelseram_addr <= ram_addr; endRGB332數據換為RGB565代碼
assign doutb_b = { doutb[7:5],2'b00,doutb[4:2],3'b000,doutb[1:0],3'b000} ;把8位doutb的RGB三個分量的數據分別對應到16位的doutb_b上不夠的位數補零
雖然這種方法還是有一些缺陷但是比價簡單后面會接著更新比較嚴謹的轉換方法
RGB565圖像數據輸出
//根據當前像素點坐標指定當前像素點顏色數據,在屏幕上顯示彩條 always @(posedge s_clk or negedge sys_rst_n) begin if (!sys_rst_n)pixel_data <= 16'd0;else beginif((pixel_xpos >= 10'd140) && (pixel_xpos <= 10'd339) && (pixel_ypos >= 10'd36) && (pixel_ypos <= 10'd235)) //顯示圖片區域 pixel_data <= doutb_b;else pixel_data <= BLACK; end end這里需要注意RAM讀出數據會落后地址一拍需要處理好從RAM中讀出數據的問題。
上板驗證
將data_2.txt文件中數據拷貝到串口調試助手然后發送,如下圖所示,點擊發送。
等一會觀察LCD顯示屏上就會出現一個200* 200的圖片了如下圖所示。哈哈 代碼可以私信我啊。
總結
以上是生活随笔為你收集整理的UART串口传图LCD显示----图像处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 伊滨区应急管理局领导莅临埃思特考察指导
- 下一篇: 最短公共超序列(最短公共父序列)