《ESP32-S3使用指南—IDF版 V1.6》第三十五章 攝像頭實驗
第三十五章攝像頭實驗
1)實驗平臺:正點原子DNESP32S3開發板
2)章節摘自【正點原子】ESP32-S3使用指南—IDF版 V1.6
3)購買鏈接:https://detail.tmall.com/item.htm?&id=768499342659
4)全套實驗源碼+手冊+視頻下載地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32S3.html
5)正點原子官方B站:https://space.bilibili.com/394620890
6)正點原子DNESP32S3開發板技術交流群:132780729


LCD_CAM控制塊CAMERA模塊則用于接收并行視頻數據信號,支持DVP 8-/16-bit模式。DNESP32S3開發板板載了一個攝像頭接口(P2),該接口可以用來連接正點原子 OV5640/OV2640/OV7725等攝像頭模塊。本章,我們將使用ESP32-S3驅動正點原子 OV56400/OV2640攝像頭模塊,實現攝像頭功能。
本章分為如下幾個小節:
35.1 OV5640和CAMERA模塊簡介
35.2 硬件設計
35.3 程序設計
35.4 下載驗證
35.1 OV5640和CAMERA模塊簡介
本節將分為兩個部分,分別介紹OV5640簡介和DNESP32S3 LCD_CAM接口簡介。另外,所有OV5640的相關資料,都在光盤:A盤à7,硬件資料àOV5640資料 文件夾里面。
35.1.1 OV5640簡介
OV5640是OV(OmniVision)公司生產的一顆1/4寸的CMOS QSXGA(25921944)圖像傳感器,提供了一個完整的500W像素攝像頭解決方案,并且集成了自動對焦(AF)功能,具有非常高的性價比。
該傳感器體積小、工作電壓低,提供單片QSXGA攝像頭和影像處理器的所有功能。通過SCCB 總線控制,可以輸出整幀、子采樣、縮放和取窗口等方式的各種分辨率8/10位影像數據。該產品QSXGA圖像最高達到15幀/秒(1080P圖像可達30幀,720P圖像可達60幀,QVGA分辨率時可達120幀)。用戶可以完全控制圖像質量、數據格式和傳輸方式。所有圖像處理功能過程包括伽瑪曲線、白平衡、對比度、色度等都可以通過SCCB接口編程。OmmiVision圖像傳感器應用獨有的傳感器技術,通過減少或消除光學或電子缺陷如固定圖案噪聲、拖尾、浮散等,提高圖像質量,得到清晰穩定的彩色圖像。
OV5640的特點有:
l 采用1.4μm1.4μm像素大小,并且使用OmniBSI技術以達到更高性能(高靈敏度、低串擾和低噪聲)
l 自動圖像控制功能:自動曝光(AEC)、自動白平衡(AWB)、自動消除燈光條紋、自動黑電平校準(ABLC)和自動帶通濾波器(ABF)等。
l 支持圖像質量控制:色飽和度調節、色調調節、gamma校準、銳度和鏡頭校準等
l 標準的SCCB接口,兼容IIC接口
l 支持RawRGB、RGB(RGB565/RGB555/RGB444)、CCIR656、YUV(422/420)、YCbCr(422)和壓縮圖像(JPEG)輸出格式
l 支持QSXGA(500W)圖像尺寸輸出,以及按比例縮小到其他任何尺寸
l 支持閃光燈
l 支持圖像縮放、平移和窗口設置
l 支持圖像壓縮,即可輸出JPEG圖像數據
l 支持數字視頻接口(DVP)和MIPI接口
l 支持自動對焦
l 自帶嵌入式微處理器
OV5640的功能框圖如圖35.1.1.1所示:

圖35.1.1.1 OV5640功能框圖
其中image array部分的尺寸,OV5640的官方數據并沒有給出具體的數字,其最大的有效輸出尺寸為:25921944,即500W像素,我們根據官方提供的一些應用文檔,發現其設置的image array最大為:26321951,所以,在接下來的介紹,我們設定其image array最大為2632*1951。
1、DVP接口說明
OV5640支持數字視頻接口(DVP)和MIPI接口,因為我們的DNESP32S3使用的DCMI接口,僅支持DVP接口,所以,OV5640必須使用DVP輸出接口,才可以連接我們的阿波羅ESP32開發板。
OV5640提供一個10位DVP接口(支持8位接法),其MSB和LSB可以程序設置先后順序,正點原子 OV5640模塊采用默認的8位連接方式,如圖35.1.1.2所示:

