該篇博文主要對「
基於udp協議的網路攝像頭的設計與實現」除錯過程遇到的問題進行說明,並闡述其解決過程。
硬體平台:diy_de2
軟體平台:quartus ii 9.0 + nios ii 9.0 + visual studio 2008
圖1 初始
上圖是初步搭建完成的網路攝像頭
的(1)有一半的色彩未完全顯示;
(2)顯示的部分呈斜體狀,有鋸齒;
(3)顯示的部分解析度降低為160*120,同(1);
(4)顯示的影象的起始位置並非一幀影象的開始,即影象錯位。
解決過程大致如下:
nios ii端測試**:
圖2 c#端顯示單色影象1
上述影象能夠驗證udp傳輸正確和c#端的顯示程式正確。
(2)其次,保證nios ii正常傳輸的基礎上,即不做剛才的改動,在quartus ii端壓縮子程式press_moudle模組中,直接設定特定資料,觀察c#端顯示效果,效果如圖3所示。
圖3 c#端顯示單色影象2
這張影象與圖1很相似,即有一半的色彩未正確顯示(因為是單色,其他的特徵不容易看出來)。根據圖2和圖3的對比,可以得知:影象資料在讀寫sram時出了問題。到底是讀sram還是寫sram的問題?
(3)再次,在nios ii端,往sram裡面寫特定資料,之後再讀取出來,最後通過網路傳輸給pc,pc端用c#顯示,通過這個測試,可以發現nios ii端讀sram沒有問題,因此,問題便可以確定為寫sram。
(4)影象錯位的問題可以定位為:開始往sram寫影象資料時,當前資料並非一幀影象的開始,即寫影象資料的條件不正確。為了能夠正確的鎖存住幀開始訊號,採用狀態機功能,關鍵**如下:
always@(posedge iclk or因為test_out的反轉,這裡其實是隔一幀採一幀的結果。negedge
rst_n)
begin
if(!rst_n)
test_out
<= 0
;
else
begin
if((niosii_cmd) && (oval_vs == 2
'b01))
begin
test_out
<= ~test_out;
//if(test_out)
//rgb_zuhe <= rgb_zuhe + 1;
end//
else
//test_out <= 0;
endend
always@(posedge iclk or
negedge
rst_n)
begin
if(!rst_n)
begin
//oaddress <= 0;
rd_en <= 0
; rgb_zuhe
<= 0
;
endelse
begin
case
(test_out)
0:begin
oaddress
<= 0
; rd_en
<= 0
; rgb_zuhe
<= 0
;
end1
:
begin
if(vga_x_count[0] && vga_y_count[0] &&oval_hs)
begin
//rgb_zuhe <= (rgb_zuhe + 1)%32;
rgb_zuhe <= ;
oaddress <= oaddress + 2
;
if(oaddress == 18
'h257fe)
begin
rd_en
<= 1
; oaddress
<= 0
;
endend
else
rd_en
<= 0
;
endendcase
endend
採用狀態機之後,影象錯位的現象便得到解決,顯示效果如圖4所示。
圖4 解決影象錯位的顯示效果
在quartus ii端的壓縮子程式press_moudle中,設定影象資料為+1遞增的資料,在網路抓包工具wireshark,收到的資料可以看出,資料是呈+2的形式遞增的,因此可以斷定,儲存的時候出現了問題。
剛開始,以為sram儲存的時候是隔乙個位址儲存乙個資料,後分析一下,實則不然。因為在nios ii讀取快取在sram中的資料的時候,是挨個位址讀取的,而讀出來的資料確實呈+2的關係,說明:實際寫入sram的時候還是挨個位址寫的,只是寫控制器端問題。
後查閱相關資料,16位資料的儲存器對應cpu時,位址線應左移一位,在系統的頂層檔案中,並沒有將位址線左移,因此,造成了解析度又一次的降低了1/4,解決辦法為,往sram儲存資料時,位址線每次+2即可(在第2步**中已有所體現)。顯示效果如圖5所示。
圖5 除錯完成解析度降低問題的效果
(1)開始一直以為c#端繪圖部分的問題,經c#端寫buffer資料顯示,並認真分析顯示效果後,確定繪圖沒有問題。下面是分析過程。採用單色遞增進行分析。
c#端寫buffer測試**:
for (int m = 0; m < num; m++)通過c#端除錯,可以得知num=1468,即734個畫素,按照320*240解析度來算,一包資料可以繪製2行94個畫素點,擷取細節圖(圖5的左上部分),如圖6所示。
圖6 c#端測試細節圖
由圖形可以看出,第一包資料剛好繪製了2行94個畫素點,且3行的起始部分均正確對應,即均從純黑色開始,說明造成影象傾斜的不是c#的問題。
(2)nios ii測試,同樣採用單色遞增的方式進行驗證,同樣分析前2行94個畫素點及以後的畫素點,發現第95和96個畫素點為非純黑色,而第97個畫素點才開始為純黑色。這說明95和96畫素點為其他的值,並非預期的畫素值。
(3)仔細分析,發現最後2個畫素點,即4個位元組為一包資料的校驗位。nios ii端傳送一包資料的最大值為1510-42-4=1464,前42個位元組為包頭,後4個位元組為校驗位。而c#端在繪製影象的時候是按照1468個位元組來繪製的,因此,繪製的效果是,每次錯位2個畫素點。在c#端繪製影象的時候需要將num-4。改正後的顯示效果如圖7所示。
圖7 顯示效果
(1)首先,nios ii一直往pc傳送資料,pc向nios ii傳送命令,nios ii能夠正確收到命令資料,但是在pc不傳送命令的時候,nios ii端仍會進入中斷服務函式,接收到空命令或者是未知的多餘命令,疑為pc會自動傳送命令?這裡的pc並非c#。
(2)nios ii等待pc命令,pc傳送命令,但是pc端的命令最多只能進入一次nios ii的中斷服務函式。
這個問題的本質其實就是pc和dm9000a互相傳送資料,其中,dm9000a是通過中斷的方式接收pc傳送下來的資料,但是dm9000a卻不能正常的接收到pc傳送到資料。測試好久,仍沒有好的效果,難道是dm9000a中斷處理機制的問題?
鑑於上述兩種均不理想的情況,系統採用另外一種解決辦法:
圖8 最終的顯示效果
基於UDP協議的網路攝像頭的設計與實現
硬體平台 diy de2 軟體平台 quartus ii 9.0 nios ii 9.0 visual studio 2008 圖1 系統整體框圖 採用博文 de2 tv例程的幾點說明 中分析的例程。該部分為了盡快驗證網路攝像頭的可行性,採用了有失真壓縮的方式,即隔一行採集一行,隔一列採集一列,並使...
基於TCP協議的網路攝像頭的設計與實現
基於tcp協議的網路攝像頭的設計與實現 基於tcp協議的網路攝像頭的設計大部分和博文 基於udp協議的網路攝像頭的設計與實現 相同,本篇博文採用的tcp協議棧為nichestack協議棧 同理,可使用lwip協議棧實現 協議分析及上位機設計可參考博文 基於nichestack協議棧的網路例程分析及客...
基於TCP協議的網路攝像頭的設計與實現
基於tcp協議的網路攝像頭的設計大部分和博文 基於udp協議的網路攝像頭的設計與實現 相同,本篇博文採用的tcp協議棧為nichestack協議棧 同理,可使用lwip協議棧實現 協議分析及上位機設計可參考博文 基於nichestack協議棧的網路例程分析及客戶端程式設計 二 實驗平台 硬體平台 d...