網(wǎng)上有很多關(guān)于pos機顯示202,正點原子開拓者FPGA開發(fā)板資料連載第38章 OV5640攝像頭顯示實驗的知識,也有很多人為大家解答關(guān)于pos機顯示202的問題,今天pos機之家(www.tjfsxbj.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機顯示202
1)實驗平臺:正點原子開拓者FPGA 開發(fā)板
2)摘自《開拓者FPGA開發(fā)指南》關(guān)注官方微信號公眾號,獲取更多資料:正點原子
3)全套實驗源碼+手冊+視頻下載地址:http://www.openedv.com/thread-13912-1-1.html
第三十八章 OV5640攝像頭RGB TFT-lcd顯示實驗
在OV5640攝像頭VGA顯示實驗中,我們成功地在VGA顯示器上實時顯示出了攝像頭采集的圖
像。本章我們將使用FPGA開發(fā)板實現(xiàn)對OV5640的數(shù)字圖像采集并通過RGB LCD液晶屏實時顯示。
本章包括以下幾個部分:
38.1 OV5640簡介
38.2 實驗任務(wù)
38.3 硬件設(shè)計
38.4 程序設(shè)計
38.5 下載驗證
OV5640簡介
我們在“OV5640攝像頭VGA顯示實驗”中對OV5640的視頻傳輸時序、SCCB協(xié)議以及寄存器
的配置信息等內(nèi)容作了詳細的介紹,如果大家對這部分內(nèi)容不是很熟悉的話,請參考“OV5640
攝像頭VGA顯示實驗”中的OV5640簡介部分。
實驗任務(wù)
本節(jié)實驗任務(wù)是使用開拓者開發(fā)板及OV5640攝像頭實現(xiàn)圖像采集,并通過正點原子推出的
RGBLCD液晶屏模塊實時顯示,支持4.3寸480*272、7寸800*480、7寸1024*600、10.1寸1280*800
這些尺寸/分辨率的屏幕。
硬件設(shè)計
攝像頭擴展接口原理圖及OV5640模塊說明與“OV5640攝像頭VGA顯示實驗”完全相同,請
參考“OV5640攝像頭VGA顯示實驗”硬件設(shè)計部分。RGB TFT-LCD接口部分的硬件設(shè)計請參考
“RGB TFT-LCD彩條顯示實驗”中的硬件設(shè)計部分。
由于OV5640、LCD接口和SDRAM引腳數(shù)目較多且在前面相應(yīng)的章節(jié)中已經(jīng)給出它們的管腳列
表,這里不再列出管腳分配。
程序設(shè)計
圖 38.4.1是根據(jù)本章實驗任務(wù)畫出的系統(tǒng)框圖。PLL時鐘模塊為I2C驅(qū)動模塊、LCD頂層模
塊以及SDRAM控制器模塊提供驅(qū)動時鐘;I2C驅(qū)動模塊和I2C配置模塊、圖像尺寸配置模塊用于
初始化OV5640圖像傳感器;攝像頭采集模塊負責(zé)采集攝像頭圖像數(shù)據(jù),并且把圖像數(shù)據(jù)寫入
SDRAM讀寫控制模塊;SDRAM讀寫控制模塊負責(zé)將用戶數(shù)據(jù)寫入和讀出片外SDRAM存儲器中;LCD
頂層模塊負責(zé)驅(qū)動RGB TFT-LCD顯示屏。
OV5640攝像頭RGB TFT-LCD顯示系統(tǒng)框圖如下圖所示:
圖 38.4.1 OV5640攝像頭RGB TFT-LCD顯示系統(tǒng)框圖
頂層模塊的原理圖如下圖所示:
圖 38.4.2 頂層模塊原理圖
由上圖可知,I2C配置模塊和I2C驅(qū)動模塊控制著傳感器初始化的開始與結(jié)束,傳感器初始
化完成后圖像采集模塊將采集到的數(shù)據(jù)寫入SDRAM讀寫控制模塊,LCD模塊從SDRAM控制模塊中
讀出數(shù)據(jù),完成了數(shù)據(jù)的采集、緩存與顯示。其中圖像數(shù)據(jù)采集模塊是在SDRAM和傳感器都初
始化完成之后才開始輸出數(shù)據(jù)的,避免了在SDRAM初始化過程中向里面寫入數(shù)據(jù)。
FPGA頂層模塊(ov5640_rgb565_lcd)例化了以下六個模塊:PLL時鐘模塊(pll_clk)、
I2C驅(qū)動模塊(i2c_dri)、I2C配置模塊(i2c_ov7725_rgb565_cfg)、攝像頭圖像采集模塊
(cmos_capture_data)、圖像尺寸配置模塊(picture_size)、SDRAM讀寫控制模塊(sdram_top)
和LCD頂層模塊(lcd)。
PLL時鐘模塊(pll_clk):PLL時鐘模塊通過調(diào)用鎖相環(huán)(PLL)IP核實現(xiàn),總共輸出3個
時鐘,頻率分別為100Mhz、100Mhz(SDRAM相位偏移時鐘)和100Mhz(LCD分頻用)時鐘。100Mhz
時鐘和100Mhz相位偏移時鐘作為SDRAM讀寫控制模塊的驅(qū)動時鐘,最后一個100Mhz時鐘作為LCD
頂層模塊的驅(qū)動時鐘。
I2C驅(qū)動模塊(i2c_dri):I2C驅(qū)動模塊負責(zé)驅(qū)動OV5640 SCCB接口總線,用戶可根據(jù)該模
塊提供的用戶接口對OV5640的寄存器進行配置,該模塊和“EEPROM讀寫實驗”章節(jié)中用到的
I2C驅(qū)動模塊為同一個模塊,有關(guān)該模塊的詳細介紹請大家參考“EEPROM讀寫實驗”章節(jié)。
I2C配置模塊(i2c_ov5640_rgb565_cfg):I2C配置模塊的驅(qū)動時鐘是由I2C驅(qū)動模塊輸出
的時鐘提供的,這樣方便了I2C驅(qū)動模塊和I2C配置模塊之間的數(shù)據(jù)交互。該模塊寄存需要配置
的寄存器地址、數(shù)據(jù)以及控制初始化的開始與結(jié)束,同時該模塊輸出OV5640的寄存器地址和數(shù)
據(jù)以及控制I2C驅(qū)動模塊開始執(zhí)行的控制信號,直接連接到I2C驅(qū)動模塊的用戶接口,從而完成
對OV5640傳感器的初始化。有關(guān)該模塊的詳細介紹請大家參考“OV5640攝像頭VGA顯示實驗”
章節(jié)。在本章節(jié)中對該模塊稍加了一些修改,我們會在后面進行講解。
攝像頭圖像采集模塊(cmos_capture_data):攝像頭采集模塊在像素時鐘的驅(qū)動下將傳
感器輸出的場同步信號、行同步信號以及8位數(shù)據(jù)轉(zhuǎn)換成SDRAM讀寫控制模塊的寫使能信號和16
位寫數(shù)據(jù)信號,完成對OV5640傳感器圖像的采集。OV7725和OV5640圖像輸出時序非常相似,有
關(guān)該模塊的詳細介紹請大家參考“OV7725攝像頭VGA顯示實驗”章節(jié)。
圖像尺寸配置模塊(picture_size):圖像尺寸配置模塊用于配置攝像頭輸出圖像尺寸的
大小,以及設(shè)置攝像頭輸出圖像的幀率(每秒輸出圖像的幀數(shù)),此外還完成了SDRAM的讀寫
結(jié)束地址設(shè)置。
SDRAM讀寫控制模塊(sdram_top):SDRAM讀寫控制器模塊負責(zé)驅(qū)動SDRAM片外存儲器,緩
存圖像傳感器輸出的圖像數(shù)據(jù)。該模塊將SDRAM復(fù)雜的讀寫操作封裝成類似FIFO的用戶接口,
非常方便用戶的使用。在“SDRAM讀寫測試實驗”的程序中,讀寫操作地址都是SDRAM的同一存儲空間,如果只使用一個存儲空間緩存圖像數(shù)據(jù),那么同一存儲空間中會出現(xiàn)兩幀圖像疊加的
情況,為了避免這一情況,我們在SDRAM的其它BANK中開辟一個相同大小的存儲空間,使用乒
乓操作的方式來寫入和讀取數(shù)據(jù),所以本次實驗在“SDRAM讀寫測試實驗”的程序里做了一個
小小的改動,有關(guān)該模塊的詳細介紹請大家參考“SDRAM讀寫測試實驗”章節(jié),修改部分請大
家參考“OV7725攝像頭VGA顯示實驗”章節(jié)。
LCD頂層模塊(lcd):LCD頂層模塊下例化了以下三個模塊:讀ID模塊(rd_id)、分頻模
塊(clk_div)、LCD驅(qū)動模塊(lcd_driver)。
讀ID模塊(rd_id):讀ID模塊用于讀取連接到開發(fā)板上的LCD的ID。
分頻模塊(clk_div):分頻模塊用于輸出驅(qū)動LCD所需要的時鐘。由于不同尺寸/分辨率
RGB LCD的驅(qū)動時鐘頻率是不一樣的,該模塊實現(xiàn)不同LCD的驅(qū)動時鐘適配。
LCD驅(qū)動模塊(lcd_driver):LCD驅(qū)動模塊負責(zé)驅(qū)動LCD液晶屏,該模塊通過讀取SDRAM讀
寫控制模塊來輸出像素數(shù)據(jù),本次實驗將LCD驅(qū)動模塊的內(nèi)部信號data_req(數(shù)據(jù)請求信號)
輸出至端口,方便從SDRAM控制器中讀取數(shù)據(jù)。有關(guān)LCD驅(qū)動模塊的詳細介紹請大家參考“RGB
TFT-LCD彩條顯示實驗”章節(jié)。
下面是頂層模塊中參數(shù)設(shè)置需要注意的地方,頂層模塊參數(shù)設(shè)置代碼如下:
55 //parameter define
56 parameter SLAVE_ADDR = 7'h3c ; //OV5640的器件地址7'h3c
57 parameter BIT_CTRL = 1'b1 ; //OV5640的字節(jié)地址為16位 0:8位 1:16位
58 parameter CLK_FREQ = 27'd100_000_000; //i2c_dri模塊的驅(qū)動時鐘頻率 100MHz
59 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL時鐘頻率,不超過400KHz
在代碼的第56行定義了OV5640的器件地址,其器件地址為7’h3c;第58行定義了寄存器地
址的位寬,BIT_CTRL=0表示地址位寬為8位,BIT_CTRL=1表示地址位寬為16位。因為OV5640的
地址位寬為16位,所以BIT_CTRL設(shè)置為1。
下面是頂層模塊里鎖相環(huán)例化部分:
82 //鎖相環(huán)
83 pll u_pll(
84 .areset (~sys_rst_n),
85 .inclk0 (sys_clk),
86 .c0 (clk_100m),
87 .c1 (clk_100m_shift),
88 .c2 (clk_100m_lcd),
89 .locked (locked)
90 );
在代碼的第88行輸出了一個100Mhz的時鐘clk_100m_lcd,作為LCD頂層模塊(lcd)和I2C
驅(qū)動模塊(i2c_dri)的驅(qū)動時鐘。
為了適配現(xiàn)有的RGB LCD屏幕,我們對I2C配置模塊的端口部分進行了修改:
92 //I2C配置模塊
93 i2c_ov5640_rgb565_cfg u_i2c_cfg(
94 .clk (i2c_dri_clk),
95 .rst_n (rst_n),
96 .i2c_done (i2c_done),
97 .i2c_exec (i2c_exec),
98 .i2c_data (i2c_data),
99 .i2c_rh_wl (i2c_rh_wl), //I2C讀寫控制信號
100 .i2c_data_r (i2c_data_r),
101 .init_done (cam_init_done),
102 .cmos_h_pixel (cmos_h_pixel), //CMOS水平方向像素個數(shù)
103 .cmos_v_pixel (cmos_v_pixel) , //CMOS垂直方向像素個數(shù)
104 .total_h_pixel (total_h_pixel), //水平總像素大小
105 .total_v_pixel (total_v_pixel) //垂直總像素大小
106 );
在“OV5640攝像頭VGA顯示實驗”中,cmos_h_pixel、cmos_v_pixel是通過參數(shù)傳遞的方
式將數(shù)值傳遞給I2C配置模塊。在本實驗中,這兩個配置需要依據(jù)LCD尺寸的大小而改變。此外,
total_h_pixel及total_v_pixel的參數(shù)也需要進行配置,它們會影響到輸出圖像的幀率。所以,
在代碼的第102行至代碼的105行,我們添加了4個端口,用于根據(jù)LCD的尺寸大小適配攝像頭輸
出圖像的尺寸及幀率。
在頂層模塊中例化了圖像尺寸配置模塊(picture_size),它輸出了上一段提到的四個變
量的具體數(shù)值:
145 //攝像頭圖像分辨率設(shè)置模塊
146 picture_size u_picture_size (
147 .rst_n (rst_n ),
148
149 .ID_lcd (ID_lcd ), //LCD的ID,用于配置攝像頭的圖像大小
150
151 .cmos_h_pixel (cmos_h_pixel ), //CMOS水平方向像素個數(shù)
152 .cmos_v_pixel (cmos_v_pixel ), //CMOS垂直方向像素個數(shù)
153 .total_h_pixel (total_h_pixel ), //用于配置HTS寄存器
154 .total_v_pixel (total_v_pixel ), //用于配置VTS寄存器
155 .sdram_max_addr (sdram_max_addr) //sdram讀寫的最大地址
156 );
模塊內(nèi)部的代碼如下:
1 module picture_size (
2 input rst_n ,
3
4 input [15:0] ID_lcd ,
5
6 output reg [12:0] cmos_h_pixel,
7 output reg [12:0] cmos_v_pixel,
8 output reg [12:0] total_h_pixel,
9 output reg [12:0] total_v_pixel,
10 output reg [23:0] sdram_max_addr
11 );
12
13 //parameter define
14 parameter ID_4342 = 0;
15 parameter ID_7084 = 1;
16 parameter ID_7016 = 2;
17 parameter ID_1018 = 5;
18
19 //*****************************************************
20 //** main code
21 //*****************************************************
22
23 //配置攝像頭輸出圖像的尺寸大小
24 always @(*) begin
25 case(ID_lcd )
26 ID_4342 : begin
27 cmos_h_pixel = 13'd480;
28 cmos_v_pixel = 13'd272;
29 sdram_max_addr =23'd130560;
30 end
31 ID_7084 : begin
32 cmos_h_pixel = 13'd800;
33 cmos_v_pixel = 13'd480;
34 sdram_max_addr =23'd384000;
35 end
36 ID_7016 : begin
37 cmos_h_pixel = 13'd1024;
38 cmos_v_pixel = 13'd600;
39 sdram_max_addr =23'd614400;
40 end
41 ID_1018 : begin
42 cmos_h_pixel = 13'd1280;
43 cmos_v_pixel = 13'd800;
44 sdram_max_addr =23'd1024000;
45 end
46 default : begin
47 cmos_h_pixel = 13'd480;
48 cmos_v_pixel = 13'd272;
49 sdram_max_addr =23'd130560;
50 end
51 endcase
52 end
53
54 //對HTS及VTS的配置會影響攝像頭輸出圖像的幀率
55 always @(*) begin
56 case(ID_lcd)
57 ID_4342 : begin
58 total_h_pixel = 13'd1800;
59 total_v_pixel = 13'd1000;
60 end
61 ID_7084 : begin
62 total_h_pixel = 13'd1800;
63 total_v_pixel = 13'd1000;
64 end
65 ID_7016 : begin
66 total_h_pixel = 13'd2200;
67 total_v_pixel = 13'd1000;
68 end
69 ID_1018 : begin
70 total_h_pixel = 13'd2570;
71 total_v_pixel = 13'd980;
72 end
73 default : begin
74 total_h_pixel = 13'd1800;
75 total_v_pixel = 13'd1000;
76 end
77 endcase
78 end
79
80 endmodule
我們通過組合邏輯對變量進行賦值,在代碼的第24至第59行,對攝像頭輸出圖像尺寸相關(guān)
的參數(shù)(cmos_h_pixel、cmos_v_pixel)進行了配置。同時還配置了一幀圖像在SDRAM里的結(jié)
束緩存地址sdram_max_addr,它是cmos_h_pixel、cmos_v_pixel的乘積。
在代碼的61至93行,對影響幀率的參數(shù)total_h_pixel、total_v_pixel進行了配置。
在頂層代碼例化SDRAM頂層模塊的170和179行,我們進行了修改。如下所示,SDRAM頂層模
塊的wr_max_addr與rd_max_addr端口和sdram_max_addr信號直連。
158 //SDRAM 控制器頂層模塊,封裝成FIFO接口
159 //SDRAM 控制器地址組成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
160 sdram_top u_sdram_top(
161 .ref_clk (clk_100m), //sdram 控制器參考時鐘
162 .out_clk (clk_100m_shift), //用于輸出的相位偏移時鐘
163 .rst_n (rst_n), //系統(tǒng)復(fù)位
164
165 //用戶寫端口
166 .wr_clk (cam_pclk), //寫端口FIFO: 寫時鐘
167 .wr_en (wr_en), //寫端口FIFO: 寫使能
168 .wr_data (wr_data), //寫端口FIFO: 寫數(shù)據(jù)
169 .wr_min_addr (24'd0), //寫SDRAM的起始地址
170 .wr_max_addr (sdram_max_addr), //寫SDRAM的結(jié)束地址
171 .wr_len (10'd512), //寫SDRAM時的數(shù)據(jù)突發(fā)長度
172 .wr_load (~rst_n), //寫端口復(fù)位: 復(fù)位寫地址,清空寫FIFO
173
174 //用戶讀端口
175 .rd_clk (clk_lcd), //讀端口FIFO: 讀時鐘
176 .rd_en (rd_en), //讀端口FIFO: 讀使能
177 .rd_data (rd_data), //讀端口FIFO: 讀數(shù)據(jù)
178 .rd_min_addr (24'd0), //讀SDRAM的起始地址
179 .rd_max_addr (sdram_max_addr), //讀SDRAM的結(jié)束地址
180 .rd_len (10'd512), //從SDRAM中讀數(shù)據(jù)時的突發(fā)長度
181 .rd_load (~rst_n), //讀端口復(fù)位: 復(fù)位讀地址,清空讀FIFO
在頂層模塊代碼的最后,例化了LCD頂層模塊(lcd),如下所示:
201 //例化LCD頂層模塊
202 lcd u_lcd(
203 .clk (clk_100m_lcd),
204 .rst_n (rst_n),
205
206 .lcd_hs (lcd_hs),
207 .lcd_vs (lcd_vs),
208 .lcd_de (lcd_de),
209 .lcd_rgb (lcd_rgb),
210 .lcd_bl (lcd_bl),
211 .lcd_rst (lcd_rst),
212 .lcd_pclk (lcd_pclk),
213
214 .clk_lcd (clk_lcd),
215
216 .pixel_data (rd_data),
217 .rd_en (rd_en),
218
219 .ID_lcd (ID_lcd)
220 );
LCD頂層模塊里例化了讀ID模塊(rd_id)、分頻模塊(clk_div)、LCD驅(qū)動模塊(lcd_driver),
如下所示:
1 module lcd(
2 input clk ,
3 input rst_n ,
4 //RGB LCD接口
5 output lcd_hs , //LCD 行同步信號
6 output lcd_vs , //LCD 場同步信號
7 output lcd_de , //LCD 數(shù)據(jù)輸入使能
8 inout [15:0] lcd_rgb , //LCD RGB565顏色數(shù)據(jù)
9 output lcd_bl , //LCD 背光控制信號
10 output lcd_rst , //LCD 復(fù)位信號
11 output lcd_pclk, //LCD 采樣時鐘
12
13 output clk_lcd,
14 input [15:0] pixel_data, //像素點數(shù)據(jù)
15 output rd_en , //請求像素點顏色數(shù)據(jù)輸入
16
17 output [15:0] ID_lcd //LCD的ID
18 );
19
20 //*****************************************************
21 //** main code
22 //*****************************************************
23
24 //RGB565數(shù)據(jù)輸出
25 assign lcd_rgb = lcd_de ? pixel_data : 16'dz;
26
27 //讀rgb lcd ID 模塊
28 rd_id u_rd_id(
29 .clk (clk),
30 .rst_n (rst_n),
31 .lcd_rgb (lcd_rgb),
32 .ID_lcd (ID_lcd)
33
34 );
35
36 //分頻模塊,根據(jù)不同的LCD ID輸出相應(yīng)的頻率的驅(qū)動時鐘
37 clk_div u_clk_div(
38 .clk (clk),
39 .rst_n (rst_n),
40 .ID_lcd (ID_lcd),
41 .clk_lcd (clk_lcd)
42 );
43
44 //lcd驅(qū)動模塊
45 lcd_driver u_lcd_driver(
46 .lcd_clk (clk_lcd),
47 .sys_rst_n (rst_n),
48
49 .lcd_hs (lcd_hs),
50 .lcd_vs (lcd_vs),
51 .lcd_de (lcd_de),
52 .lcd_bl (lcd_bl),
53 .lcd_rst (lcd_rst),
54 .lcd_pclk (lcd_pclk),
55
56 .data_req (rd_en), //請求像素點顏色數(shù)據(jù)輸入
57 .pixel_xpos (),
58 .pixel_ypos (),
59 .ID_lcd (ID_lcd)
60 );
61
62 endmodule
在代碼的第25行,當(dāng)lcd_de信號為高電平時,即像素數(shù)據(jù)有效的時候,輸出pixel_data信
號給lcd_rgb。當(dāng)lcd_de信號為低電平時,給lcd_rgb信號賦值為高阻態(tài)。我們就是在當(dāng)lcd_rgb
信號高阻態(tài)的時候,讀取LCD的ID。讀ID模塊的代碼如下:
1 module rd_id(
2 input clk ,
3 input rst_n ,
4 input [15:0] lcd_rgb, //像素點數(shù)據(jù)
5
6 output reg [15:0] ID_lcd
7 );
8
9 //reg define
10 reg ID_rd_en;
11
12 //*****************************************************
13 //** main code
14 //*****************************************************
15
16 //通過讀r、g、b信號的最高位來獲取LCD的ID
17 always @(posedge clk or negedge rst_n) begin
18 if (!rst_n) begin
19 ID_lcd <= 16'd5;
20 ID_rd_en <= 1'b0;
21 end
22 else if(!ID_rd_en) begin
23 ID_lcd <= {13'b0,lcd_rgb[4],lcd_rgb[10],lcd_rgb[15]};
24 ID_rd_en <= 1'b1;
25 end
26 else
27 ID_lcd <= ID_lcd;
28 end
29
30 endmodule
代碼的第17行至28行實現(xiàn)了讀取LCD ID的操作,在復(fù)位信號拉高后讀取一次ID。
在前面,我們提到過不同尺寸的LCD所需的驅(qū)動時鐘頻率是不一樣的。比如4.3寸LCD需要
9MHz的時鐘,
7寸800*480分辨率的LCD需要33.3MHz的時鐘,7寸1024*600分辨率的LCD需要50MHz
的時鐘,10.1寸LCD需要70MHz的時鐘。為了適配不同尺寸/分辨率的LCD,就需要輸出相應(yīng)的驅(qū)
動時鐘。分頻模塊的代碼如下:
1 module clk_div(
2 input clk ,
3 input rst_n ,
4 input [15:0] ID_lcd , //LCD的ID
5 output reg clk_lcd //驅(qū)動LCD的時鐘
6
7 );
8
9 //parameter define
10 parameter ID_4342 = 0;
11 parameter ID_7084 = 1;
12 parameter ID_7016 = 2;
13 parameter ID_1018 = 5;
14
15 //wire define
16 wire clk_33m;
17
18 //reg define
19 reg [1:0] state_33m_0;
20 reg [1:0] state_33m_1;
21 reg [2:0] cnt_10m;
22 reg clk_50m;
23 reg clk_10m;
24
25 //*****************************************************
26 //** main code
27 //*****************************************************
28
29 //50m hz時鐘分頻
30 always @ (posedge clk or negedge rst_n) begin
31 if(!rst_n)
32 clk_50m <= 1'b0;
33 else
34 clk_50m <= ~ clk_50m ;
35 end
36
37 //33.3m hz時鐘分頻
38 always @ (posedge clk ) begin
39 case (state_33m_0)
40 2'b00 : state_33m_0 <= 2'b1;
41 2'b01 : state_33m_0 <= 2'b10;
42 2'b10 : state_33m_0 <= 2'b0;
43 default : state_33m_0 <= 2'b0;
44 endcase
45 end
46
47 always @ (negedge clk ) begin
48 case (state_33m_1)
49 2'b00 : state_33m_1 <= 2'b01;
50 2'b01 : state_33m_1 <= 2'b10;
51 2'b10 : state_33m_1 <= 2'b0;
52 default : state_33m_1 <= 2'b0;
53 endcase
54 end
55
56 assign clk_33m = state_33m_0[1] | state_33m_1[1];
57
58 //10m hz時鐘分頻
59 always @ (posedge clk or negedge rst_n) begin
60 if(!rst_n)
61 cnt_10m <= 3'd0;
62 else if(cnt_10m == 3'd4)
63 cnt_10m <= 3'd0;
64 else
65 cnt_10m <= cnt_10m + 1'b1;
66 end
67
68 always @ (posedge clk or negedge rst_n) begin
69 if(!rst_n)
70 clk_10m <= 1'b0;
71 else if(cnt_10m == 3'd4)
72 clk_10m <= ~ clk_10m;
73 else
74 clk_10m <= clk_10m;
75 end
76
77 //選擇輸出的時鐘
78 always @ ( * ) begin
79 case(ID_lcd)
80 ID_4342 : clk_lcd = clk_10m;
81 ID_7084 : clk_lcd = clk_33m;
82 ID_7016 : clk_lcd = clk_50m;
83 ID_1018 : clk_lcd = clk_50m;
84 default : clk_lcd = clk_10m;
85 endcase
86 end
87
88 endmodule
我們決定把100MHz的輸入時鐘分頻為10MHz、33.3MHz、50Mhz這三個頻率的時鐘。7寸1024*600分辨率的LCD和10.1寸的LCD共用50MHz的時鐘。在代碼的第78至90行,根據(jù)LCD的ID選
取合適頻率的時鐘輸出。
仿真的結(jié)果如下所示:
圖 38.4.3 分頻模塊仿真結(jié)果圖
為了能夠驅(qū)動不同的LCD,LCD驅(qū)動模塊也需要進行適當(dāng)?shù)男薷模?/p>
1 module lcd_driver(
2 input lcd_clk, //lcd模塊驅(qū)動時鐘
3 input sys_rst_n, //復(fù)位信號
4 //RGB LCD接口
5 output lcd_hs, //LCD 行同步信號
6 output lcd_vs, //LCD 場同步信號
7 output lcd_de, //LCD 數(shù)據(jù)輸入使能
8 output lcd_bl, //LCD 背光控制信號
9 output lcd_rst, //LCD 復(fù)位信號
10 output lcd_pclk, //LCD 采樣時鐘
11
12 output data_req , //請求像素點顏色數(shù)據(jù)輸入
13 output [10:0] pixel_xpos, //像素點橫坐標
14 output [10:0] pixel_ypos, //像素點縱坐標
15 input [15:0] ID_lcd //LCD的ID
16 );
17
18 //parameter define
19 // 4.3' 480*272
20 parameter H_SYNC_4342 = 11'd41; //行同步
21 parameter H_BACK_4342 = 11'd2; //行顯示后沿
22 parameter H_DISP_4342 = 11'd480; //行有效數(shù)據(jù)
23 parameter H_FRONT_4342 = 11'd2; //行顯示前沿
24 parameter H_TOTAL_4342 = 11'd525; //行掃描周期
25
26 parameter V_SYNC_4342 = 11'd10; //場同步
27 parameter V_BACK_4342 = 11'd2; //場顯示后沿
28 parameter V_DISP_4342 = 11'd272; //場有效數(shù)據(jù)
29 parameter V_FRONT_4342 = 11'd2; //場顯示前沿
30 parameter V_TOTAL_4342 = 11'd286; //場掃描周期
31
32 // 7' 800*480
33 parameter H_SYNC_7084 = 11'd128; //行同步
34 parameter H_BACK_7084 = 11'd88; //行顯示后沿
35 parameter H_DISP_7084 = 11'd800; //行有效數(shù)據(jù)
36 parameter H_FRONT_7084 = 11'd40; //行顯示前沿
37 parameter H_TOTAL_7084 = 11'd1056; //行掃描周期
38
39 parameter V_SYNC_7084 = 11'd2; //場同步
40 parameter V_BACK_7084 = 11'd33; //場顯示后沿
41 parameter V_DISP_7084 = 11'd480; //場有效數(shù)據(jù)
42 parameter V_FRONT_7084 = 11'd10; //場顯示前沿
43 parameter V_TOTAL_7084 = 11'd525; //場掃描周期
44
45 // 7' 1024*600
46 parameter H_SYNC_7016 = 11'd20; //行同步
47 parameter H_BACK_7016 = 11'd140; //行顯示后沿
48 parameter H_DISP_7016 = 11'd1024; //行有效數(shù)據(jù)
49 parameter H_FRONT_7016 = 11'd160; //行顯示前沿
50 parameter H_TOTAL_7016 = 11'd1344; //行掃描周期
51
52 parameter V_SYNC_7016 = 11'd3; //場同步
53 parameter V_BACK_7016 = 11'd20; //場顯示后沿
54 parameter V_DISP_7016 = 11'd600; //場有效數(shù)據(jù)
55 parameter V_FRONT_7016 = 11'd12; //場顯示前沿
56 parameter V_TOTAL_7016 = 11'd635; //場掃描周期
57
58 // 10.1' 1280*800
59 parameter H_SYNC_1018 = 11'd10; //行同步
60 parameter H_BACK_1018 = 11'd80; //行顯示后沿
61 parameter H_DISP_1018 = 11'd1280; //行有效數(shù)據(jù)
62 parameter H_FRONT_1018 = 11'd70; //行顯示前沿
63 parameter H_TOTAL_1018 = 11'd1440; //行掃描周期
64
65 parameter V_SYNC_1018 = 11'd3; //場同步
66 parameter V_BACK_1018 = 11'd10; //場顯示后沿
67 parameter V_DISP_1018 = 11'd800; //場有效數(shù)據(jù)
68 parameter V_FRONT_1018 = 11'd10; //場顯示前沿
69 parameter V_TOTAL_1018 = 11'd823; //場掃描周期
70
71 //LCD的ID
72 parameter ID_4342 = 0;
73 parameter ID_7084 = 1;
74 parameter ID_7016 = 2;
75 parameter ID_1018 = 5;
76
77 //reg define
78 reg [10:0] cnt_h;
79 reg [10:0] cnt_v;
80 reg [10:0] h_sync ;
81 reg [10:0] h_back ;
82 reg [10:0] h_disp ;
83 reg [10:0] h_total;
84 reg [10:0] v_sync ;
85 reg [10:0] v_back ;
86 reg [10:0] v_disp ;
87 reg [10:0] v_total;
88
89 //wire define
90 wire lcd_en;
91
92 //*****************************************************
93 //** main code
94 //*****************************************************
95 assign lcd_bl = 1'b1; //RGB LCD顯示模塊背光控制信號
96 assign lcd_rst = 1'b1; //RGB LCD顯示模塊系統(tǒng)復(fù)位信號
97 assign lcd_pclk = lcd_clk; //RGB LCD顯示模塊采樣時鐘
98
99 //RGB LCD 采用數(shù)據(jù)輸入使能信號同步時,行場同步信號需要拉高
100 assign lcd_de = lcd_en; //LCD輸入的顏色數(shù)據(jù)采用數(shù)據(jù)輸入使能信號同步
101 assign lcd_hs = 1'b1;
102 assign lcd_vs = 1'b1;
103
104 //使能RGB565數(shù)據(jù)輸出
105 assign lcd_en = (((cnt_h >= h_sync+h_back) && (cnt_h < h_sync+h_back+h_disp))
106 &&((cnt_v >= v_sync+v_back) && (cnt_v < v_sync+v_back+v_disp)))
107 ? 1'b1 : 1'b0;
108
109 //請求像素點顏色數(shù)據(jù)輸入
110 assign data_req = (((cnt_h >= h_sync+h_back-1'b1) && (cnt_h < h_sync+h_back+h_disp-1'b1))
111 && ((cnt_v >= v_sync+v_back) && (cnt_v < v_sync+v_back+v_disp)))
112 ? 1'b1 : 1'b0;
113
114 //像素點坐標
115 assign pixel_xpos = data_req ? (cnt_h - (h_sync + h_back - 1'b1)) : 11'd0;
116 assign pixel_ypos = data_req ? (cnt_v - (v_sync + v_back - 1'b1)) : 11'd0;
117
118 //行場時序參數(shù)
119 always @(*) begin
120 case(ID_lcd)
121 ID_4342 : begin
122 h_sync = H_SYNC_4342;
123 h_back = H_BACK_4342;
124 h_disp = H_DISP_4342;
125 h_total = H_TOTAL_4342;
126 v_sync = V_SYNC_4342;
127 v_back = V_BACK_4342;
128 v_disp = V_DISP_4342;
129 v_total = V_TOTAL_4342;
130 end
131 ID_7084 : begin
132 h_sync = H_SYNC_7084;
133 h_back = H_BACK_7084;
134 h_disp = H_DISP_7084;
135 h_total = H_TOTAL_7084;
136 v_sync = V_SYNC_7084;
137 v_back = V_BACK_7084;
138 v_disp = V_DISP_7084;
139 v_total = V_TOTAL_7084;
140 end
141 ID_7016 : begin
142 h_sync = H_SYNC_7016;
143 h_back = H_BACK_7016;
144 h_disp = H_DISP_7016;
145 h_total = H_TOTAL_7016;
146 v_sync = V_SYNC_7016;
147 v_back = V_BACK_7016;
148 v_disp = V_DISP_7016;
149 v_total = V_TOTAL_7016;
150 end
151 ID_1018 : begin
152 h_sync = H_SYNC_1018;
153 h_back = H_BACK_1018;
154 h_disp = H_DISP_1018;
155 h_total = H_TOTAL_1018;
156 v_sync = V_SYNC_1018;
157 v_back = V_BACK_1018;
158 v_disp = V_DISP_1018;
159 v_total = V_TOTAL_1018;
160 end
161 default : begin
162 h_sync = H_SYNC_4342;
163 h_back = H_BACK_4342;
164 h_disp = H_DISP_4342;
165 h_total = H_TOTAL_4342;
166 v_sync = V_SYNC_4342;
167 v_back = V_BACK_4342;
168 v_disp = V_DISP_4342;
169 v_total = V_TOTAL_4342;
170 end
171 endcase
172 end
173
174 //行計數(shù)器對像素時鐘計數(shù)
175 always @(posedge lcd_clk or negedge sys_rst_n) begin
176 if (!sys_rst_n)
177 cnt_h <= 11'd0;
178 else begin
179 if(cnt_h < h_total - 1'b1)
180 cnt_h <= cnt_h + 1'b1;
181 else
182 cnt_h <= 11'd0;
183 end
184 end
185
186 //場計數(shù)器對行計數(shù)
187 always @(posedge lcd_clk or negedge sys_rst_n) begin
188 if (!sys_rst_n)
189 cnt_v <= 11'd0;
190 else if(cnt_h == h_total - 1'b1) begin
191 if(cnt_v < v_total - 1'b1)
192 cnt_v <= cnt_v + 1'b1;
193 else
194 cnt_v <= 11'd0;
195 end
196 end
197
198 endmodule
在代碼的第20至70行,定義了四種RGB LCD屏的時序參數(shù)。在代碼的第120行至第185行,
根據(jù)LCD的ID對參數(shù)變量進行賦值。
本章實驗程序設(shè)計與“OV5640攝像頭VGA顯示實驗”比較近似,除了例舉出來的部分,其
余模塊(除PLL時鐘模塊外)完全相同。有關(guān)本章實驗的詳細設(shè)計詳情請大家參考“OV5640攝
像頭VGA顯示實驗”章節(jié)。
下載驗證
首先我們打開OV5640攝像頭RGB TFT-LCD顯示實驗工程,在工程所在的路徑下打開
ov5640_rgb565_lcd/par文件夾,在里面找到“ov5640_rgb565_lcd.qpf”并雙擊打開。注意工
程所在的路徑名只能由字母、數(shù)字以及下劃線組成,不能出現(xiàn)中文、空格以及特殊字符等。工
程打開后如圖 38.5.1所示:
圖 38.5.1 OV5640攝像頭RGB TFT-LCD顯示實驗工程
然后將OV5640攝像頭插入開發(fā)板上的攝像頭擴展接口(注意攝像頭鏡頭朝外);將FPC 排
線一端與ALIENTEK的RGB接口模塊上的J1接口連接,另一端與開拓者開發(fā)板上的J1接口連接;
連接時,先掀開FPC連接器上的黑色翻蓋,將FPC排線藍色面朝上插入連接器,最后將黑色翻蓋
壓下以固定FPC排線。
最后將下載器一端連電腦,另一端與開發(fā)板上的JTAG端口連接,連接電源線并打開電源開
關(guān)。
接下來我們下載程序,驗證OV5640攝像頭RGB TFT-LCD實時顯示功能。
工程打開后通過點擊工具欄中的“Programmer”圖標打開下載界面,通過“Add File”按
鈕選擇ov5640_rgb565_lcd/par/output_files目錄下的“ov5640_rgb565_lcd.sof”文件。開
發(fā)板電源打開后,在程序下載界面點擊“Hardware Setup”,在彈出的對話框中選擇當(dāng)前的硬
件連接為“USB-Blaster[USB-0]”。然后點擊“Start”將工程編譯完成后得到的sof文件下載
到開發(fā)板中,如圖 38.5.所示:
圖 38.5.2 程序下載完成界面
下載完成后觀察顯示器的顯示圖像如圖 38.5.所示,說明OV5640攝像頭LCD顯示程序下載
驗證成功。
圖 38.5.3 RGB TFT-LCD實時顯示圖像
以上就是關(guān)于pos機顯示202,正點原子開拓者FPGA開發(fā)板資料連載第38章 OV5640攝像頭顯示實驗的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機顯示202的知識,希望能夠幫助到大家!