圖35.1.1.2 OV5640默認8位連接方式
OV5640的寄存器通過SCCB時序訪問并設置,SCCB時序和IIC時序十分類似。SCCB 與標準的 I2C 協議的區別是它每次傳輸只能寫入或讀取一個字節的數據,而 I2C協議是支持突發讀寫的,即在一次傳輸中可以寫入多個字節的數據(EEPROM中的頁寫入時序即突發寫)。在本章我們不做介紹,請大家參考光盤《OmniVisionTechnologies Seril Camera Control Bus(SCCB) Specification》這個文檔。
2、窗口設置說明
接下來,我們介紹一下OV5640的:ISP(Image Signal Processor)輸入窗口設置、預縮放窗口設置和輸出大小窗口設置,這幾個設置與我們的正常使用密切相關,有必要了解一下。他們的設置關系,如圖35.1.1.3所示:

圖35.1.1.3 OV5640各窗口設置關系
ISP輸入窗口設置(ISP input size)
該設置允許用戶設置整個傳感器區域(physical pixel size,26321951)的感興趣部分,也就是在傳感器里面開窗(X_ADDR_ST、Y_ADDR_ST、X_ADDR_END和Y_ADDR_END),開窗范圍從00~26321951都可以設置,該窗口所設置的范圍,將輸入ISP進行處理。
ISP輸入窗口,通過:0X3800~0X3807等8個寄存器進行設置,這些寄存器的定義請看:OV5640_CSP3_DS_2.01_Ruisipusheng.pdf 這個文檔(下同)。
預縮放窗口設置(pre-scaling size)
該設置允許用戶在ISP輸入窗口的基礎上,再次設置將要用于縮放的窗口大小。該設置僅在ISP輸入窗口內進行x/y方向的偏移(X_OFFSET/Y_OFFSET)。通過:0X3810~0X3813等4個寄存器進行設置。
輸出大小窗口設置(data output size)
該窗口是以預縮放窗口為原始大小,經過內部DSP進行縮放處理后,輸出給外部的圖像窗口大小。它控制最終的圖像輸出尺寸(X_OUTPUT_SIZE/Y_OUTPUT_SIZE)。通過:0X3808~0X380B等4個寄存器進行設置。注意:當輸出大小窗口與預縮放窗口比例不一致時,圖像將進行縮放處理(會變形),僅當兩者比例一致時,輸出比例才是1:1(正常)。
圖35.1.1.3中,右側data output size區域,才是OV5640輸出給外部的圖像尺寸,也就是顯示在LCD上面的圖像大小。輸出大小窗口與預縮放窗口比例不一致時,會進行縮放處理,在LCD上面看到的圖像將會變形。
3、輸出時序說明
接下來,我們介紹一下OV5640的圖像數據輸出時序。首先我們簡單介紹一些定義:
QSXGA,這里指:分辨率為25921944的輸出格式,類似的還有:QXGA(20481536)、UXGA(16001200)、SXGA(12801024)、WXGA+(1440900)、WXGA(1280800)、XGA(1024768)、SVGA(800600)、VGA(640480)、QVGA(320240)和QQVGA(160120)等。
PCLK,即像素時鐘,一個PCLK時鐘,輸出一個像素(或半個像素)。
VSYNC,即幀同步信號。
HREF /HSYNC,即行同步信號。
OV5640的圖像數據輸出(通過Y[9:0])就是在PCLK,VSYNC和HREF/ HSYNC的控制下進行的。首先看看行輸出時序,如圖35.1.1.4所示:

圖35.1.1.4 OV5640行輸出時序
從上圖可以看出,圖像數據在HREF為高的時候輸出,當HREF變高后,每一個PCLK時鐘,輸出一個8位/10位數據。我們采用8位接口,所以每個PCLK輸出1個字節,且在RGB/YUV輸出格式下,每個tp=2個Tpclk,如果是Raw格式,則一個tp=1個Tpclk。比如我們采用QSXGA時序,RGB565格式輸出,每2個字節組成一個像素的顏色(低字節在前,高字節在后),這樣每行輸出總共有25922個PCLK周期,輸出25922個字節。
再來看看幀時序(QSXGA模式),如圖35.1.1.5所示:

