日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OV2640

發布時間:2024/3/12 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OV2640 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OV2640

硬件連接

通過開發板的OLED/CAMERA接口與攝像頭模塊連接。具體引腳連接如上圖所示

SCCB時序
外部控制器對OV2640寄存器的配置參數是通過SCCB總線傳輸過去的,而SCCB總線跟I2C十分類似,在STM32驅動中直接使用片上I2C外設與它通訊。 SCCB與標準的I2C協議的區別是它每次傳輸只能寫入或讀取一個字節的數據,而I2C協議是支持突發讀寫的, 即在一次傳輸中可以寫入多個字節的數據(EEPROM中的頁寫入時序即突發寫)。
SCCB的起始、停止信號及數據有效性
SCCB的起始信號、停止信號及數據有效性與I2C完全一樣
起始信號:在SIO_C為高電平時,SIO_D出現一個下降沿,則SCCB開始傳輸。
停止信號:在SIO_C為高電平時,SIO_D出現一個上升沿,則SCCB停止傳輸。

數據有效性:除了開始和停止狀態,在數據傳輸過程中,當SIO_C為高電平時,必須保證SIO_D上的數據穩定,即SIO_D上的電平變換只能發生在SIO_C為低電平的時候,SIO_D的信號在SIO_C為高電平時被采集。
SCCB數據讀寫過程
在SCCB協議中定義的讀寫操作與I2C一樣。它定義了兩種寫操作,即三步寫操作和兩步寫操作。 三步寫操作可向從設備的一個目的寄存器中寫入數據 。第一階段發送從設備的ID地址+W標志(等于I2C的設備地址:7位設備地址+讀寫方向標志),第二階段發送從設備目標寄存器的8位地址, 第三階段發送要寫入寄存器的8位數據。圖中的“X”數據位可寫入1或0,對通訊無影響。(見下圖)

而兩步寫操作沒有第三階段,即只向從器件傳輸了設備ID+W標志和目的寄存器的地址 。 兩步寫操作是用來配合后面的讀寄存器數據操作的,它與讀操作一起使用,實現I2C的復合過程。


兩步讀操作用于讀取從設備目的寄存器中的數據。在第一階段中發送從設備的設備ID+R標志(設備地址+讀方向標志)和自由位, 在第二階段中讀取寄存器中的8位數據和寫NA位(非應答信號)。由于兩步讀操作沒有確定目的寄存器的地址, 所以在讀操作前,必需有一個兩步寫操作,以提供讀操作中的寄存器地址。

以上介紹的SCCB特性都與I2C無區別,而I2C比SCCB還多出了突發讀寫的功能,因此我們可以使用STM32的I2C外設來與OV2640進行SCCB通訊。

相關宏

/*攝像頭接口 */ //IIC SCCB #define CAMERA_I2C I2C1 #define CAMERA_I2C_CLK RCC_APB1Periph_I2C1#define CAMERA_I2C_SCL_PIN GPIO_Pin_8 #define CAMERA_I2C_SCL_GPIO_PORT GPIOB #define CAMERA_I2C_SCL_GPIO_CLK RCC_AHB1Periph_GPIOB #define CAMERA_I2C_SCL_SOURCE GPIO_PinSource8 #define CAMERA_I2C_SCL_AF GPIO_AF_I2C1#define CAMERA_I2C_SDA_PIN GPIO_Pin_9 #define CAMERA_I2C_SDA_GPIO_PORT GPIOB #define CAMERA_I2C_SDA_GPIO_CLK RCC_AHB1Periph_GPIOB #define CAMERA_I2C_SDA_SOURCE GPIO_PinSource9 #define CAMERA_I2C_SDA_AF GPIO_AF_I2C1//VSYNC #define DCMI_VSYNC_GPIO_PORT GPIOB #define DCMI_VSYNC_GPIO_CLK RCC_AHB1Periph_GPIOB #define DCMI_VSYNC_GPIO_PIN GPIO_Pin_7 #define DCMI_VSYNC_PINSOURCE GPIO_PinSource7 #define DCMI_VSYNC_AF GPIO_AF_DCMI // HSYNC #define DCMI_HSYNC_GPIO_PORT GPIOA #define DCMI_HSYNC_GPIO_CLK RCC_AHB1Periph_GPIOA #define DCMI_HSYNC_GPIO_PIN GPIO_Pin_4 #define DCMI_HSYNC_PINSOURCE GPIO_PinSource4 #define DCMI_HSYNC_AF GPIO_AF_DCMI //PIXCLK #define DCMI_PIXCLK_GPIO_PORT GPIOA #define DCMI_PIXCLK_GPIO_CLK RCC_AHB1Periph_GPIOA #define DCMI_PIXCLK_GPIO_PIN GPIO_Pin_6 #define DCMI_PIXCLK_PINSOURCE GPIO_PinSource6 #define DCMI_PIXCLK_AF GPIO_AF_DCMI //PWDN #define DCMI_PWDN_GPIO_PORT GPIOC #define DCMI_PWDN_GPIO_CLK RCC_AHB1Periph_GPIOC #define DCMI_PWDN_GPIO_PIN GPIO_Pin_0//數據信號線 #define DCMI_D0_GPIO_PORT GPIOC #define DCMI_D0_GPIO_CLK RCC_AHB1Periph_GPIOC #define DCMI_D0_GPIO_PIN GPIO_Pin_6 #define DCMI_D0_PINSOURCE GPIO_PinSource6 #define DCMI_D0_AF GPIO_AF_DCMI

