#include "dcmi_ov2640.h"
#include "dcmi_ov2640_cfg.h"
DCMI_HandleTypeDef hdcmi; // DCMI¾ä±ú
DMA_HandleTypeDef DMA_Handle_dcmi; // DMA¾ä±ú
volatile uint8_t DCMI_FrameState = 0; // DCMI״̬±êÖ¾£¬µ±Êý¾ÝÖ¡´«ÊäÍê³Éʱ£¬»á±» HAL_DCMI_FrameEventCallback() Öжϻص÷º¯ÊýÖà 1
volatile uint8_t OV2640_FPS ; // Ö¡ÂÊ
/*************************************************************************************************
* º¯ Êý Ãû: HAL_DCMI_MspInit
* Èë¿Ú²ÎÊý: hdcmi - DCMI_HandleTypeDef¶¨ÒåµÄ±äÁ¿£¬¼´±íʾ¶¨ÒåµÄ DCMI ¾ä±ú
* ·µ »Ø Öµ: ÎÞ
* º¯Êý¹¦ÄÜ: ³õʼ»¯ DCMI Òý½Å
* ˵ Ã÷: ÎÞ
*************************************************************************************************/
void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hdcmi->Instance==DCMI)
{
__HAL_RCC_DCMI_CLK_ENABLE(); // ʹÄÜ DCMI ÍâÉèʱÖÓ
__HAL_RCC_GPIOE_CLK_ENABLE(); // ʹÄÜÏàÓ¦µÄGPIOʱÖÓ
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
GPIO_OV2640_PWDN_CLK_ENABLE; // ʹÄÜPWDN Òý½ÅµÄ GPIO ʱÖÓ
/****************************************************************************
Êý¾ÝÒý½Å ʱÖÓºÍͬ²½Òý½Å
PH9 ------> DCMI_D0 PG9 ------> DCMI_VSYNC
PH10 ------> DCMI_D1 PH8 ------> DCMI_HSYNC
PH11 ------> DCMI_D2 PA6 ------> DCMI_PIXCLK
PH12 ------> DCMI_D3
PH14 ------> DCMI_D4 SCCB ¿ØÖÆÒý½Å£¬³õʼ»¯ÔÚ camera_sccb.c Îļþ
PD3 ------> DCMI_D5 PH7 ------> SCCB_SCL
PE5 ------> DCMI_D6 PH13 ------> SCCB_SDA
PE6 ------> DCMI_D7
µôµç¿ØÖÆÒý½Å
PH15 ------> PWDN
******************************************************************************/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
// ³õʼ»¯ PWDN Òý½Å
OV2640_PWDN_ON; // ¸ßµçƽ£¬½øÈëµôµçģʽ£¬ÉãÏñÍ·Í£Ö¹¹¤×÷£¬´Ëʱ¹¦ºÄ½µµ½×îµÍ
GPIO_InitStruct.Pin = OV2640_PWDN_PIN; // PWDN Òý½Å
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // ÍÆÍìÊä³öģʽ
GPIO_InitStruct.Pull = GPIO_PULLUP; // ÉÏÀ
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Ëٶȵȼ¶µÍ
HAL_GPIO_Init(OV2640_PWDN_PORT, &GPIO_InitStruct); // ³õʼ»¯
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: MX_DCMI_Init
*
* º¯Êý¹¦ÄÜ: ÅäÖÃDCMIÏà¹Ø²ÎÊý
*
* ˵ Ã÷: 8λÊý¾Ýģʽ£¬È«Êý¾Ý¡¢È«Ö¡²¶×½£¬¿ªÆôÖжÏ
*
*****************************************************************************************************************************************/
void MX_DCMI_Init(void)
{
hdcmi.Instance = DCMI;
hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Ó²¼þͬ²½Ä£Ê½£¬¼´Ê¹ÓÃÍⲿµÄVS¡¢HSÐźŽøÐÐͬ²½
hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING; // ÏñËØÊ±ÖÓÉÏÉýÑØÓÐЧ
hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW; // VSµÍµçƽÓÐЧ
hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW; // HSµÍµçƽÓÐЧ
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME; // ²¶»ñµÈ¼¶£¬ÉèÖÃÿһ֡¶¼½øÐв¶»ñ
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // 8λÊý¾Ýģʽ
hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE; // ²»Ê¹ÓÃDCMIµÄJPEGģʽ
hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL; // DCMI½Ó¿Ú²¶×½ËùÓÐÊý¾Ý
hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD; // Ñ¡Ôñ¿ªÊ¼×Ö½Ú£¬´Ó Ö¡/ÐÐ µÄµÚÒ»¸öÊý¾Ý¿ªÊ¼²¶»ñ
hdcmi.Init.LineSelectMode = DCMI_LSM_ALL; // ²¶»ñËùÓÐÐÐ
hdcmi.Init.LineSelectStart = DCMI_OELS_ODD; // Ñ¡Ôñ¿ªÊ¼ÐÐ,ÔÚÖ¡¿ªÊ¼ºó²¶»ñµÚÒ»ÐÐ
HAL_DCMI_Init(&hdcmi) ;
HAL_NVIC_SetPriority(DCMI_IRQn, 0 ,5); // ÉèÖÃÖжÏÓÅÏȼ¶
HAL_NVIC_EnableIRQ(DCMI_IRQn); // ¿ªÆôDCMIÖжÏ
//// ÔÚJPGģʽÏ£¬Ò»¶¨Òªµ¥¶ÀʹÄܸÃÖжÏ
// __HAL_DCMI_ENABLE_IT(&hdcmi, DCMI_IT_FRAME); // ʹÄÜ FRAME ÖжÏ
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DMA_Init
*
* º¯Êý¹¦ÄÜ: ÅäÖà DMA Ïà¹Ø²ÎÊý
*
* ˵ Ã÷: ʹÓõÄÊÇDMA2£¬ÍâÉèµ½´æ´¢Æ÷ģʽ¡¢Êý¾Ýλ¿í32bit¡¢²¢¿ªÆôÖжÏ
*
*****************************************************************************************************************************************/
void OV2640_DMA_Init(void)
{
__HAL_RCC_DMA2_CLK_ENABLE(); // ʹÄÜDMA2ʱÖÓ
DMA_Handle_dcmi.Instance = DMA2_Stream7; // DMA2Êý¾ÝÁ÷7
DMA_Handle_dcmi.Init.Request = DMA_REQUEST_DCMI; // DMAÇëÇóÀ´×ÔDCMI
DMA_Handle_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY; // ÍâÉèµ½´æ´¢Æ÷ģʽ
DMA_Handle_dcmi.Init.PeriphInc = DMA_PINC_DISABLE; // ÍâÉèµØÖ·½ûÖ¹×ÔÔö
DMA_Handle_dcmi.Init.MemInc = DMA_MINC_ENABLE; // ´æ´¢Æ÷µØÖ·×ÔÔö
DMA_Handle_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; // DCMIÊý¾Ýλ¿í£¬32λ
DMA_Handle_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; // ´æ´¢Æ÷Êý¾Ýλ¿í£¬32λ
DMA_Handle_dcmi.Init.Mode = DMA_CIRCULAR; // Ñ»·Ä£Ê½
DMA_Handle_dcmi.Init.Priority = DMA_PRIORITY_LOW; // ÓÅÏȼ¶µÍ
DMA_Handle_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE; // ʹÄÜfifo
DMA_Handle_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; // È«fifoģʽ£¬4*32bit´óС
DMA_Handle_dcmi.Init.MemBurst = DMA_MBURST_SINGLE; // µ¥´Î´«Êä
DMA_Handle_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE; // µ¥´Î´«Êä
HAL_DMA_Init(&DMA_Handle_dcmi); // ÅäÖÃDMA
__HAL_LINKDMA(&hdcmi, DMA_Handle, DMA_Handle_dcmi); // ¹ØÁªDCMI¾ä±ú
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0); // ÉèÖÃÖжÏÓÅÏȼ¶
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn); // ʹÄÜÖжÏ
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Delay
* Èë¿Ú²ÎÊý: Delay - ÑÓʱʱ¼ä£¬µ¥Î» ms
* º¯Êý¹¦ÄÜ: ¼òµ¥ÑÓʱº¯Êý£¬²»ÊǺܾ«È·
* ˵ Ã÷: ΪÁËÒÆÖ²µÄ¼ò±ãÐÔ,´Ë´¦²ÉÓÃÈí¼þÑÓʱ£¬Êµ¼ÊÏîÄ¿ÖпÉÒÔÌæ»»³ÉRTOSµÄÑÓʱ»òÕßHAL¿âµÄÑÓʱ
*****************************************************************************************************************************************/
void OV2640_Delay(volatile uint32_t Delay)
{
volatile uint16_t i;
while (Delay --)
{
for (i = 0; i < 20000; i++);
}
// HAL_Delay(Delay); // ¿ÉʹÓÃHAL¿âµÄÑÓʱ
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: DCMI_OV2640_Init
*
* º¯Êý¹¦ÄÜ: ³õʼSCCB¡¢DCMI¡¢DMAÒÔ¼°ÅäÖÃOV2640
*
*****************************************************************************************************************************************/
int8_t DCMI_OV2640_Init(void)
{
uint16_t Device_ID; // ¶¨Òå±äÁ¿´æ´¢Æ÷¼þID
SCCB_GPIO_Config(); // SCCBÒý½Å³õʼ»¯
MX_DCMI_Init(); // ³õʼ»¯DCMIÅäÖÃÒý½Å
OV2640_DMA_Init(); // ³õʼ»¯DMAÅäÖÃ
OV2640_Reset(); // Ö´ÐÐÈí¼þ¸´Î»
Device_ID = OV2640_ReadID(); // ¶ÁÈ¡Æ÷¼þID
if( (Device_ID == 0x2640) || (Device_ID == 0x2642) ) // ½øÐÐÆ¥Å䣬ʵ¼ÊµÄÆ÷¼þID¿ÉÄÜÊÇ 0x2640 »òÕß 0x2642
{
printf ("OV2640 OK,ID:0x%X\r\n",Device_ID); // Æ¥Åäͨ¹ý
OV2640_Config( OV2640_SVGA_Config ); // ÅäÖà SVGAģʽ ------> 800*600£¬ ×î´óÖ¡ÂÊ30Ö¡
// OV2640_Config( OV2640_UXGA_Config ); // ÅäÖà UXGAģʽ ------> 1600*1200£¬×î´óÖ¡ÂÊ15Ö¡
OV2640_Set_Framesize(OV2640_Width,OV2640_Height); // ÉèÖÃOV2640Êä³öµÄͼÏñ´óС
OV2640_DCMI_Crop(Display_Width, Display_Height, OV2640_Width, OV2640_Height ); // ½«OV2640Êä³öͼÏñ²Ã¼ô³ÉÊÊÓ¦ÆÁÄ»µÄ´óС
return OV2640_Success; // ·µ»Ø³É¹¦±êÖ¾
}
else
{
printf ("OV2640 ERROR!!!!! ID:%X\r\n",Device_ID); // ¶ÁÈ¡ID´íÎó
return OV2640_Error; // ·µ»Ø´íÎó±êÖ¾
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DMA_Transmit_Continuous
*
* Èë¿Ú²ÎÊý: DMA_Buffer - DMA½«Òª´«ÊäµÄµØÖ·£¬¼´ÓÃÓÚ´æ´¢ÉãÏñÍ·Êý¾ÝµÄ´æ´¢ÇøµØÖ·
* DMA_BufferSize - ´«ÊäµÄÊý¾Ý´óС£¬32λ¿í
*
* º¯Êý¹¦ÄÜ: Æô¶¯DMA´«Ê䣬Á¬ÐøÄ£Ê½
*
* ˵ Ã÷: 1. ¿ªÆôÁ¬ÐøÄ£Ê½Ö®ºó£¬»áÒ»Ö±½øÐд«Ê䣬³ý·Ç¹ÒÆð»òÕßÍ£Ö¹DCMI
* 2. OV2640ʹÓÃRGB565ģʽʱ£¬1¸öÏñËØµãÐèÒª2¸ö×Ö½ÚÀ´´æ´¢
* 3. ÒòΪDMAÅäÖô«ÊäÊý¾ÝΪ32λ¿í£¬¼ÆËã DMA_BufferSize ʱ£¬ÐèÒª³ýÒÔ4£¬ÀýÈ磺
* Òª»ñÈ¡ 240*240·Ö±æÂÊ µÄͼÏñ£¬ÐèÒª´«Êä 240*240*2 = 115200 ×Ö½ÚµÄÊý¾Ý£¬
* Ôò DMA_BufferSize = 115200 / 4 = 28800 ¡£
*LXB
*****************************************************************************************************************************************/
void OV2640_DMA_Transmit_Continuous(uint32_t DMA_Buffer,uint32_t DMA_BufferSize)
{
DMA_Handle_dcmi.Init.Mode = DMA_CIRCULAR; // Ñ»·Ä£Ê½
HAL_DMA_Init(&DMA_Handle_dcmi); // ÅäÖÃDMA
// ʹÄÜDCMI²É¼¯Êý¾Ý,Á¬Ðø²É¼¯Ä£Ê½
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)DMA_Buffer,DMA_BufferSize);
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DMA_Transmit_Snapshot
*
* Èë¿Ú²ÎÊý: DMA_Buffer - DMA½«Òª´«ÊäµÄµØÖ·£¬¼´ÓÃÓÚ´æ´¢ÉãÏñÍ·Êý¾ÝµÄ´æ´¢ÇøµØÖ·
* DMA_BufferSize - ´«ÊäµÄÊý¾Ý´óС£¬32λ¿í
*
* º¯Êý¹¦ÄÜ: Æô¶¯DMA´«Ê䣬¿ìÕÕģʽ£¬´«Êäһ֡ͼÏñºóÍ£Ö¹
*
* ˵ Ã÷: 1. ¿ìÕÕģʽ£¬Ö»´«ÊäÒ»Ö¡µÄÊý¾Ý
* 2. OV2640ʹÓÃRGB565ģʽʱ£¬1¸öÏñËØµãÐèÒª2¸ö×Ö½ÚÀ´´æ´¢
* 3. ÒòΪDMAÅäÖô«ÊäÊý¾ÝΪ32λ¿í£¬¼ÆËã DMA_BufferSize ʱ£¬ÐèÒª³ýÒÔ4£¬ÀýÈ磺
* Òª»ñÈ¡ 240*240·Ö±æÂÊ µÄͼÏñ£¬ÐèÒª´«Êä 240*240*2 = 115200 ×Ö½ÚµÄÊý¾Ý£¬
* Ôò DMA_BufferSize = 115200 / 4 = 28800 ¡£
* 4. ʹÓøÃģʽ´«ÊäÍê³ÉÖ®ºó£¬DCMI»á±»¹ÒÆð£¬ÔÙ´ÎÆôÓô«Êä֮ǰ£¬ÐèÒªµ÷Óà OV2640_DCMI_Resume() »Ö¸´DCMI
*
*****************************************************************************************************************************************/
void OV2640_DMA_Transmit_Snapshot(uint32_t DMA_Buffer,uint32_t DMA_BufferSize)
{
DMA_Handle_dcmi.Init.Mode = DMA_NORMAL; // Õý³£Ä£Ê½
HAL_DMA_Init(&DMA_Handle_dcmi); // ÅäÖÃDMA
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)DMA_Buffer,DMA_BufferSize);
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DCMI_Suspend
*
* º¯Êý¹¦ÄÜ: ¹ÒÆðDCMI£¬Í£Ö¹²¶»ñÊý¾Ý
*
* ˵ Ã÷: 1. ¿ªÆôÁ¬ÐøÄ£Ê½Ö®ºó£¬ÔÙµ÷Óøú¯Êý£¬»áÍ£Ö¹²¶»ñDCMIµÄÊý¾Ý
* 2. ¿ÉÒÔµ÷ÓÃ OV2640_DCMI_Resume() »Ö¸´DCMI
* 3. ÐèҪעÒâµÄ£¬¹ÒÆðDCMIÆÚ¼ä£¬DMAÊÇûÓÐÍ£Ö¹¹¤×÷µÄ
*LXB
*****************************************************************************************************************************************/
void OV2640_DCMI_Suspend(void)
{
HAL_DCMI_Suspend(&hdcmi); // ¹ÒÆðDCMI
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DCMI_Resume
*
* º¯Êý¹¦ÄÜ: »Ö¸´DCMI£¬¿ªÊ¼²¶»ñÊý¾Ý
*
* ˵ Ã÷: 1. µ±DCMI±»¹ÒÆðʱ£¬¿ÉÒÔµ÷Óøú¯Êý»Ö¸´
* 2. ʹÓà OV2640_DMA_Transmit_Snapshot() ¿ìÕÕģʽ£¬´«ÊäÍê³ÉÖ®ºó£¬DCMIÒ²»á±»¹ÒÆð£¬ÔÙ´ÎÆôÓô«Êä֮ǰ£¬
* ÐèÒªµ÷Óñ¾º¯Êý»Ö¸´DCMI²¶»ñ
*
*****************************************************************************************************************************************/
void OV2640_DCMI_Resume(void)
{
(&hdcmi)->State = HAL_DCMI_STATE_BUSY; // ±ä¸üDCMI±êÖ¾
(&hdcmi)->Instance->CR |= DCMI_CR_CAPTURE; // ¿ªÆôDCMI²¶»ñ
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DCMI_Stop
*
* º¯Êý¹¦ÄÜ: ½ûÖ¹DCMIµÄDMAÇëÇó£¬Í£Ö¹DCMI²¶»ñ£¬½ûÖ¹DCMIÍâÉè
*
*****************************************************************************************************************************************/
void OV2640_DCMI_Stop(void)
{
HAL_DCMI_Stop(&hdcmi);
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_DCMI_Crop
*
* Èë¿Ú²ÎÊý: Displey_XSize ¡¢Displey_YSize - ÏÔʾÆ÷µÄ³¤¿í
* Sensor_XSize¡¢Sensor_YSize - ÉãÏñÍ·´«¸ÐÆ÷Êä³öͼÏñµÄ³¤¿í
*
* º¯Êý¹¦ÄÜ: ʹÓÃDCMIµÄ²Ã¼ô¹¦ÄÜ£¬½«´«¸ÐÆ÷Êä³öµÄͼÏñ²Ã¼ô³ÉÊÊÓ¦ÆÁÄ»µÄ´óС
*
* ˵ Ã÷: 1. ÒòΪÉãÏñÍ·Êä³öµÄ»Ãæ±ÈÀý¹Ì¶¨Îª4:3£¬²»Ò»¶¨Æ¥ÅäÏÔʾÆ÷
* 2. ÐèҪעÒâµÄÊÇ£¬ÉãÏñÍ·Êä³öµÄͼÏñ³¤¡¢¿í±ØÐëÒªÄܱ»4Õû³ý£¡£¨ ʹÓÃOV2640_Set_Framesizeº¯Êý½øÐÐÉèÖà £©
* 3. DCMIµÄˮƽÓÐЧÏñËØÒ²±ØÐëÒªÄܱ»4Õû³ý£¡
* 4. º¯Êý»á¼ÆËãˮƽºÍ´¹Ö±Æ«ÒÆ£¬¾¡Á¿ÈÃ»Ãæ¾ÓÖвüô
*****************************************************************************************************************************************/
int8_t OV2640_DCMI_Crop(uint16_t Displey_XSize,uint16_t Displey_YSize,uint16_t Sensor_XSize,uint16_t Sensor_YSize )
{
uint16_t DCMI_X_Offset,DCMI_Y_Offset; // ˮƽºÍ´¹Ö±Æ«ÒÆ£¬´¹Ö±´ú±íµÄÊÇÐÐÊý£¬Ë®Æ½´ú±íµÄÊÇÏñËØÊ±ÖÓÊý£¨PCLKÖÜÆÚÊý£©
uint16_t DCMI_CAPCNT; // ˮƽÓÐЧÏñËØ£¬´ú±íµÄÊÇÏñËØÊ±ÖÓÊý£¨PCLKÖÜÆÚÊý£©
uint16_t DCMI_VLINE; // ´¹Ö±ÓÐЧÐÐÊý
if( (Displey_XSize>=Sensor_XSize)|| (Displey_YSize>=Sensor_YSize) )
{
// printf("ʵ¼ÊÏÔʾµÄ³ß´ç´óÓÚ»òµÈÓÚÉãÏñÍ·Êä³öµÄ³ß´ç£¬Í˳öDCMI²Ã¼ô\r\n");
return OV2640_Error; //Èç¹ûʵ¼ÊÏÔʾµÄ³ß´ç´óÓÚ»òµÈÓÚÉãÏñÍ·Êä³öµÄ³ß´ç£¬ÔòÍ˳öµ±Ç°º¯Êý£¬²»½øÐвüô
}
// ÔÚÉèÖÃΪRGB565¸ñʽʱ£¬Ë®Æ½Æ«ÒÆ£¬±ØÐëÊÇÆæÊý£¬·ñÔò»ÃæÉ«²Ê²»ÕýÈ·£¬
// ÒòΪһ¸öÓÐЧÏñËØÊÇ2¸ö×Ö½Ú£¬ÐèÒª2¸öPCLKÖÜÆÚ£¬ËùÒÔ±ØÐë´ÓÆæÊýλ¿ªÊ¼£¬²»È»Êý¾Ý»á´íÂÒ£¬
// ÐèҪעÒâµÄÊÇ£¬¼Ä´æÆ÷ÖµÊÇ´Ó0¿ªÊ¼ËãÆðµÄ £¡
DCMI_X_Offset = Sensor_XSize - Displey_XSize; // ʵ¼Ê¼ÆËã¹ý³ÌΪ£¨Sensor_XSize - LCD_XSize£©/2*2
// ¼ÆËã´¹Ö±Æ«ÒÆ£¬¾¡Á¿ÈÃ»Ãæ¾ÓÖвüô£¬¸ÃÖµ´ú±íµÄÊÇÐÐÊý£¬
DCMI_Y_Offset = (Sensor_YSize - Displey_YSize)/2-1; // ¼Ä´æÆ÷ÖµÊÇ´Ó0¿ªÊ¼ËãÆðµÄ£¬ËùÒÔÒª-1
// ÒòΪһ¸öÓÐЧÏñËØÊÇ2¸ö×Ö½Ú£¬ÐèÒª2¸öPCLKÖÜÆÚ£¬ËùÒÔÒª³Ë2
// ×îÖյõ½µÄ¼Ä´æÆ÷Öµ£¬±ØÐëÒªÄܱ»4Õû³ý£¡
DCMI_CAPCNT = Displey_XSize*2-1; // ¼Ä´æÆ÷ÖµÊÇ´Ó0¿ªÊ¼ËãÆðµÄ£¬ËùÒÔÒª-1
DCMI_VLINE = Displey_YSize-1; // ´¹Ö±ÓÐЧÐÐÊý
// printf("%d %d %d %d\r\n",DCMI_X_Offset,DCMI_Y_Offset,DCMI_CAPCNT,DCMI_VLINE);
HAL_DCMI_ConfigCrop (&hdcmi,DCMI_X_Offset,DCMI_Y_Offset,DCMI_CAPCNT,DCMI_VLINE);// ÉèÖòüô´°¿Ú
HAL_DCMI_EnableCrop(&hdcmi); // ʹÄܲüô
return OV2640_Success;
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Reset
*
* º¯Êý¹¦ÄÜ: Ö´ÐÐÈí¼þ¸´Î»
*
* ˵ Ã÷: ÔÚÅäÖÃOV2640֮ǰ£¬ÐèÒªÖ´ÐÐÒ»´ÎÈí¼þ¸´Î»
*
*****************************************************************************************************************************************/
void OV2640_Reset(void)
{
OV2640_Delay(5); // µÈ´ýÄ£¿éÉϵçÎȶ¨£¬×îÉÙ5ms£¬È»ºóÀµÍPWDN
OV2640_PWDN_OFF; // PWDN Òý½ÅÊä³öµÍµçƽ£¬²»¿ªÆôµôµçģʽ£¬ÉãÏñÍ·Õý³£¹¤×÷£¬´ËʱÉãÏñÍ·Ä£¿éµÄ°×É«LED»áµãÁÁ
// ¸ù¾ÝOV2640µÄÉϵçʱÐò£¬Ó²¼þ¸´Î»µÄ³ÖÐøÊ±¼äÒª>=3ms£¬Â¹Ð¡°àµÄOV2640²ÉÓÃÓ²¼þRC¸´Î»£¬³ÖÐøÊ±¼ä´ó¸ÅÔÚ6ms×óÓÒ
// Òò´Ë¼ÓÈëÑÓʱ£¬µÈ´ýÓ²¼þ¸´Î»Íê³É²¢Îȶ¨ÏÂÀ´
OV2640_Delay(5);
SCCB_WriteReg( OV2640_SEL_Registers, OV2640_SEL_SENSOR); // Ñ¡Ôñ SENSOR ¼Ä´æÆ÷×é
SCCB_WriteReg( OV2640_SENSOR_COM7, 0x80); // Æô¶¯Èí¼þ¸´Î»
// ¸ù¾ÝOV2640µÄÈí¼þ¸´Î»Ê±Ðò£¬Èí¼þ¸´Î»Ö´Ðкó£¬Òª>=2ms·½¿ÉÖ´ÐÐSCCBÅäÖ㬴˴¦²ÉÓñ£ÊØÒ»µãµÄ²ÎÊý£¬ÑÓʱ10ms
OV2640_Delay(10);
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_ReadID
*
* º¯Êý¹¦ÄÜ: ¶ÁÈ¡ OV2640 µÄÆ÷¼þID
*
* ˵ Ã÷: ʵ¼ÊµÄÆ÷¼þID¿ÉÄÜÊÇ 0x2640 »òÕß 0x2642£¬Åú´Î²»Í¬ID¿ÉÄܻ᲻һÑù
*
*****************************************************************************************************************************************/
uint16_t OV2640_ReadID(void)
{
uint8_t PID_H,PID_L; // ID±äÁ¿
SCCB_WriteReg( OV2640_SEL_Registers, OV2640_SEL_SENSOR); // Ñ¡Ôñ SENSOR ¼Ä´æÆ÷×é
PID_H = SCCB_ReadReg(OV2640_SENSOR_PIDH); // ¶ÁÈ¡ID¸ß×Ö½Ú
PID_L = SCCB_ReadReg(OV2640_SENSOR_PIDL); // ¶ÁÈ¡IDµÍ×Ö½Ú
return(PID_H<<8)|PID_L; // ·µ»ØÍêÕûµÄÆ÷¼þID
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Config
*
* Èë¿Ú²ÎÊý: (*ConfigData)[2] - ÒªÅäÖõIJÎÊý£¬¿ÉÅäÖÃΪ OV2640_SVGA_Config »ò OV2640_UXGA_Config
*
* º¯Êý¹¦ÄÜ: ÅäÖà OV2640 ´«¸ÐÆ÷ºÍDSP²ÎÊý
*
* ˵ Ã÷: 1. ¿ÉÅäÖÃΪ SVGA »òÕß UXGAģʽ
* 2. SVGA ·Ö±æÂÊΪ800*600£¬×î¸ßÖ§³Ö30Ö¡
* 3. UXGA ·Ö±æÂÊΪ1600*1200£¬×î¸ßÖ§³Ö15Ö¡
* 4. ²ÎÊý¶¨ÒåÔÚ dcmi_ov2640_cfg.h
*
*****************************************************************************************************************************************/
void OV2640_Config( const uint8_t (*ConfigData)[2] )
{
uint32_t i; // ¼ÆÊý±äÁ¿
for( i=0; ConfigData[i][0]; i++)
{
SCCB_WriteReg( ConfigData[i][0], ConfigData[i][1]); // ½øÐвÎÊýÅäÖÃ
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Framesize
*
* Èë¿Ú²ÎÊý: pixformat - ÏñËØ¸ñʽ£¬¿ÉÑ¡Ôñ Pixformat_RGB565¡¢Pixformat_JPEG
*
* º¯Êý¹¦ÄÜ: ÉèÖÃÊä³öµÄÏñËØ¸ñʽ
*
*****************************************************************************************************************************************/
void OV2640_Set_Pixformat(uint8_t pixformat)
{
const uint8_t (*ConfigData)[2];
uint32_t i; // ¼ÆÊý±äÁ¿
switch (pixformat)
{
case Pixformat_RGB565:
ConfigData = OV2640_RGB565_Config;
break;
case Pixformat_JPEG:
ConfigData = OV2640_JPEG_Config;
break;
default: break;
}
for( i=0; ConfigData[i][0]; i++)
{
SCCB_WriteReg( ConfigData[i][0], ConfigData[i][1]); // ½øÐвÎÊýÅäÖÃ
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Framesize
*
* Èë¿Ú²ÎÊý: width - ʵ¼ÊÊä³öͼÏñµÄ³¤¶È£¬height - ʵ¼ÊÊä³öͼÏñµÄ¿í¶È
*
* º¯Êý¹¦ÄÜ: ÉèÖÃʵ¼ÊÊä³öµÄͼÏñ´óС
*
* ˵ Ã÷: 1. OV2640ÉèÖÃΪ SVGA£¨800*600£© »òÕß UXGA£¨1600*1200£©Ä£Ê½£¬Í¼Ïñ´óСͨ³£Óëʵ¼ÊÓÃµÄÆÁÄ»·Ö±æÂʲ»Ò»Ñù£¬
* Òò´Ë¿ÉÒÔµ÷Óôκ¯Êý£¬ÉèÖÃʵ¼ÊÊä³öµÄͼÏñ´óС
* 2. ÐèҪעÒâµÄÊÇ£¬ÒªÉèÖõÄͼÏñ³¤¡¢¿í±ØÐëÄܱ»4Õû³ý£¡
* 3. ²¢²»ÊÇÉèÖÃÊä³öµÄͼÏñ·Ö±æÂÊԽС֡ÂʾÍÔ½¸ß£¬Ö¡ÂÊÖ»ºÍÅäÖõÄģʽÓйأ¬ÀýÈçÅäÖÃΪSVGA×î¸ßÖ»ÄÜÖ§³Ö30Ö¡
*
*****************************************************************************************************************************************/
int8_t OV2640_Set_Framesize(uint16_t width,uint16_t height)
{
if( (width%4)||(height%4) ) // Êä³öͼÏñµÄ´óСһ¶¨ÒªÄܱ»4Õû³ý
{
return OV2640_Error; // ·µ»Ø´íÎó±êÖ¾
}
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_DSP); // Ñ¡Ôñ DSP¼Ä´æÆ÷×é
SCCB_WriteReg(0X5A, width/4 &0XFF); // ʵ¼ÊͼÏñÊä³öµÄ¿í¶È£¨OUTW£©£¬7~0 bit£¬¼Ä´æÆ÷µÄÖµµÈÓÚʵ¼ÊÖµ/4
SCCB_WriteReg(0X5B, height/4 &0XFF); // ʵ¼ÊͼÏñÊä³öµÄ¸ß¶È£¨OUTH£©£¬7~0 bit£¬¼Ä´æÆ÷µÄÖµµÈÓÚʵ¼ÊÖµ/4
SCCB_WriteReg(0X5C, (width/4>>8&0X03)|(height/4>>6&0x04) ); // ÉèÖÃZMHHµÄBit[2:0]£¬Ò²¾ÍÊÇOUTH µÄµÚ 8 bit£¬OUTW µÄµÚ 9~8 bit£¬
SCCB_WriteReg(OV2640_DSP_RESET,0X00); // ¸´Î»
return OV2640_Success; // ³É¹¦
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Horizontal_Mirror
*
* Èë¿Ú²ÎÊý: ConfigState - ÖÃ1ʱ£¬Í¼Ïñ»áˮƽ¾µÏñ£¬ÖÃ0ʱ»Ö¸´Õý³£
*
* º¯Êý¹¦ÄÜ: ÓÃÓÚÉèÖÃÊä³öµÄͼÏñÊÇ·ñ½øÐÐˮƽ¾µÏñ
*
*****************************************************************************************************************************************/
int8_t OV2640_Set_Horizontal_Mirror( int8_t ConfigState )
{
uint8_t OV2640_Reg; // ¼Ä´æÆ÷µÄÖµ
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_SENSOR); // Ñ¡Ôñ SENSOR ¼Ä´æÆ÷×é
OV2640_Reg = SCCB_ReadReg(OV2640_SENSOR_REG04); // ¶ÁÈ¡ 0x04 µÄ¼Ä´æÆ÷Öµ
// REG04,¼Ä´æÆ÷×é4£¬¼Ä´æÆ÷µØÖ·Îª 0x04£¬¸Ã¼Ä´æÆ÷µÄBit[7]£¬ÓÃÓÚÉèÖÃˮƽÊÇ·ñ¾µÏñ
if ( ConfigState == OV2640_Enable ) // Èç¹ûʹÄܾµÏñ
{
OV2640_Reg |= 0X80; // Bit[7]ÖÃ1Ôò¾µÏñ
}
else // È¡Ïû¾µÏñ
{
OV2640_Reg &= ~0X80; // Bit[7]ÖÃ0ÔòÊÇÕý³£Ä£Ê½
}
return SCCB_WriteReg(OV2640_SENSOR_REG04,OV2640_Reg); // дÈë¼Ä´æÆ÷
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Vertical_Flip
*
* Èë¿Ú²ÎÊý: ConfigState - ÖÃ1ʱ£¬Í¼Ïñ»á´¹Ö±·×ª£¬ÖÃ0ʱ»Ö¸´Õý³£
*
* º¯Êý¹¦ÄÜ: ÓÃÓÚÉèÖÃÊä³öµÄͼÏñÊÇ·ñ½øÐд¹Ö±·×ª
*
*****************************************************************************************************************************************/
int8_t OV2640_Set_Vertical_Flip( int8_t ConfigState )
{
uint8_t OV2640_Reg; // ¼Ä´æÆ÷µÄÖµ
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_SENSOR); // Ñ¡Ôñ SENSOR ¼Ä´æÆ÷×é
OV2640_Reg = SCCB_ReadReg(OV2640_SENSOR_REG04); // ¶ÁÈ¡ 0x04 µÄ¼Ä´æÆ÷Öµ
// REG04,¼Ä´æÆ÷×é4£¬¼Ä´æÆ÷µØÖ·Îª 0x04£¬¸Ã¼Ä´æÆ÷µÄµÚBit[6]£¬ÓÃÓÚÉèÖÃˮƽÊÇ´¹Ö±·×ª
if ( ConfigState == OV2640_Enable )
{
// ´Ë´¦ÉèÖòο¼OpenMVµÄÇý¶¯
// Bit[4]¾ßÌåµÄ×÷ÓÃÊÇʲôÊÖ²áûÓÐ˵£¬Èç¹û´¹Ö±·×ªÖ®ºó£¬¸Ãλ²»ÖÃ1µÄ»°£¬ÑÕÉ«»á²»¶Ô
OV2640_Reg |= 0X40|0x10 ; // Bit[6]ÖÃ1ʱ£¬Í¼Ïñ»á´¹Ö±·×ª
}
else // È¡Ïû·×ª
{
OV2640_Reg &= ~(0X40|0x10 ); // ½«Bit[6]ºÍBit[4]¶¼Ð´0
}
return SCCB_WriteReg(OV2640_SENSOR_REG04,OV2640_Reg); // дÈë¼Ä´æÆ÷
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Saturation
*
* Èë¿Ú²ÎÊý: Saturation - ±¥ºÍ¶È£¬¿ÉÉèÖÃΪ5¸öµÈ¼¶£º2£¬1£¬0£¬-1£¬-2
*
* ˵ Ã÷: 1. ÊÖ²áÀïûÓÐ˵Ã÷ÅäÖÃÖеÄÄÇ2¸ö¼Ä´æÆ÷ÈçºÎʹÓã¬Òò´ËÕâÀïÖ±½ÓʹÓÃOV2640±à³ÌÊÖ²á¸ø³öµÄ´úÂë
* 2.±¥ºÍ¶ÈÔ½¸ß£¬É«²Ê¾ÍÔ½ÏÊÑÞ£¬µ«µ±ÏàÓ¦µÄÇåÎú¶È»áϽµ£¬Ôëµã±ä¶à
*
*****************************************************************************************************************************************/
void OV2640_Set_Saturation(int8_t Saturation)
{
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_DSP); // Ñ¡Ôñ DSP¼Ä´æÆ÷×é
switch (Saturation)
{
case 2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x02);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x03);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x68);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x68);
break;
case 1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x02);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x03);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x58);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x58);
break;
case 0:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x02);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x03);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x48);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x48);
break;
case -1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x02);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x03);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x38);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x38);
break;
case -2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x02);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x03);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x28);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x28);
break;
default: break;
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Brightness
*
* Èë¿Ú²ÎÊý: Brightness - ÁÁ¶È£¬¿ÉÉèÖÃΪ5¸öµÈ¼¶£º2£¬1£¬0£¬-1£¬-2
*
* ˵ Ã÷: 1. ÊÖ²áÀïûÓÐ˵Ã÷ÅäÖÃÖеÄÄÇ2¸ö¼Ä´æÆ÷ÈçºÎʹÓã¬Òò´ËÕâÀïÖ±½ÓʹÓÃOV2640±à³ÌÊÖ²á¸ø³öµÄ´úÂë
* 2. ÁÁ¶ÈÔ½¸ß£¬»Ãæ¾ÍÔ½Ã÷ÁÁ£¬µ«ÊÇ»á±äÄ£ºýһЩ
*
*****************************************************************************************************************************************/
void OV2640_Set_Brightness(int8_t Brightness)
{
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_DSP); // Ñ¡Ôñ DSP¼Ä´æÆ÷×é
switch (Brightness)
{
case 2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x09);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x40);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
break;
case 1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x09);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x30);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
break;
case 0:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x09);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
break;
case -1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x09);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x10);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
break;
case -2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x09);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
break;
default: break;
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Contrast
*
* Èë¿Ú²ÎÊý: Contrast - ¶Ô±È¶È£¬¿ÉÉèÖÃΪ5¸öµÈ¼¶£º2£¬1£¬0£¬-1£¬-2
*
* ˵ Ã÷: 1. ÊÖ²áÀïûÓÐ˵Ã÷ÅäÖÃÖеÄÄÇ2¸ö¼Ä´æÆ÷ÈçºÎʹÓã¬Òò´ËÕâÀïÖ±½ÓʹÓÃOV2640±à³ÌÊÖ²á¸ø³öµÄ´úÂë
* 2. ¶Ô±È¶ÈÔ½¸ß£¬»ÃæÔ½ÇåÎú£¬ºÚ°×Ô½¼Ó·ÖÃ÷
*
*****************************************************************************************************************************************/
void OV2640_Set_Contrast(int8_t Contrast)
{
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_DSP); // Ñ¡Ôñ DSP¼Ä´æÆ÷×é
switch (Contrast)
{
case 2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x07);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x28);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x0c);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x06);
break;
case 1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x07);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x24);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x16);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x06);
break;
case 0:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x07);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x20);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x06);
break;
case -1:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x07);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x1c);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x2a);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x06);
break;
case -2:
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x04);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x07);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x20);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x18);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x34);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x06);
break;
default: break;
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: OV2640_Set_Effect
*
* Èë¿Ú²ÎÊý: effect_Mode - ÌØÐ§Ä£Ê½£¬¿ÉÑ¡Ôñ²ÎÊý OV2640_Effect_Normal¡¢OV2640_Effect_Negative¡¢
* OV2640_Effect_BW¡¢OV2640_Effect_BW_Negative
*
* º¯Êý¹¦ÄÜ: ÓÃÓÚÉèÖÃOV2640µÄÌØÐ§£¬Õý³£¡¢¸ºÆ¬¡¢ºÚ°×¡¢ºÚ°×+¸ºÆ¬µÈģʽ
*
* ˵ Ã÷: ÊÖ²áÀïûÓÐ˵Ã÷ÅäÖÃÖеÄÄÇ2¸ö¼Ä´æÆ÷ÈçºÎʹÓã¬Òò´ËÕâÀïÖ±½ÓʹÓÃOV2640±à³ÌÊÖ²á¸ø³öµÄ´úÂë
*
*****************************************************************************************************************************************/
void OV2640_Set_Effect(uint8_t effect_Mode)
{
SCCB_WriteReg(OV2640_SEL_Registers,OV2640_SEL_DSP); // Ñ¡Ôñ DSP¼Ä´æÆ÷×é
switch (effect_Mode)
{
case OV2640_Effect_Normal: // Õý³£Ä£Ê½
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x00);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x05);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
break;
case OV2640_Effect_Negative: // ¸ºÆ¬Ä£Ê½£¬Ò²¾ÍÊÇÑÕɫȫ²¿È¡·´
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x40);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x05);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
break;
case OV2640_Effect_BW: // ºÚ°×ģʽ
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x18);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x05);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
break;
case OV2640_Effect_BW_Negative: // ºÚ°×+¸ºÆ¬Ä£Ê½
SCCB_WriteReg(OV2640_DSP_BPADDR,0x00);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x58);
SCCB_WriteReg(OV2640_DSP_BPADDR,0x05);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
SCCB_WriteReg(OV2640_DSP_BPDATA,0x80);
break;
default: break;
}
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: HAL_DCMI_FrameEventCallback
*
* º¯Êý¹¦ÄÜ: Ö¡»Øµ÷º¯Êý£¬Ã¿´«ÊäÒ»Ö¡Êý¾Ý£¬»á½øÈë¸ÃÖжϷþÎñº¯Êý
*
* ˵ Ã÷: ÿ´Î´«ÊäÍêÒ»Ö¡£¬¶ÔÏàÓ¦µÄ±ê־λ½øÐвÙ×÷£¬²¢¼ÆËãÖ¡ÂÊ
*****************************************************************************************************************************************/
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
static uint32_t DCMI_Tick = 0; // ÓÃÓÚ±£´æµ±Ç°µÄʱ¼ä¼ÆÊýÖµ
static uint8_t DCMI_Frame_Count = 0; // Ö¡Êý¼ÆÊý
if(HAL_GetTick() - DCMI_Tick >= 1000) // ÿ¸ô 1s ¼ÆËãÒ»´ÎÖ¡ÂÊ
{
DCMI_Tick = HAL_GetTick(); // ÖØÐ»ñÈ¡µ±Ç°Ê±¼ä¼ÆÊýÖµ
OV2640_FPS = DCMI_Frame_Count; // »ñµÃfps
DCMI_Frame_Count = 0; // ¼ÆÊýÇå0
}
DCMI_Frame_Count ++; // û½øÈëÒ»´ÎÖжϣ¨Ã¿´Î´«ÊäÍêÒ»Ö¡Êý¾Ý£©£¬¼ÆÊýÖµ+1
DCMI_FrameState = 1; // ´«ÊäÍê³É±ê־λÖÃ1
}
/***************************************************************************************************************************************
* º¯ Êý Ãû: HAL_DCMI_ErrorCallback
*
* º¯Êý¹¦ÄÜ: ´íÎ󻨵÷º¯Êý
*
* ˵ Ã÷: µ±·¢ÉúDMA´«Êä´íÎó»òÕßFIFOÒç³ö´íÎó¾Í»á½øÈë
*****************************************************************************************************************************************/
void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
{
// if( HAL_DCMI_GetError(hdcmi) == HAL_DCMI_ERROR_OVR)
// {
// printf("FIFOÒç³ö´íÎ󣡣¡£¡\r\n");
// }
printf("error:0x%x£¡£¡£¡\r\n",HAL_DCMI_GetError(hdcmi));
}
/*********************************************************************************************************************************************************************************************************************************************LXB*************/
// ¹С°à
代码分析