圖35.1.1.5 OV5640幀時序
上圖清楚的表示了OV5640在QSXGA模式下的數據輸出。我們按照這個時序去讀取OV5640的數據,就可以得到圖像數據。
4、自動對焦(Auto Focus)說明
OV5640由內置微型控制器完成自動對焦,并且VCM(Voice CoilMotor,即音圈馬達)驅動器也已集成在傳感器內部。微型控制器的控制固件(firmware)從主機下載。當固件運行后,內置微型控制器從OV5640傳感器讀得自動對焦所需的信息,計算并驅動VCM馬達帶動鏡頭到達正確的對焦位置。主機可以通過IIC命令控制微型控制器的各種功能。
OV5640的自動對焦命令(通過SCCB總線發送),如表35.1.1.1所示:

表35.1.1.1 OV5640自動對焦命令
OV5640內部的微控制器收到自動對焦命令后會自動將CMD_MAIN(0X3022)寄存器數據清零,當命令完成后會將CMD_ACK(0X3023)寄存器數據清零。
自動對焦(AF)過程
第一步:在第一次進入圖像預覽的時候(圖像可以正常輸出時),下載固件(firmware)。
第二步:拍照前,自動對焦,對焦完成后,拍照。
第三步:拍照完畢,釋放馬達到初始狀態。
接下來,我們分別說明:
① 下載固件
OV5640初始化完成后,就可以下載AF自動對焦固件了,其操作和下載初始化參數類似,AF固件下載地址為:0X8000,初始化數組由廠家提供(本例程該數組保存在ov5640af.h里面),下載固件完成后,通過檢查0X3029寄存器的值,來判斷固件狀態(等于0X70,說明正常)。
② 自動對焦
OV5640支持單次自動對焦和持續自動對焦,通過0X3022寄存器控制。單次自動對焦過程如下:
1,將0X3022寄存器寫為0X03,開始單點對焦過程。
2,讀取寄存器0X3029,如果返回值為0X10,代表對焦已完成。
3,寫寄存器0X3022為0X06,暫停對焦過程,使鏡頭將保持在此對焦位置。
其中,前兩步是必須的,第三步,可以不要,因為單次自動對焦完成以后,就不會繼續自動對焦了,鏡頭也就不會動了。
持續自動對焦過程如下:
1, 將0X22寄存器寫為0X08,釋放馬達到初始位置(對焦無窮遠)。
2, 將0X3022寄存器寫為0X04,啟動持續自動對焦過程。
3, 讀取寄存器0X3023,等待命令完成。
4, 當OV5640每次檢測到失焦時,就會自動進行對焦(一直檢測)。
③ 釋放馬達,結束自動對焦
最后,在拍照完成,或者需要結束自動對焦的時候,我們對在寄存器0X3022寫入0X08,即可釋放馬達,結束自動對焦。
最后說一下OV5640的圖像數據格式,我們一般用2種輸出方式:RGB565和JPEG。當輸出RGB565格式數據的時候,時序完全就是上面兩幅圖介紹的關系。以滿足不同需要。而當輸出數據是JPEG數據的時候,同樣也是這種方式輸出(所以數據讀取方法一模一樣),不過PCLK數目大大減少了,且不連續,輸出的數據是壓縮后的JPEG數據,輸出的JPEG數據以:0XFF,0XD8開頭,以0XFF,0XD9結尾,且在0XFF,0XD8之前,或者0XFF,0XD9之后,會有不定數量的其他數據存在(一般是0),這些數據我們直接忽略即可,將得到的0XFF,0XD8~0XFF,0XD9之間的數據,保存為.jpg/.jpeg文件,就可以直接在電腦上打開看到圖像了。
OV5640自帶的JPEG輸出功能,大大減少了圖像的數據量,使得其在網絡攝像頭、無線視頻傳輸等方面具有很大的優勢。OV5640我們就介紹到這,關于OV5640更詳細的介紹,請大家參考:A盤à7,硬件資料àOV5640資料àOV5640_CSP3_DS_2.01_Ruisipusheng.pdf。
正點原子OV5640攝像頭模塊
本實驗,我們將使用DNESP32S3開發板的DCMI接口連接正點原子 OV5640攝像頭模塊,該模塊采用8位數據輸出接口,自帶24M有源晶振,無需外部提供時鐘,模組支持自動對焦功能,且支持閃光燈,整個模塊只需提供3.3V 供電即可正常使用。
正點原子 OV5640攝像頭模塊外觀如圖35.1.1.6所示:

圖35.1.1.6 ALIENTEKOV5640攝像頭模塊外觀圖
模塊原理圖如圖35.1.1.7所示:

