基於UDP協議的網路攝像頭的關鍵問題解決及除錯過程

2022-07-04 19:21:09 字數 4177 閱讀 6278

該篇博文主要對「

基於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

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

因為test_out的反轉,這裡其實是隔一幀採一幀的結果。

採用狀態機之後,影象錯位的現象便得到解決,顯示效果如圖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...