STM32正點(diǎn)原子戰(zhàn)艦開發(fā)板驅(qū)動(dòng)OV7725攝像頭
????開發(fā)板把 OV7725 芯片采集到的圖像顯示到 LCD 屏的過程分為三步:OV7725 輸出、FIFO 輸入、FIFO 輸出。下面是模塊的原理圖,主要有 OV7725 芯片、 AL422B? FIFO芯片和一個(gè) SN74VC1G00? 邏輯門芯片,圖中紅點(diǎn)是直接和STM32芯片連接的引腳,其它引腳是內(nèi)部引腳。

OV7725 圖像數(shù)據(jù)輸出
????OV7725 芯片配置各種寄存器通過 SCCB 標(biāo)準(zhǔn)實(shí)現(xiàn),這種標(biāo)準(zhǔn)和 I2C 類似,只用到 SCL 和 SDA 兩條線。
????OV7725 有兩種輸出模式:VGA(640 * 480)和QVGA(320 * 240),下面分別是 OV7725 輸出一行和 QVGA 模式輸出一幀顏色數(shù)據(jù)的寫時(shí)序,一行的時(shí)序可以理解為是一幀時(shí)序的一部分。


OV7725輸出一幀顏色數(shù)據(jù)時(shí)序
????仔細(xì)分析上圖。輸出時(shí)序需要用到引腳 XCLK 、 PCLK 、 HREF 、 VSYNC 和數(shù)據(jù)線, XCLK 是24MHz的輸入時(shí)鐘, PCLK 是輸出數(shù)據(jù)的時(shí)鐘, HREF 只在輸出有效數(shù)據(jù)時(shí)為高, VSYNC 在輸出完一幀圖像后拉高片刻??梢岳斫鉃椋涸?PCLK 時(shí)鐘同步下,每輸出完一行圖像數(shù)據(jù) HREF 置低片刻,每輸出完一幀圖像數(shù)據(jù) VSYNC 置高片刻。以上信號(hào)被稍微處理后通過 PCLK 、 HREF 和數(shù)據(jù)線傳給 AL422B 芯片。
AL422B 存儲(chǔ)圖像數(shù)據(jù)
????AL422B 現(xiàn)在有了寫時(shí)鐘 WCK 即 OV7725 的輸出時(shí)鐘 PCLK 、數(shù)據(jù)線,然而數(shù)據(jù)的時(shí)序和自己的寫時(shí)序并不匹配,它現(xiàn)在要做的就是想辦法接受得到的數(shù)據(jù)。 AL422B 重置并寫數(shù)據(jù)的時(shí)序如下圖。 AL422B 存儲(chǔ)圖像要用到的引腳為 WE 、 WRST 、 WCLK 和數(shù)據(jù)線。

????可見 AL422B 每次需要連續(xù)的一幀數(shù)據(jù),考慮到 VSYNC 信號(hào)每幀出現(xiàn)一次,且 HREF 信號(hào)只在 OV7725 輸出有效信號(hào)時(shí)置低,因此可以利用 VSYNC 創(chuàng)建外部中斷,每幀前發(fā)生中斷,在中斷里控制 WRST 信號(hào)開始接收數(shù)據(jù),并且 WE 全程被程序和 HREF 同時(shí)控制,實(shí)現(xiàn)方法為一個(gè) C=!A+!B 即 SN74VC1G00 的邏輯門,只有在程序把 FIFO_WEN 置高并且 OV7725 在輸出有效數(shù)據(jù)時(shí)WE才被置低, AL422B 才繼續(xù)接收數(shù)據(jù)。
????中斷代碼如下:
void EXTI9_5_IRQHandler( void )
{
????? ?if ( EXTI_GetITStatus( EXTI_Line8 ) == SET )? ? /* 是8線的中斷 */
????? ?{
????????? ? ? if ( ov_sta == 0 )
????????? ? ? {
????????????? ? ? ? ?OV7725_WRST? ? = 0;? ? ? ? ? ? /* 復(fù)位寫指針 */
????????????? ? ? ? ?OV7725_WRST? ? = 1;
????????????? ? ? ? ?OV7725_WREN? ? = 1;? ? ? ? ? ? /* 允許寫入FIFO */
????????????? ? ? ? ?ov_sta++;? ? ? ? ? ? ? ? ? ? ? ?/* 幀中斷加1 */
????????? ? ? }else OV7725_WREN = 0;? ? ? ? ? ? ? ? ? /* 禁止寫入FIFO */
????? ?}
????? ?EXTI_ClearITPendingBit( EXTI_Line8 );? ? ? ? ? ?/* 清除EXTI8線路掛起位 */
}
AL422B 圖像數(shù)據(jù)輸出
????AL433B 圖像數(shù)據(jù)輸出只用遵循輸出時(shí)序讀取即可,重置并讀數(shù)據(jù)的時(shí)序如下圖。用到的引腳為 OE 、 RE 、 RRST 、 RCLK 和數(shù)據(jù)線, RE 和 OE 已被物理和程序上拉低。

?AL422B 重置并讀時(shí)序
????分析時(shí)序,得到把顏色數(shù)據(jù)顯示到 LCD 屏上的代碼如下。
u8 ov_sta; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 在exit.c里 面定義 */
/* 更新LCD顯示(OV7725) */
void OV7725_camera_refresh( void )
{
? ?????u32 ? ?i, j;
? ?????u16 ? ?color;
? ?????if ( ov_sta ) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 有幀中斷更新 */
? ?????{
? ? ? ?????????LCD_WriteRAM_Prepare(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 開始寫入GRAM */
? ? ? ?????????OV7725_RRST = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 開始復(fù)位讀指針 */
? ? ? ?????????OV7725_RCK_L;
? ? ? ?????????OV7725_RCK_H;
? ? ? ?????????OV7725_RCK_L;
? ? ? ?????????OV7725_RRST = 1;
? ? ? ?????????OV7725_RCK_H;
? ? ? ?????????OV7725_RCK_L;
? ? ? ?????????/* 復(fù)位讀指針結(jié)束 */
? ? ? ?????????for ( i = 0; i < OV7725_WINDOW_HEIGHT; i++ )
? ? ? ?????????{
? ? ? ? ? ?????????????for ( j = 0; j < OV7725_WINDOW_WIDTH; j++ )
? ? ? ? ? ?????????????{
? ? ? ? ? ? ? ?????????????????color = GPIOC->IDR & 0XFF; ? ? ?/* 讀數(shù)據(jù) */
? ? ? ? ? ? ? ?????????????????OV7725_RCK_H;
? ? ? ? ? ? ? ?????????????????color <<= 8;
? ? ? ? ? ? ? ?????????????????OV7725_RCK_L;
? ? ? ? ? ? ? ?????????????????color |= GPIOC->IDR & 0XFF; ? ? /* 讀數(shù)據(jù) */
? ? ? ? ? ? ? ?????????????????OV7725_RCK_H;
? ? ? ? ? ? ? ?????????????????LCD->LCD_RAM = color;
? ? ? ? ? ? ? ?????????????????OV7725_RCK_L;
? ? ? ? ? ?????????????}
? ? ? ?????????}
? ? ? ?????????ov_sta = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 清零幀中斷標(biāo)記 */? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ?????}
}
參考:正點(diǎn)原子AN1704 ALIENTEK 攝像頭模塊使用、OV7725_datasheet、AL422B_datasheet。