圖35.1.1.7 正點原子OV5640攝像頭模塊原理圖
從上圖可以看出,正點原子 OV5640攝像頭模塊自帶了有源晶振,用于產生24M時鐘作為OV5640的XCLK輸入,模塊的閃光燈(LED1&LED2)由OV5640的STROBE腳控制(可編程控制)。同時自帶了穩壓芯片,用于提供OV5640穩定的2.8V和1.5V工作電壓,模塊通過一個2*9的雙排排針(P6)與外部通信,與外部的通信信號如表35.1.1.2所示:

表35.1.1.2 OV5640模塊信號及其作用描述
35.1.2 CAMERA模塊簡介
前面講解到,ESP32-S3的LCD_CAM控制器包含獨立的LCD模塊和Camera模塊。其中LCD模塊已經在第三十五章節中介紹過。下面我們介紹Camera模塊用于接收并行視頻數據信號,其總線支持DVP 8-/16-bit 模式。
以下是Camera模塊特點:
①:支持以下工作模式:
– Camera 從機接收模式。
– Camera 主機接收模式。
②:支持同時外接 LCD 和 Camera。
③:支持單獨外接 Camera(即 DVP 圖像傳感器)。
– 可配置為 8-bit 或 16-bit 位并行輸入模式。
– Camera 數據可由 GDMA 存入內部存儲器。
④:支持 LCD_CAM 接口中斷。
CAMERA控制器功能框圖如下:

圖35.1.2.1 ESP32-S3LCD_CAM模塊的結構框圖
這個系統的CAMERA模塊和LCD模塊類似:包含一個獨立的接收控制單元(Camera_Ctrl),用于控制攝像頭的接收;一個接收異步FIFO(Async Rx FIFO),用于與外部設備交互,接收數據;一個LCD_ClockGenerator時鐘生成模塊,用于生成對應模塊的時鐘;以及一個格式轉換模塊,即RGB/YCbCr Converter,用于各種格式的視頻數據互相轉換。這些模塊協同工作,確保系統能夠高效、穩定地處理和傳輸視頻數據。
1,CAMERA模塊信號描述
CAMERA模塊信號對應了上圖右上角的幾個信號,它們的具體作用如下所示。

表35.1.2.1 CAMERA模塊信號描述
從上表可以看到,CAMERA模塊工作模式分為兩種,分別為從機接收模式和主機接收模式。一般我們使用主機接收模式開啟動攝像頭模組。
在啟動CAMERA模塊時,信號的位寬是一個關鍵參數。根據所接入的CAMERA的位寬,N的值會有所不同。如果使用位寬為16位,則N的值為15。相反,如果使用8位的位寬,則N的值為7。因此,根據CAMERA的位寬,可以確定N的具體值。
2,CAMERA時鐘選擇
CAMERA模塊的時鐘LCD模塊時鐘選擇是一樣的配置流程,請讀者參考第三十五章的35.1.2小節。
35.2 硬件設計
35.2.1. 例程功能
本章實驗功能簡介:程序下載完成,攝像頭的圖像數據在SPILCD顯示屏上顯示。
35.2.2. 硬件資源
- XL9555
IIC_SDA-IO41
IIC_SCL-IO42 - SPILCD
CS-IO21
SCK-IO12
SDA-IO11
DC-IO40(在P5端口,使用跳線帽將IO_SET和LCD_DC相連)
PWR- IO1_3(XL9555)
RST- IO1_2(XL9555) - CAMERA
OV_SCL-IO38
OV_SDA- IO 39
VSYNC- IO 47
HREF- IO 48
PCLK- IO 45
D0- IO 4
D1- IO 5
D2- IO 6
D3- IO 7
D4- IO 15
D5- IO 16
D6- IO 17
D7- IO 18
RESET-IO0_5(XL9555)
PWDN-IO0_4(XL9555)
35.2.3.原理圖
CAMERA接口與ESP32-S3的連接關系,如下圖所示:

圖35.2.3.1 CAMERA接口與ESP32-S3的連接電路圖
35.3 程序設計
35.3.1 程序流程圖
程序流程圖能幫助我們更好的理解一個工程的功能和實現的過程,對學習和設計工程有很好的主導作用。下面看看本實驗的程序流程圖:

圖35.3.1.1 CAMERA實驗程序流程圖
35.3.2 CAMERA函數解析
本章實驗要使用到樂鑫官方的esp32-camera驅動庫,此驅動庫承載ESP32系列Soc兼容的圖像傳感器驅動程序。此外,它還提供了一些工具,允許將捕獲的幀數據轉換為更常見的BMP和JPEG格式。要使用此功能,需要導入必要的頭文件:
#include"esp_camera.h"
接下來,作者將介紹一些常用的ESP32-S3中的CAMERA函數,這些函數的描述及其作用如下:
1,初始化攝像頭驅動
該函數用于檢測并配置攝像頭,其函數原型如下所示:
esp_err_tesp_camera_init(const camera_config_t *config);
該函數的形參描述,如下表所示:

表35.3.2.1 函數esp_camera_init ()形參描述
該函數的返回值描述,如下表所示:

表35.3.2.2 函數esp_camera_init ()
返回值描述該函數使用camera_config_t類型的結構體變量傳入,該結構體的定義如下所示:

表35.3.2.3 camera_config_t結構體參數值描述
完成上述結構體參數配置之后,可以將結構傳遞給 esp_camera_init() 函數,用以實例化CAMERA。
2,獲取攝像頭圖像傳感器
該函數用于獲取指向圖像傳感器控制結構的指針,其函數原型如下所示:
sensor_t *esp_camera_sensor_get(void);
該函數的形參描述,如下表所示:

表35.3.2.4 函數esp_camera_sensor_get ()形參描述
該函數的返回值描述,如下表所示:

