1. 程式人生 > >基於STM32的OV7670攝像頭總結

基於STM32的OV7670攝像頭總結

一、OV7670模組:
     介紹一下OV7670感測器:CMOS器件;標準的SCCB介面,相容IIC介面;內建感光陣列,時序發生器,AD轉換器,模擬訊號處理,數字訊號處理器.....
     大致工作過程:光照射到
感光陣列產生相應電荷,傳輸到相應的模擬訊號處理單元,再由AD轉換為數字訊號,在經由數字訊號處理器插值到RGB訊號,最後傳輸到螢幕上......

     先了解一下基礎知識:現在市面上的OV7670模組分兩種:1、帶FIFO晶片;2、不帶FIFO晶片。當然帶FIFO的要貴一點~下面介紹帶FIFO和不帶FIFO的工作原理:


圖1:不帶FIFO


圖2:帶FIFO

下面就講解這兩種方式的適用範圍:

  • 不帶FIFO:這種方法最簡單,最直接,但是最不好實現的方法,原因是多數的CMOS晶片(如OV7670)的時鐘速度可以高達24M,一般微控制器的IO口速度根本達不到(stm32的IO速度,暫存器比庫函式快,博主之前測,用庫函式IO口速度好像是2.5Mhz,而用暫存器IO口速度是8M吧,速度相差較大~)。當然,高階的MCU,如ARM9以上或者DSP影象處理晶片等,本身處理速度快,記憶體大而且有的還帶camera介面,可以不用帶FIFO。主要是人家價格也高啊~
  • 但也不是不是完全沒有辦法在低速上實現採集,方法也很簡單,那麼就是降低CMOS 的輸出速度,不過這需要靠外部的晶振和內部的PLL 電路以及畫素時鐘速度,幀速等多個暫存器共同設定,並且要和MCU 的IO 速度匹配才可實現。但不建議這麼做,原因是:這種暫存器設定將帶來更多的學習困難和理解困難,並導致硬體影象的採集速度可能下降到0.5 幀以下,同時帶來影象失真的可能。
  • 還有一種方法就是DMA方式採集,程式碼複雜,速度在5-10幀左右。(博主本來想用該方法的,可是基礎差,除錯困難。會接著除錯~)
  • 注:部分CMOS 時鐘速度不快,可以微控制器直接採集,如OV7660,但該晶片已經停產。
  • 帶FIFO:由於採用了FIFO 做為資料緩衝,資料採集大大簡便,使用者只需要關心是如何讀取即可,不需要關心具體資料是如何採集到的,這樣可減小甚至不用關心CMOS 的控制以及時序關係,就能夠實現影象的採集。

注意:FIFO不具備地址功能,因此他也就不具備資料的定位(選址)讀取功能,所以不可能有真正的資料處理能力!

總的來說:帶FIFO比不帶FIFO操作起來更簡單,8位MCU也能勝任。下面我們參考戰艦攝像頭實驗(帶FIFO的OV7670模組)

二、OV7670的影象資料輸出格式:(參考戰艦開發指南)

       先簡單瞭解幾個定義:

  • VGA:解析度為640*480的輸出模式
  • QVGA:解析度為320*240的輸出格式
  • QQVGA:解析度為160*120的輸出格式
  • PCLK:畫素時鐘,一個PCLK時鐘,輸出1個畫素或半個畫素
  • VSYNC:幀同步訊號
  • HREF/HSYNC:行同步訊號
先看行輸出時序

圖3:OV7670行輸出時序
         圖3中,影象資料在HREF為高的時候輸出,當HREF變高後,每一個PCLK時鐘,輸出一個位元組資料。比如我們採用VGA時序,RGB565格式輸出,每兩個位元組組成一個畫素的顏色(高位元組在前,低位元組在後),這樣每行輸出總共有640*2個PCLK週期,輸出640*2個位元組。
在來看幀時序

圖4:OV7670幀時序
       在圖4中,VSYNC位高時產生一個幀同步訊號,故當產生兩個幀同步訊號時,一幀資料輸出完成。注意:圖中的HSYNC和HREF其實是一個引腳產生的訊號,只是在不同的場合下面,使用不同的訊號方式。

三、戰艦OV7670模組原理圖講解:


圖5:戰艦OP7670模組原理圖
       在圖5中,我們用3種顏色的線,將OV7670模組原理圖中幾個重要晶片同MCU“連”了起來。不多說,看圖~

四、儲存和讀取影象資料的過程及程式講解(參考原子哥的開發指南和程式碼)
       對於該模組,我們只關心兩點:1、如何儲存影象資料;2、如何讀取影象資料
       1、儲存(OV7670往FIFO中寫資料)
       戰艦OV7670模組儲存影象資料的過程為:等待OV767同步訊號->FIFO寫指標復位->FIFO寫使能->等待第二個同步訊號->FIFO寫禁止,通過以上5個步驟就可以完成一幀影象的儲存
       2、讀取(MCU從FIFO中讀取資料)
       讀取過程:FIFO讀指標復位->給FIFO讀時鐘(FIFO RCLK)->讀取第一個畫素高位元組->給FIFO讀時鐘(FIFO RCLK)->讀取第一個畫素低位元組->給FIFO讀時鐘(FIFO RCLK)->讀取第二個畫素高位元組->迴圈讀取剩餘畫素->結束
       比如QVGA模式,RGB565格式,我們總共迴圈讀取320*240*2次,就可以讀取一幀資料,把這些資料寫入LCD模組,就可以看到攝像頭的畫面了。

程式講解:(主要是OV7670對FIFO的寫控制和MCU從FIFO中讀取資料)
1、利用外部中斷來對OV7670進行寫操作控制

圖6:外部中斷對OV7670進行寫控制
         詳細解釋請看程式碼註釋~
2、MCU從FIFO中讀取資料(更新LCD顯示)

圖7:更新LCD顯示函式(MCU讀取FIFO資料)
        詳細請看程式碼註釋~
對了,戰艦例程中還有個位元組對齊的問題,詳情請瀏覽我轉載的部落格:http://blog.csdn.net/houqi02/article/details/51707456
本篇部落格到此結束,多謝看官!博主不才,難免有不足之處,懇請看官提出交流,共同進步!