要點:
1.初始化DCMI時鐘,I2C時鐘;
2.使用I2C接口向OV2640寫入寄存器配置;
3.初始化DCMI工作模式;
4.初始化DMA,用于搬運DCMI的數據到顯存空間進行顯示;
5.編寫測試程序,控制采集圖像數據并顯示到液晶屏。

初始化DCMI的 GPIO及I2C

void OV2640_HW_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStruct;/***DCMI引腳配置***//* 使能DCMI時鐘 */RCC_AHB1PeriphClockCmd(DCMI_PWDN_GPIO_CLK|DCMI_VSYNC_GPIO_CLK |DCMI_HSYNC_GPIO_CLK | DCMI_PIXCLK_GPIO_CLK|DCMI_D0_GPIO_CLK| DCMI_D1_GPIO_CLK|, ENABLE);/*控制/同步信號線*/GPIO_InitStructure.GPIO_Pin = DCMI_VSYNC_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;GPIO_Init(DCMI_VSYNC_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(DCMI_VSYNC_GPIO_PORT, DCMI_VSYNC_PINSOURCE, DCMI_VSYNC_AF);GPIO_InitStructure.GPIO_Pin = DCMI_HSYNC_GPIO_PIN ;GPIO_Init(DCMI_HSYNC_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(DCMI_HSYNC_GPIO_PORT, DCMI_HSYNC_PINSOURCE, DCMI_HSYNC_AF);GPIO_InitStructure.GPIO_Pin = DCMI_PIXCLK_GPIO_PIN ;GPIO_Init(DCMI_PIXCLK_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(DCMI_PIXCLK_GPIO_PORT, DCMI_PIXCLK_PINSOURCE, DCMI_PIXCLK_AF);GPIO_InitStructure.GPIO_Pin = DCMI_PWDN_GPIO_PIN ;GPIO_Init(DCMI_PWDN_GPIO_PORT, &GPIO_InitStructure);/*PWDN引腳,高電平關閉電源,低電平供電*/GPIO_ResetBits(DCMI_PWDN_GPIO_PORT,DCMI_PWDN_GPIO_PIN);/*數據信號*/GPIO_InitStructure.GPIO_Pin = DCMI_D0_GPIO_PIN ;GPIO_Init(DCMI_D0_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(DCMI_D0_GPIO_PORT, DCMI_D0_PINSOURCE, DCMI_D0_AF);/*...省略部分數據信號線*//****** 配置I2C,使用I2C與攝像頭的SCCB接口通訊*****//* 使能I2C時鐘 */RCC_APB1PeriphClockCmd(CAMERA_I2C_CLK, ENABLE);/* 使能I2C使用的GPIO時鐘 */RCC_AHB1PeriphClockCmd(CAMERA_I2C_SCL_GPIO_CLK|CAMERA_I2C_SDA_GPIO_CLK, ENABLE);/* 配置引腳源 */GPIO_PinAFConfig(CAMERA_I2C_SCL_GPIO_PORT, CAMERA_I2C_SCL_SOURCE, CAMERA_I2C_SCL_AF);GPIO_PinAFConfig(CAMERA_I2C_SDA_GPIO_PORT, CAMERA_I2C_SDA_SOURCE, CAMERA_I2C_SDA_AF);/* 初始化GPIO */GPIO_InitStructure.GPIO_Pin = CAMERA_I2C_SCL_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(CAMERA_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);GPIO_PinAFConfig(CAMERA_I2C_SCL_GPIO_PORT, CAMERA_I2C_SCL_SOURCE, CAMERA_I2C_SCL_AF);GPIO_InitStructure.GPIO_Pin = CAMERA_I2C_SDA_PIN ;GPIO_Init(CAMERA_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);/*初始化I2C模式 */I2C_DeInit(CAMERA_I2C);I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStruct.I2C_OwnAddress1 = 0xFE;I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStruct.I2C_ClockSpeed = 40000;/* 寫入配置 */I2C_Init(CAMERA_I2C, &I2C_InitStruct);/* 使能I2C */I2C_Cmd(CAMERA_I2C, ENABLE); }

配置DCMI的模式

void OV2640_Init(void) {DCMI_InitTypeDef DCMI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;/*** 配置DCMI接口 ***//* 使能DCMI時鐘 */RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);/* DCMI 配置*/DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising;DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_Low;DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;DCMI_Init(&DCMI_InitStructure);//配置DMA傳輸,直接配置循環傳輸即可OV2640_DMA_Config(FSMC_LCD_ADDRESS,1);/* 配置中斷 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* 配置幀中斷,接收到幀同步信號就進入中斷 */NVIC_InitStructure.NVIC_IRQChannel = DCMI_IRQn ; //幀中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);DCMI_ITConfig (DCMI_IT_FRAME,ENABLE); }

配置DMA數據傳輸

void OV2640_DMA_Config(uint32_t DMA_Memory0BaseAddr,uint16_t DMA_BufferSize) {DMA_InitTypeDef DMA_InitStructure;/* 配置DMA從DCMI中獲取數據*//* 使能DMA*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);DMA_Cmd(DMA2_Stream1,DISABLE);while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE) {}DMA_InitStructure.DMA_Channel = DMA_Channel_1;DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS; //DCMI數據寄存器地址//DMA傳輸的目的地址(傳入的參數)DMA_InitStructure.DMA_Memory0BaseAddr = DMA_Memory0BaseAddr;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;DMA_InitStructure.DMA_BufferSize =DMA_BufferSize; //傳輸的數據大小(傳入的參數)DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//液晶數據地址,不自增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循環模式DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC8;DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;/*DMA初始化 */DMA_Init(DMA2_Stream1, &DMA_InitStructure);DMA_Cmd(DMA2_Stream1,ENABLE);while (DMA_GetCmdStatus(DMA2_Stream1) != ENABLE) {}

配置幀中斷

extern uint8_t fps;//使用幀中斷重置line_num,可防止有時掉數據的時候DMA傳送行數出現偏移 void DCMI_IRQHandler(void) {if ( DCMI_GetITStatus (DCMI_IT_FRAME) == SET ) {/*傳輸完一幀,計數復位*/fps++; //幀率計數DCMI_ClearITPendingBit(DCMI_IT_FRAME);} }

讀取攝像頭ID

//存儲攝像頭ID的結構體 typedef struct {uint8_t Manufacturer_ID1;uint8_t Manufacturer_ID2;uint8_t PIDH;uint8_t PIDL; } OV2640_IDTypeDef; /*寄存器地址*/ #define OV2640_DSP_RA_DLMT 0xFF #define OV2640_SENSOR_MIDH 0x1C #define OV2640_SENSOR_MIDL 0x1D #define OV2640_SENSOR_PIDH 0x0A #define OV2640_SENSOR_PIDL 0x0B /** * @brief 讀取攝像頭的ID. * @param OV2640ID: 存儲ID的結構體 * @retval None */ void OV2640_ReadID(OV2640_IDTypeDef *OV2640ID) {/*OV2640有兩組寄存器,設置0xFF寄存器的值為0或為1時可選擇使用不同組的寄存器*/OV2640_WriteReg(OV2640_DSP_RA_DLMT, 0x01);/*讀取寄存芯片ID*/OV2640ID->Manufacturer_ID1 = OV2640_ReadReg(OV2640_SENSOR_MIDH);OV2640ID->Manufacturer_ID2 = OV2640_ReadReg(OV2640_SENSOR_MIDL);OV2640ID->PIDH = OV2640_ReadReg(OV2640_SENSOR_PIDH);OV2640ID->PIDL = OV2640_ReadReg(OV2640_SENSOR_PIDL); }

向OV2640寫入寄存器配置

uint16_t img_width=852, img_height=480; /* 使用用 UXGA 模式,再根據所需的圖像窗口裁剪 */ const unsigned char OV2640_UXGA[][2]= {0xff, 0x00,0x2c, 0xff,0x2e, 0xdf,0xff, 0x01,0x3c, 0x32,0x11, 0x00,0x09, 0x02,0x04, 0xD8, //水平翻轉0x13, 0xe5,/*....以下省略*/ }/** * @brief 配置OV2640為UXGA模式,并設置輸出圖像大小 * @param None * @retval None */ void OV2640_UXGAConfig(void) {uint32_t i;/* 寫入寄存器配置 */for (i=0; i<(sizeof(OV2640_UXGA)/2); i++){OV2640_WriteReg(OV2640_UXGA[i][0], OV2640_UXGA[i][1]);}/*設置輸出的圖像大小*/OV2640_OutSize_Set(img_width,img_height); }

總結

以上是生活随笔為你收集整理的OV2640的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。