表35.3.2.5 函數esp_camera_sensor_get()返回值描述
35.3.3 CAMERA驅動解析
在IDF版的25_1_camera例程中,作者在25_1_camera\components\BSP路徑下新增了一個CAMERA文件夾以及25_1_camera\components\esp32-camera路徑下新增了一個樂鑫官方的esp32-camera驅動庫,分別用于存放camera.c、camera.h和esp32-camera庫文件。其中,camera.h負責聲明CAMERA相關的函數和變量,而camera.c和esp32-camera庫文件則實現了CAMERA的驅動。下面,我們將詳細解析這幾個文件的實現內容。
1,camera.h文件
/* 引腳聲明 */
#defineCAM_PIN_PWDN GPIO_NUM_NC
#defineCAM_PIN_RESET GPIO_NUM_NC
#defineCAM_PIN_XCLK GPIO_NUM_NC
#defineCAM_PIN_SIOD GPIO_NUM_39
#define CAM_PIN_SIOC GPIO_NUM_38
#defineCAM_PIN_D7 GPIO_NUM_18
#defineCAM_PIN_D6 GPIO_NUM_17
#defineCAM_PIN_D5 GPIO_NUM_16
#defineCAM_PIN_D4 GPIO_NUM_15
#defineCAM_PIN_D3 GPIO_NUM_7
#defineCAM_PIN_D2 GPIO_NUM_6
#defineCAM_PIN_D1 GPIO_NUM_5
#defineCAM_PIN_D0 GPIO_NUM_4
#defineCAM_PIN_VSYNC GPIO_NUM_47
#defineCAM_PIN_HREF GPIO_NUM_48
#defineCAM_PIN_PCLK GPIO_NUM_45
#defineCAM_PWDN(x) do{ x ? \
(xl9555_pin_write(OV_PWDN_IO, 1)): \
(xl9555_pin_write(OV_PWDN_IO, 0)); \
}while(0)
#defineCAM_RST(x) do{ x ? \
(xl9555_pin_write(OV_RESET_IO, 1)): \
(xl9555_pin_write(OV_RESET_IO, 0)); \
}while(0)
2,camera.c文件
/* 攝像頭配置 */
staticcamera_config_t camera_config = {
/* 引腳配置 */
.pin_pwdn =CAM_PIN_PWDN,
.pin_reset =CAM_PIN_RESET,
.pin_xclk =CAM_PIN_XCLK,
.pin_sccb_sda =CAM_PIN_SIOD,
.pin_sccb_scl =CAM_PIN_SIOC,
.pin_d7 =CAM_PIN_D7,
.pin_d6 =CAM_PIN_D6,
.pin_d5 =CAM_PIN_D5,
.pin_d4 =CAM_PIN_D4,
.pin_d3 =CAM_PIN_D3,
.pin_d2 =CAM_PIN_D2,
.pin_d1 =CAM_PIN_D1,
.pin_d0 =CAM_PIN_D0,
.pin_vsync =CAM_PIN_VSYNC,
.pin_href =CAM_PIN_HREF,
.pin_pclk =CAM_PIN_PCLK,
/* 圖像配置 */
.xclk_freq_hz = 24000000,
.ledc_timer =LEDC_TIMER_0,
.ledc_channel =LEDC_CHANNEL_0,
.fb_location =CAMERA_FB_IN_PSRAM,
/* 圖像輸出模式 */
.pixel_format =PIXFORMAT_RGB565,
/* 圖像輸出大小 */
.frame_size =FRAMESIZE_QVGA,
/* 0-63,對于OV系列相機傳感器,數量越少意味著質量越高 */
.jpeg_quality = 12,
/* 當使用jpeg模式時,如果fb_count超過一個,則驅動程序將在連續模式下工作 */
.fb_count = 2,
.grab_mode =CAMERA_GRAB_WHEN_EMPTY,
};
/**
* @brief 攝像頭初始化
* @param cmd 傳輸的8位命令數據
* @retval 無
*/
uint8_tcamera_init(void)
{
esp_err_t err =ESP_OK;
if (CAM_PIN_PWDN== GPIO_NUM_NC)
{
CAM_PWDN(0);
}
if (CAM_PIN_RESET== GPIO_NUM_NC)
{
CAM_RST(0);
vTaskDelay(20);
CAM_RST(1);
vTaskDelay(20);
}
/* 攝像頭初始化 */
err =esp_camera_init(&camera_config);
if (err !=ESP_OK)
{
return 1;
}
sensor_t * s =esp_camera_sensor_get();
if (s->id.PID ==OV3660_PID)
{
s->set_vflip(s, 1); /* 向后翻轉 */
s->set_brightness(s, 1); /* 亮度提高 */
s->set_saturation(s, -2); /* 降低飽和度 */
}
else if (s->id.PID ==OV5640_PID)
{
s->set_vflip(s, 1); /* 向后翻轉 */
}
return err;
}
首先定義一個camera_config_t類型的局部結構體變量,然后給結構體中的成員賦值,再調用esp_camera_init(&camera_config)函數進行初始化。如果攝像頭模塊是OV3660或者是OV5640,還需要進行配置。
35.3.4 CMakeLists.txt文件
打開本實驗BSP下的CMakeLists.txt文件,其內容如下所示:
set(src_dirs
CAMERA
IIC
LCD
LED
SPI
XL9555)
set(include_dirs
CAMERA
IIC
LCD
LED
SPI
XL9555)
set(requires
driver
esp_lcd
esp32-camera)
idf_component_register(SRC_DIRS${src_dirs}
INCLUDE_DIRS ${include_dirs}REQUIRES ${requires})
component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)
上述的紅色CAMERA驅動以及esp_ camera依賴庫需要由開發者自行添加,以確保CAMERA驅動能夠順利集成到構建系統中。這一步驟是必不可少的,它確保了CAMERA驅動的正確性和可用性,為后續的開發工作提供了堅實的基礎。
35.3.5 實驗應用代碼
打開main/main.c文件,該文件定義了工程入口函數,名為app_main。該函數代碼如下。
i2c_obj_ti2c0_master;
/**
* @brief 程序入口
* @param 無
* @retval 無
*/
voidapp_main(void)
{
uint8_t x = 0;
esp_err_t ret;
ret =nvs_flash_init(); /* 初始化NVS */
if (ret ==ESP_ERR_NVS_NO_FREE_PAGES ||
ret ==ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret =nvs_flash_init();
}
led_init(); /* 初始化LED*/
i2c0_master =iic_init(I2C_NUM_0); /* 初始化IIC0*/
spi2_init(); /* 初始化SPI2 */
xl9555_init(i2c0_master); /* 初始化XL9555 */
lcd_init(); /* 初始化LCD*/
lcd_show_string(30, 50, 200, 16, 16, "ESP32", RED);
lcd_show_string(30, 70, 200, 16, 16, "CAMERATEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
/* 初始化攝像頭 */
while (camera_init())
{
lcd_show_string(30, 110, 200, 16, 16, "CAMERAFail!", BLUE);
vTaskDelay(500);
}
lcd_clear(BLACK);
while (1)
{
camera_show(0,0); /* 顯示圖像 */
x++;
if (x % 30 == 0)
{
LED_TOGGLE();
}
vTaskDelay(5);
}
}
從上述源碼可知,我們首先初始化各個外設,如IIC、SPI、XL9555、攝像頭和LCD等驅動,然后調用camera_show()函數在SPILCD顯示屏上顯示攝像頭圖像。
35.4 下載驗證
程序下載到開發板后,LCD顯示屏不斷更新攝像頭輸出的圖像數據,如下圖所示。

圖35.4.1 LCD顯示效果圖

浙公網安備 33010602011771號