不多說話
Show you the code.
其中TCP的封包使用了大神造的輪子,直接拖過來用。
main.c
/*********************************************************************** 文件名稱:main.C 功 能: 編寫時間: 注 意: ***********************************************************************/ #include "main.h" OV2640_IDTypeDef ov2640type; void Init_OV2640(void); /*********************************************************************** 函數名稱:void Init_Wifi(void) 功 能:wifi相關的初始化 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void Init_Wifi(void) { int ret; u32_t addr; ZQWL_System_Clock_Init(); //初始化時鍾 OSStatInit(); //初始化UCOS狀態,必須在初始化時鍾之后調用 USART_Configuration(); //初始化串口 ret = SD_Init(); //初始化SDIO設備 if (ret != 0) //如果失敗 { printf("SD_Init faild!\n"); // LED4_ON; while(1); //程序停止運行 } ret = Init_W8782(); //初始化WIFI芯片 if(ret != 0) //如果失敗 { printf("init wifi faild!\n"); while(1); //程序停止運行 } printf("Init_W8782 ok!\n"); Power_Mode(POWER_SAVE_MODE); //進入省電模式,OFF_POWER_SAVE_MODE為退出省電模式 Init_Lwip(); //初始化lwip協議棧,並初始化了板子的IP //以下創建一個AP ret = Init_Udhcpd(); //初始化dhcp服務器,如果WIFI工作的STA模式下(與路由器連接)可以不用DHCP if(ret == -1) { printf("Init_Udhcpd faild!\n"); while(1); } printf("Init_Udhcpd ok!\n"); Enable_Dhcp_Server(); // 開啟dhcp服務器,如果工作在sta模式,可以不開啟dhcpserver ret = Create_AP("WPLINK-B814","510510510",KEY_WPA2,6,4);//創建AP,創建AP后就不要再調Wifi_Connect函數了 if(ret == -1) { printf("Create_AP faild!\n"); while(1); } printf("Create_AP ok!\n"); // //以下加入一個AP(路由器) //Wifi_Connect("TP-LINK_8E32A0","zhaohongjie123");//路由器名稱和密碼,該函數調用后,自動進入sta模式 //if(ret == -1) //{ // printf("Wifi_Connect faild!\n"); // while(1); //} // printf("Wifi_Connect ok!\n"); // } /*********************************************************************** 函數名稱:void main_thread(void *pdata) 功 能:主線程 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void main_thread(void *pdata) { Init_Wifi(); //初始化Wifi LED_Configuration(); //初始化LED Init_OV2640(); //初始化OV2640 thread_create(Task_TCP_server, 0, TASK_TCP_SERVER_PRIO, 0, TASK_TCP_SERVER_STK_SIZE, "Task_TCP_server"); thread_create(Task_TCP_server2, 0, TASK_TCP_SERVER_PRIO-1, 0, TASK_TCP_SERVER_STK_SIZE, "Task_TCP_server2"); while (1)//在此可以指定一個CPU運行指示燈閃爍,監視系統運行狀態 { GPIO_ToggleBits(LED4); OSTimeDlyHMSM(0, 0, 1, 0);//!!!!!!!!!! } } /*********************************************************************** 函數名稱:int main(void) 功 能:程序入口 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ int main(void) { OSInit(); _mem_init(); //初始化內存分配 thread_create(main_thread, 0, TASK_MAIN_PRIO, 0, TASK_MAIN_STACK_SIZE, "main_thread"); OSStart(); return 0; } /*********************************************************************** 函數名稱:void Init_OV2640(void) 功 能:初始化OV2640 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void Init_OV2640(void) { I2C_Configuration(); memset(&ov2640type,0x0,sizeof(ov2640type)); OV2640_ReadID(&ov2640type); printf("ov2640 chip id: 0x%02x , x%02x , x%02x , x%02x .\n",ov2640type.Manufacturer_ID1,ov2640type.Manufacturer_ID2,ov2640type.PIDH,ov2640type.PIDL); OV2640_JPEGConfig(JPEG_320x240); //配置OV2640輸出320*240像素的JPG圖片 OV2640_BrightnessConfig(0x20); OV2640_AutoExposure(2); OSTimeDlyHMSM(0, 0, 0, 100); OV2640_CaptureGpioInit(); //數據采集引腳初始化 EXTI->IMR &= ~EXTI_Line8; //關閉場同步中斷 EXTI->EMR &= ~EXTI_Line8; EXTI->IMR &= ~EXTI_Line11; //關閉像素同步中斷 EXTI->EMR &= ~EXTI_Line11; OSTimeDlyHMSM(0, 0, 0, 500); //等待圖像輸出穩定!!!!!!!!! EXTI->IMR |= EXTI_Line8; //使能場同步中斷,准備下次采集 EXTI->EMR |= EXTI_Line8; }
LED.c
/*********************************************************************** 文件名稱:LED.C 功 能:led IO初始化 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ #include "main.h" /*********************************************************************** 函數名稱:LED_Configuration(void) 功 能:完成LED的配置 輸入參數: 輸出參數: 編寫時間:2013.4.25 編 寫 人: 注 意: ***********************************************************************/ void LED_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable the GPIO_LED Clock */ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); /*****熄滅四個led燈******/ LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; } /*********************************************************************** 函數名稱:LED_Blink(void) 功 能:完成LED閃爍 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void LED_Blink(void) { /*****熄滅四個led燈******/ LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; LED_Delay(0x4fffff); /*****點亮四個led燈******/ LED1_ON; LED2_ON; LED3_ON; LED4_ON; LED_Delay(0x4fffff); } /*********************************************************************** 函數名稱:One_LED_ON(unsigned char led_num) 功 能:實現點亮一個LED燈 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void One_LED_ON(unsigned char led_num) { /*****熄滅四個led燈******/ LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; switch(led_num) { case 1: { LED1_ON; break; } case 2: { LED2_ON; break; } case 3: { LED3_ON; break; } case 4: { LED4_ON; break; } default: { break; } } } static LED_Delay(uint32_t nCount) { while(nCount > 0) { nCount --; } }
LED_Ctrl.c
/*********************************************************************** 文件名稱:LED_Ctrl.C 功 能: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ #include "main.h" /*********************************************************************** 函數名稱:void LED_Ctrl(unsigned char *data) 功 能:根據data的數據命令控制led的亮滅 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: 命令: led1_on LED1燈亮 led2_on LED2燈亮 led3_on LED3燈亮 led4_on LED4燈亮 led1_off LED1燈滅 led2_off LED2燈滅 led3_off LED3燈滅 led4_off LED4燈滅 ***********************************************************************/ void LED_Ctrl(unsigned char *data) { if(strncmp(&data[0],"led", 3) == 0)//是LED的控制數據 { switch(data[3]) //第3個字節是控制哪個LED的 { case '1': { if(strncmp(&data[4],"_on", 3) == 0)//如果是led1_on { LED1_ON; } else if(strncmp(&data[4],"_off", 4) == 0) { LED1_OFF; } break; } case '2': { if(strncmp(&data[4],"_on", 3) == 0)//如果是led1_on { LED2_ON; } else if(strncmp(&data[4],"_off", 4) == 0) { LED2_OFF; } break; } case '3': { if(strncmp(&data[4],"_on", 3) == 0)//如果是led1_on { LED3_ON; } else if(strncmp(&data[4],"_off", 4) == 0) { LED3_OFF; } break; } case '4': { if(strncmp(&data[4],"_on", 3) == 0)//如果是led1_on { LED4_ON; } else if(strncmp(&data[4],"_off", 4) == 0) { LED4_OFF; } break; } default: { break; } } } }
sys_misc.c
// #define DEBUG #include "main.h" void delay_1us() { int i = 25; while (i--) ; } void delay_us(uint32_t us) { while (us--) delay_1us(); } void assert_failed(uint8_t *file, uint32_t line) { p_err("assert_failed in:%s,line:%d \n", file ? file : "n", line); while (1) ; } void HardFault_Handler() { #if USE_MEM_DEBUG static int once = 0; if (!once) { once = 1; mem_slide_check(0); } #endif p_err("%s\n", __FUNCTION__); // printf("HardFault_Handler!"); while (1) ; } #if OS_APP_HOOKS_EN > 0u void App_TaskCreateHook(OS_TCB *ptcb) { ptcb = ptcb; } void App_TaskDelHook(OS_TCB *ptcb) { ptcb = ptcb; } void App_TaskReturnHook(OS_TCB *ptcb) { ptcb = ptcb; } void App_TCBInitHook(OS_TCB *ptcb) { ptcb = ptcb; } void App_TaskSwHook(void) { } void App_TimeTickHook(void){} //uC/OS-II Stat線程中調用此函數,每100MS一次 void App_TaskStatHook() { #if USE_MEM_DEBUG mem_slide_check(0); #endif //button_stat_callback(); } #endif
SCI.c
#include "main.H" /*********************************************************************** 文件名稱:SCI.C 功 能:完成對usart1和usart2的操作 編寫時間:2012.11.22 編 寫 人: 注 意:本例程是通過判斷兩個特定的字符來確定一幀數據是否結束的。 USART1 時鍾 : RCC_APB2PeriphClockCmd USART1~6 時鍾 :RCC_APB1PeriphClockCmd ***********************************************************************/ #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ PUTCHAR_PROTOTYPE { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ USART_SendData(USART1, (uint8_t) ch); /* Loop until the end of transmission */ while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} return ch; } volatile unsigned char RS232_REC_Flag = 0; volatile unsigned char RS485_REC_Flag = 0; volatile unsigned char RS232_buff[RS232_REC_BUFF_SIZE];//用於接收數據 volatile unsigned char RS485_buff[RS485_REC_BUFF_SIZE];//用於接收數據 volatile unsigned int RS232_rec_counter = 0;//用於RS232接收計數 volatile unsigned int RS485_rec_counter = 0;//用於RS485接收計數 void USART_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure;//定義GPIO_InitTypeDef類型的結構體成員GPIO_InitStructure USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStruct; //使能需要用到的GPIO管腳時鍾 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE); //使能USART1 時鍾 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); ///復位串口1 USART_DeInit(USART1); USART_StructInit(&USART_InitStructure);//載入默認USART參數 USART_ClockStructInit(&USART_ClockInitStruct);//載入默認USART參數 //配置串口1的管腳 PA8 USART1_EN PA9 USART1_TX PA10 USART1_RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //復用 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽輸出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //管腳PA9復用為USART1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); USART_ClockInit(USART1,&USART_ClockInitStruct); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); ///////接收中斷使能 USART_ClearITPendingBit(USART1, USART_IT_TC);//清除中斷TC位 USART_Cmd(USART1,ENABLE);//最后使能串? } /*********************************************************************** 函數名稱:void USART1_IRQHandler(void) 功 能:完成SCI的數據的接收,並做標識 輸入參數: 輸出參數: 編寫時間:2012.11.22 編 寫 人: 注 意 RS232用的是USART1. ***********************************************************************/ void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { RS232_buff[RS232_rec_counter] = USART1->DR;// RS232_rec_counter ++; /********以RS232_END_FLAG1和RS232_END_FLAG2定義的字符作為一幀數據的結束標識************/ if(RS232_rec_counter >= 2) //只有接收到2個數據以上才做判斷 { if(RS232_buff[RS232_rec_counter - 2] == RS232_END_FLAG1 && RS232_buff[RS232_rec_counter - 1] == RS232_END_FLAG2) //幀起始標志 { RS232_REC_Flag = 1; } } if(RS232_rec_counter > RS232_REC_BUFF_SIZE)//超過接收緩沖區大小 { RS232_rec_counter = 0; } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_TXE); /* Clear the USART transmit interrupt */ } } /*********************************************************************** 函數名稱:RS232_Send_Data(unsigned char *send_buff,unsigned int length) 功 能:RS232發送字符串 輸入參數:send_buff:待發送的數據指針;length:發送的數據長度(字符個數) 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void RS232_Send_Data(unsigned char *send_buff,unsigned int length) { unsigned int i = 0; for(i = 0;i < length;i ++) { USART1->DR = send_buff[i]; while((USART1->SR&0X40)==0); } } /*********************************************************************** 函數名稱:void RS485_Delay(uint32_t nCount) 功 能:RS485收發延時函數 輸入參數: 輸出參數: 編寫時間:2012.11.22 編 寫 人: 注 意: ***********************************************************************/ // static void RS485_Delay(uint32_t nCount) // { // while(nCount > 0) // { // nCount --; // } // }
TCP_Serve.c
/*********************************************************************** 文件名稱:TCP_Server.C 功 能: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ #include "main.h" /***************開發板ip定義*************************/ char *BOARD_IP = "192.168.1.253"; //開發板ip char *BOARD_NETMASK = "255.255.255.0"; //開發板子網掩碼 char *BOARD_WG = "192.168.1.1"; //開發板子網關 #define TCP_LOCAL_PORT 4000 //即TCP服務器端口號 #define FRAME_SIZE 500 //一包網絡數據大小 int tcp_server_sock_fd = -1; //TCP服務器socket句柄 int a_new_client_sock_fd = -1; //TCP客戶端socket句柄 char tcp_recv_flag = 0; OS_EVENT *sem_tcp_rec_flag = 0; //tcp接收完一楨數據信號量定義 char tcp_recv_buff[2048]; //tcp數據接收緩沖器 int tcp_recv_len = 0; //tcp數據接收長度 int client_sock[MAX_TEMPER_CLIENT_NUM]; unsigned char flag_send_over; unsigned char tcp_frame_send_ok = 0,tcp_frame_next = 0; u32 JpegDataCnt; unsigned char JpegBuffer[FRAME_BUFF_NUM]; unsigned char VsyncActive; unsigned char tcp_sending_flag; extern unsigned char tcp_frame_send_ok; extern unsigned char tcp_frame_next; unsigned char frame_start[22] = { 0xAA,0xAA,0xAA,0xAA,0XAA, 0xAA,0xAA,0xAA,0xAA,0XAA, 0xAA,0xAA,0xAA,0xAA,0XAA, 0xAA,0xAA,0xAA,0xAA,0XAA, }; unsigned char frame_end[20] = { 0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,0x55, }; void Send_OV2640_Data(unsigned char *buff,unsigned int length); /*********************************************************************** 函數名稱:void ZQWL_W8782_IRQ_Handler(int socket, uint8_t *buff, int size) 功 能:網絡數據處理函數,當有網絡數據時,該函數被自動調用,網絡的所有數據均在這里處理 輸入參數:s為socket號,buff數據指針,size是數據長度 remote_addr 遠程地址信息 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void ZQWL_W8782_IRQ_Handler(int s, uint8_t *buff, int size,struct sockaddr remote_addr) { struct lwip_sock *sock; sock = get_socket(s); if(sock->conn->pcb.tcp->local_port == TCP_LOCAL_PORT) //與開發板TCP端口號一致 { if (sock->conn->type == NETCONN_TCP) //是TCP協議 { if(buff[0] = 0xAA && buff[1] == 0XAA) //是圖像數據幀頭,只取2字節判斷 { OSSemPost(sem_tcp_rec_flag); //拋出一個信號量表示tcp已經接收完成一幀數據 } else if(buff[0] = 0x55 && buff[1] == 0X55) //圖像結尾幀 { JpegDataCnt = 0; //JPEG計數器清零 EXTI->IMR |= EXTI_Line8; //使能場同步中斷,准備下次采集 EXTI->EMR |= EXTI_Line8; OSSemPost(sem_tcp_rec_flag); //拋出一個信號量表示tcp已經接收完成一幀數據 } } } } /*********************************************************************** 函數名稱:void Task_TCP_server(void *pdata) 功 能:TCP服務器的任務,在此可以實現具體功能,本例例程是將收到的數據原樣返回。 輸入參數: 輸出參數: 編寫時間: 編 寫 人: 注 意: ***********************************************************************/ void Task_TCP_server(void *pdata) { unsigned char os_err; int i = 0; for(i = 0;i < MAX_TEMPER_CLIENT_NUM;i ++) //最多連接的客戶端數MAX_TEMPER_CLIENT_NUM { client_sock[i] = -1; //初始化 } tcp_server_sock_fd = Create_TCP_Server(TCP_LOCAL_PORT); //初始化一個TCP服務socket 端口為TCP_LOCAL_PORT並開始監聽 sem_tcp_rec_flag = OSSemCreate(0); //創建一個信號量, while(1) { if(VsyncActive == 2) //如果一幀圖片采集完成 { VsyncActive = 0; Send_OV2640_Data(JpegBuffer,JpegDataCnt); //發送圖片 } OSTimeDlyHMSM(0, 0, 1, 0); //任務掛起20ms,以便其他任務運行!!!!!!! } } /*********************************************************************** 函數名稱:Send_OV2640_Data(unsigned char *buff,unsigned int length) 功 能:完成圖像的發送 輸入參數:buff圖像指針,length圖像大小 輸出參數: 編寫時間:2015 編 寫 人: 注 意: ***********************************************************************/ void Send_OV2640_Data(unsigned char *buff,unsigned int length) { unsigned int frame_counter = 0,frame_left; unsigned int i = 0,j; struct lwip_sock *sock; unsigned char os_err; frame_counter = length / FRAME_SIZE; //一張圖片分成的數據包個數 frame_left = length % FRAME_SIZE; //不夠1包數據時的余數 frame_start[20] = length; //圖像長度低字節 frame_start[21] = length >> 8; //圖像長度高字節 for(i = 0;i < MAX_TEMPER_CLIENT_NUM;i ++)//最多連接的客戶端數MAX_TEMPER_CLIENT_NUM { sock = get_socket(client_sock[i]); if(sock->conn->pcb.tcp->state == ESTABLISHED)//有連接 { TCP_Send_Data(client_sock[i],frame_start,22,MSG_DONTWAIT);//向該客戶端發送圖像協議幀頭 //開始數據包 OSSemPend(sem_tcp_rec_flag,0,&os_err); //持續等待sem_tcp_rec_flag信號量有效 if(frame_counter > 0) { for(j = 0;j < frame_counter;j ++) { TCP_Send_Data(client_sock[i],&buff[FRAME_SIZE * j],FRAME_SIZE,MSG_DONTWAIT);//向該客戶端發送圖像 OSSemPend(sem_tcp_rec_flag,0,&os_err); //持續等待sem_tcp_rec_flag信號量有效 } } if(frame_left > 0) { TCP_Send_Data(client_sock[i],&buff[FRAME_SIZE * j],frame_left,MSG_DONTWAIT);//向該客戶端發送圖像 OSSemPend(sem_tcp_rec_flag,0,&os_err); //持續等待sem_tcp_rec_flag信號量有效 } TCP_Send_Data(client_sock[i],frame_end,20,MSG_DONTWAIT); //結束數據包 OSSemPend(sem_tcp_rec_flag,0,&os_err); //持續等待sem_tcp_rec_flag信號量有效 } else //客戶端斷開了連接 { client_sock[i] = -1; //將該索引號置為無效 } } } /****************************!!!!!!!!!!!!!!***/ void Task_TCP_server2(void *pdata) { unsigned char os_err; int i = 0; for(i = 0;i < MAX_TEMPER_CLIENT_NUM;i ++) //最多連接的客戶端數MAX_TEMPER_CLIENT_NUM { client_sock[i] = -1; //初始化 } tcp_server_sock_fd = Create_TCP_Server(TCP_LOCAL_PORT); //初始化一個TCP服務socket 端口為TCP_LOCAL_PORT並開始監聽 sem_tcp_rec_flag = OSSemCreate(0); //創建一個信號量, while(1) { OSSemPend(sem_tcp_rec_flag,0,&os_err); LED_Ctrl(tcp_recv_buff); OSTimeDlyHMSM(0, 0, 1, 0); //任務掛起20ms,以便其他任務運行!!!!!!! } }
dcmi_ov2640.c
/** ****************************************************************************** * @file DCMI/Camera/dcmi_ov2640.c * @author MCD Application Team * @version V1.0.0 * @date 30-September-2011 * @brief This file includes the driver for OV2640 Camera module mounted on * STM324xG-EVAL board RevB. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" FunctionalState I2C_WriteByte(unsigned char SendByte, short int WriteAddress, unsigned char DeviceAddress); FunctionalState I2C_ReadByte(unsigned char* pBuffer, short int length, short int ReadAddress, unsigned char DeviceAddress); /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define TIMEOUT 2 #define CLR_BAR_EN 0 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* QQVGA 160x120 */ const char OV2640_QQVGA[][2]= { 0xff, 0x00, 0x2c, 0xff, 0x2e, 0xdf, 0xff, 0x01, 0x3c, 0x32, 0x11, 0x00, 0x09, 0x02, 0x03, 0xcf, 0x04, 0x08, 0x13, 0xe5, 0x14, 0x48, 0x2c, 0x0c, 0x33, 0x78, 0x3a, 0x33, 0x3b, 0xfb, 0x3e, 0x00, 0x43, 0x11, 0x16, 0x10, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x23, 0x00, 0x34, 0xa0, 0x36, 0x1a, 0x06, 0x02, 0x07, 0xc0, 0x0d, 0xb7, 0x0e, 0x01, 0x4c, 0x00, 0x4a, 0x81, 0x21, 0x99, 0x24, 0x3a, 0x25, 0x32, 0x26, 0x82, 0x5c, 0x00, 0x63, 0x00, 0x5d, 0x55, 0x5e, 0x7d, 0x5f, 0x7d, 0x60, 0x55, 0x61, 0x70, 0x62, 0x80, 0x7c, 0x05, 0x20, 0x80, 0x28, 0x30, 0x6c, 0x00, 0x6d, 0x80, 0x6e, 0x00, 0x70, 0x02, 0x71, 0x96, 0x73, 0xe1, 0x3d, 0x34, 0x5a, 0x57, 0x4f, 0xbb, 0x50, 0x9c, 0x0f, 0x43, 0xff, 0x00, 0xe5, 0x7f, 0xf9, 0xc0, 0x41, 0x24, 0xe0, 0x14, 0x76, 0xff, 0x33, 0xa0, 0x42, 0x20, 0x43, 0x18, 0x4c, 0x00, 0x87, 0xd0, 0x88, 0x3f, 0xd7, 0x03, 0xd9, 0x10, 0xd3, 0x82, 0xc8, 0x08, 0xc9, 0x80, 0x7c, 0x00, 0x7d, 0x02, 0x7c, 0x03, 0x7d, 0x48, 0x7d, 0x48, 0x7c, 0x08, 0x7d, 0x20, 0x7d, 0x10, 0x7d, 0x0e, 0x90, 0x00, 0x91, 0x0e, 0x91, 0x1a, 0x91, 0x31, 0x91, 0x5a, 0x91, 0x69, 0x91, 0x75, 0x91, 0x7e, 0x91, 0x88, 0x91, 0x8f, 0x91, 0x96, 0x91, 0xa3, 0x91, 0xaf, 0x91, 0xc4, 0x91, 0xd7, 0x91, 0xe8, 0x91, 0x20, 0x92, 0x00, 0x93, 0x06, 0x93, 0xe3, 0x93, 0x05, 0x93, 0x05, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x96, 0x00, 0x97, 0x08, 0x97, 0x19, 0x97, 0x02, 0x97, 0x0c, 0x97, 0x24, 0x97, 0x30, 0x97, 0x28, 0x97, 0x26, 0x97, 0x02, 0x97, 0x98, 0x97, 0x80, 0x97, 0x00, 0x97, 0x00, 0xc3, 0xed, 0xa4, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xba, 0xf0, 0xbc, 0x64, 0xbb, 0x02, 0xb6, 0x3d, 0xb8, 0x57, 0xb7, 0x38, 0xb9, 0x4e, 0xb3, 0xe8, 0xb4, 0xe1, 0xb5, 0x66, 0xb0, 0x67, 0xb1, 0x5e, 0xb2, 0x04, 0xc7, 0x00, 0xc6, 0x51, 0xc5, 0x11, 0xc4, 0x9c, 0xcf, 0x02, 0xa6, 0x00, 0xa7, 0xe0, 0xa7, 0x10, 0xa7, 0x1e, 0xa7, 0x21, 0xa7, 0x00, 0xa7, 0x28, 0xa7, 0xd0, 0xa7, 0x10, 0xa7, 0x16, 0xa7, 0x21, 0xa7, 0x00, 0xa7, 0x28, 0xa7, 0xd0, 0xa7, 0x10, 0xa7, 0x17, 0xa7, 0x21, 0xa7, 0x00, 0xa7, 0x28, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x1d, 0x50, 0x00, 0x51, 0x90, 0x52, 0x18, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x90, 0x5b, 0x18, 0x5c, 0x05, 0xc3, 0xef, 0x7f, 0x00, 0xda, 0x00, 0xe5, 0x1f, 0xe1, 0x67, 0xe0, 0x00, 0xdd, 0xff, 0x05, 0x00, 0xff, 0x01, 0xff, 0x01, 0x12, 0x00, 0x17, 0x11, 0x18, 0x75, 0x19, 0x01, 0x1a, 0x97, 0x32, 0x36, 0x4f, 0xbb, 0x6d, 0x80, 0x3d, 0x34, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x23, 0x00, 0x34, 0xa0, 0x36, 0x1a, 0x06, 0x02, 0x07, 0xc0, 0x0d, 0xb7, 0x0e, 0x01, 0x4c, 0x00, 0xff, 0x00, 0xe0, 0x04, 0x8c, 0x00, 0x87, 0xd0, 0xe0, 0x00, 0xff, 0x00, 0xe0, 0x14, 0xe1, 0x77, 0xe5, 0x1f, 0xd7, 0x03, 0xda, 0x10, 0xe0, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x1d, 0x50, 0x00, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x90, 0x5b, 0x2c, 0x5c, 0x05, 0xe0, 0x00, 0xd3, 0x04, 0xff, 0x00, 0xc3, 0xef, 0xa6, 0x00, 0xa7, 0xdd, 0xa7, 0x78, 0xa7, 0x7e, 0xa7, 0x24, 0xa7, 0x00, 0xa7, 0x25, 0xa6, 0x06, 0xa7, 0x20, 0xa7, 0x58, 0xa7, 0x73, 0xa7, 0x34, 0xa7, 0x00, 0xa7, 0x25, 0xa6, 0x0c, 0xa7, 0x28, 0xa7, 0x58, 0xa7, 0x6d, 0xa7, 0x34, 0xa7, 0x00, 0xa7, 0x25, 0xff, 0x00, 0xe0, 0x04, 0xe1, 0x67, 0xe5, 0x1f, 0xd7, 0x01, 0xda, 0x08, 0xda, 0x09, 0xe0, 0x00, 0x98, 0x00, 0x99, 0x00, 0xff, 0x01, 0x04, 0x28, 0xff, 0x01, #if CLR_BAR_EN > 0 0x12, 0x42, //0x42彩條測試使能 #else 0x12, 0x40, #endif 0x17, 0x11, 0x18, 0x43, 0x19, 0x00, 0x1a, 0x4b, 0x32, 0x09, 0x4f, 0xca, 0x50, 0xa8, 0x5a, 0x23, 0x6d, 0x00, 0x39, 0x12, 0x35, 0xda, 0x22, 0x1a, 0x37, 0xc3, 0x23, 0x00, 0x34, 0xc0, 0x36, 0x1a, 0x06, 0x88, 0x07, 0xc0, 0x0d, 0x87, 0x0e, 0x41, 0x4c, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0x64, 0xc1, 0x4b, 0x86, 0x35, 0x50, 0x92, 0x51, 0xc8, 0x52, 0x96, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x5a, 0x28, 0x5b, 0x1e, 0x5c, 0x00, 0xe0, 0x00, 0xff, 0x01, 0x11, 0x00,//時鍾分頻 0x3d, 0x38, 0x2d, 0x00, 0x50, 0x65, 0xff, 0x00, 0xd3, 0x04, 0x7c, 0x00, 0x7d, 0x04, 0x7c, 0x09, 0x7d, 0x28, 0x7d, 0x00, }; /* QVGA 320x240 */ const unsigned char OV2640_QVGA[][2]= { 0xff, 0x00, 0x2c, 0xff, 0x2e, 0xdf, 0xff, 0x01, 0x3c, 0x32, 0x11, 0x00, 0x09, 0x02, 0x04, 0x28, 0x13, 0xe5, 0x14, 0x48, 0x2c, 0x0c, 0x33, 0x78, 0x3a, 0x33, 0x3b, 0xfB, 0x3e, 0x00, 0x43, 0x11, 0x16, 0x10, 0x4a, 0x81, 0x21, 0x99, 0x24, 0x40, 0x25, 0x38, 0x26, 0x82, 0x5c, 0x00, 0x63, 0x00, 0x46, 0x3f, 0x0c, 0x3c, 0x61, 0x70, 0x62, 0x80, 0x7c, 0x05, 0x20, 0x80, 0x28, 0x30, 0x6c, 0x00, 0x6d, 0x80, 0x6e, 0x00, 0x70, 0x02, 0x71, 0x94, 0x73, 0xc1, 0x3d, 0x34, 0x5a, 0x57, #if CLR_BAR_EN > 0 0x12, 0x02, //bit1彩條測試使能 #else 0x12, 0x00, #endif 0x11, 0x00, 0x17, 0x11, 0x18, 0x75, 0x19, 0x01, 0x1a, 0x97, 0x32, 0x36, 0x03, 0x0f, 0x37, 0x40, 0x4f, 0xbb, 0x50, 0x9c, 0x5a, 0x57, 0x6d, 0x80, 0x6d, 0x38, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x23, 0x00, 0x34, 0xa0, 0x36, 0x1a, 0x06, 0x02, 0x07, 0xc0, 0x0d, 0xb7, 0x0e, 0x01, 0x4c, 0x00, 0xff, 0x00, 0xe5, 0x7f, 0xf9, 0xc0, 0x41, 0x24, 0xe0, 0x14, 0x76, 0xff, 0x33, 0xa0, 0x42, 0x20, 0x43, 0x18, 0x4c, 0x00, 0x87, 0xd0, 0x88, 0x3f, 0xd7, 0x03, 0xd9, 0x10, 0xd3, 0x82, 0xc8, 0x08, 0xc9, 0x80, 0x7d, 0x00, 0x7c, 0x03, 0x7d, 0x48, 0x7c, 0x08, 0x7d, 0x20, 0x7d, 0x10, 0x7d, 0x0e, 0x90, 0x00, 0x91, 0x0e, 0x91, 0x1a, 0x91, 0x31, 0x91, 0x5a, 0x91, 0x69, 0x91, 0x75, 0x91, 0x7e, 0x91, 0x88, 0x91, 0x8f, 0x91, 0x96, 0x91, 0xa3, 0x91, 0xaf, 0x91, 0xc4, 0x91, 0xd7, 0x91, 0xe8, 0x91, 0x20, 0x92, 0x00, 0x93, 0x06, 0x93, 0xe3, 0x93, 0x02, 0x93, 0x02, 0x93, 0x00, 0x93, 0x04, 0x93, 0x00, 0x93, 0x03, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x96, 0x00, 0x97, 0x08, 0x97, 0x19, 0x97, 0x02, 0x97, 0x0c, 0x97, 0x24, 0x97, 0x30, 0x97, 0x28, 0x97, 0x26, 0x97, 0x02, 0x97, 0x98, 0x97, 0x80, 0x97, 0x00, 0x97, 0x00, 0xc3, 0xeF, //AWB等使能 0xff, 0x00, 0xba, 0xdc, 0xbb, 0x08, 0xb6, 0x24, 0xb8, 0x33, 0xb7, 0x20, 0xb9, 0x30, 0xb3, 0xb4, 0xb4, 0xca, 0xb5, 0x43, 0xb0, 0x5c, 0xb1, 0x4f, 0xb2, 0x06, 0xc7, 0x00, 0xc6, 0x51, 0xc5, 0x11, 0xc4, 0x9c, 0xbf, 0x00, 0xbc, 0x64, 0xa6, 0x00, 0xa7, 0x1e, 0xa7, 0x6b, 0xa7, 0x47, 0xa7, 0x33, 0xa7, 0x00, 0xa7, 0x23, 0xa7, 0x2e, 0xa7, 0x85, 0xa7, 0x42, 0xa7, 0x33, 0xa7, 0x00, 0xa7, 0x23, 0xa7, 0x1b, 0xa7, 0x74, 0xa7, 0x42, 0xa7, 0x33, 0xa7, 0x00, 0xa7, 0x23, 0xc0, 0xc8, 0xc1, 0x96, 0x8c, 0x00, 0x86, 0x3d, 0x50, 0x92, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x5a, 0x50, 0x5b, 0x3c, 0x5c, 0x00, 0xd3, 0x04, 0x7f, 0x00, 0xda, 0x00, 0xe5, 0x1f, 0xe1, 0x67, 0xe0, 0x00, 0xdd, 0x7f, 0x05, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x92, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x50, 0x5b, 0x3c, 0x5c, 0x00, 0xd3, 0x04, 0xe0, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xDA, 0x08, 0xda, 0x09, 0x98, 0x00, 0x99, 0x00, }; const unsigned char OV2640_JPEG_INIT[][2]= { 0xff, 0x00, 0x2c, 0xff, 0x2e, 0xdf, 0xff, 0x01, 0x3c, 0x32, 0x11, 0x00, 0x09, 0x02, 0x04, 0x28, 0x13, 0xe5, 0x14, 0x48, 0x2c, 0x0c, 0x33, 0x78, 0x3a, 0x33, 0x3b, 0xfB, 0x3e, 0x00, 0x43, 0x11, 0x16, 0x10, 0x39, 0x92, 0x35, 0xda, 0x22, 0x1a, 0x37, 0xc3, 0x23, 0x00, 0x34, 0xc0, 0x36, 0x1a, 0x06, 0x88, 0x07, 0xc0, 0x0d, 0x87, 0x0e, 0x41, 0x4c, 0x00, 0x48, 0x00, 0x5B, 0x00, 0x42, 0x03, 0x4a, 0x81, 0x21, 0x99, 0x24, 0x40, 0x25, 0x38, 0x26, 0x82, 0x5c, 0x00, 0x63, 0x00, 0x61, 0x70, 0x62, 0x80, 0x7c, 0x05, 0x20, 0x80, 0x28, 0x30, 0x6c, 0x00, 0x6d, 0x80, 0x6e, 0x00, 0x70, 0x02, 0x71, 0x94, 0x73, 0xc1, 0x12, 0x40,//0x40 0x17, 0x11, 0x18, 0x43, 0x19, 0x00, 0x1a, 0x4b, 0x32, 0x09, 0x37, 0xc0, 0x4f, 0x60, 0x50, 0xa8, 0x6d, 0x00, 0x3d, 0x38, 0x46, 0x3f, 0x4f, 0x60, 0x0c, 0x3c, 0xff, 0x00, 0xe5, 0x7f, 0xf9, 0xc0, 0x41, 0x24, 0xe0, 0x14, 0x76, 0xff, 0x33, 0xa0, 0x42, 0x20, 0x43, 0x18, 0x4c, 0x00, 0x87, 0xd5, 0x88, 0x3f, 0xd7, 0x03, 0xd9, 0x10, 0xd3, 0x82, 0xc8, 0x08, 0xc9, 0x80, 0x7c, 0x00, 0x7d, 0x00, 0x7c, 0x03, 0x7d, 0x48, 0x7d, 0x48, 0x7c, 0x08, 0x7d, 0x20, 0x7d, 0x10, 0x7d, 0x0e, 0x90, 0x00, 0x91, 0x0e, 0x91, 0x1a, 0x91, 0x31, 0x91, 0x5a, 0x91, 0x69, 0x91, 0x75, 0x91, 0x7e, 0x91, 0x88, 0x91, 0x8f, 0x91, 0x96, 0x91, 0xa3, 0x91, 0xaf, 0x91, 0xc4, 0x91, 0xd7, 0x91, 0xe8, 0x91, 0x20, 0x92, 0x00, 0x93, 0x06, 0x93, 0xe3, 0x93, 0x05, 0x93, 0x05, 0x93, 0x00, 0x93, 0x04, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x96, 0x00, 0x97, 0x08, 0x97, 0x19, 0x97, 0x02, 0x97, 0x0c, 0x97, 0x24, 0x97, 0x30, 0x97, 0x28, 0x97, 0x26, 0x97, 0x02, 0x97, 0x98, 0x97, 0x80, 0x97, 0x00, 0x97, 0x00, 0xc3, 0xed, 0xa4, 0x00, 0xa8, 0x00, 0xc5, 0x11, 0xc6, 0x51, 0xbf, 0x80, 0xc7, 0x10, 0xb6, 0x66, 0xb8, 0xA5, 0xb7, 0x64, 0xb9, 0x7C, 0xb3, 0xaf, 0xb4, 0x97, 0xb5, 0xFF, 0xb0, 0xC5, 0xb1, 0x94, 0xb2, 0x0f, 0xc4, 0x5c, 0xc0, 0x64, 0xc1, 0x4B, 0x8c, 0x00, 0x86, 0x3D, 0x50, 0x00, 0x51, 0xC8, 0x52, 0x96, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x5a, 0xC8, 0x5b, 0x96, 0x5c, 0x00, 0xd3, 0x7f, 0xc3, 0xed, 0x7f, 0x00, 0xda, 0x00, 0xe5, 0x1f, 0xe1, 0x67, 0xe0, 0x00, 0xdd, 0x7f, 0x05, 0x00, 0x12, 0x40,//0x40 0xd3, 0x7f, 0xc0, 0x16, 0xC1, 0x12, 0x8c, 0x00, 0x86, 0x3d, 0x50, 0x00, 0x51, 0x2C, 0x52, 0x24, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x5A, 0x2c, 0x5b, 0x24, 0x5c, 0x00, }; const unsigned char OV2640_YUV422[][2]= { 0xFF, 0x00, 0x05, 0x00, 0xDA, 0x10, 0xD7, 0x03, 0xDF, 0x00, 0x33, 0x80, 0x3C, 0x40, 0xe1, 0x77, 0x00, 0x00, }; const unsigned char OV2640_JPEG[][2]= { 0xe0, 0x14, 0xe1, 0x77, 0xe5, 0x1f, 0xd7, 0x03, 0xda, 0x10, 0xe0, 0x00, 0xFF, 0x01, 0x04, 0x08, }; /* JPG 160x120 */ const unsigned char OV2640_160x120_JPEG[][2]= { 0xff, 0x01, 0x12, 0x40, 0x17, 0x11, 0x18, 0x43, 0x19, 0x00, 0x1a, 0x4b, 0x32, 0x09, 0x4f, 0xca, 0x50, 0xa8, 0x5a, 0x23, 0x6d, 0x00, 0x39, 0x12, 0x35, 0xda, 0x22, 0x1a, 0x37, 0xc3, 0x23, 0x00, 0x34, 0xc0, 0x36, 0x1a, 0x06, 0x88, 0x07, 0xc0, 0x0d, 0x87, 0x0e, 0x41, 0x4c, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0x64, 0xc1, 0x4b, 0x86, 0x35, 0x50, 0x92, 0x51, 0xc8, 0x52, 0x96, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x5a, 0x28, 0x5b, 0x1e, 0x5c, 0x00, 0xe0, 0x00, }; /* JPG, 0x176x144 */ const unsigned char OV2640_176x144_JPEG[][2]= { 0xff, 0x01, 0x12, 0x40, 0x17, 0x11, 0x18, 0x43, 0x19, 0x00, 0x1a, 0x4b, 0x32, 0x09, 0x4f, 0xca, 0x50, 0xa8, 0x5a, 0x23, 0x6d, 0x00, 0x39, 0x12, 0x35, 0xda, 0x22, 0x1a, 0x37, 0xc3, 0x23, 0x00, 0x34, 0xc0, 0x36, 0x1a, 0x06, 0x88, 0x07, 0xc0, 0x0d, 0x87, 0x0e, 0x41, 0x4c, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0x64, 0xc1, 0x4b, 0x86, 0x35, 0x50, 0x92, 0x51, 0xc8, 0x52, 0x96, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x5a, 0x2c, 0x5b, 0x24, 0x5c, 0x00, 0xe0, 0x00, }; /* JPG 320x240 */ const unsigned char OV2640_320x240_JPEG[][2]= { {0xff, 0x01}, {0x11, 0x01}, {0x12, 0x00}, // Bit[6:4]: Resolution selection//0x02為彩條 {0x17, 0x11}, // HREFST[10:3] {0x18, 0x75}, // HREFEND[10:3] {0x32, 0x36}, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0] {0x19, 0x01}, // VSTRT[9:2] {0x1a, 0x97}, // VEND[9:2] {0x03, 0x0f}, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0] {0x37, 0x40}, {0x4f, 0xbb}, {0x50, 0x9c}, {0x5a, 0x57}, {0x6d, 0x80}, {0x3d, 0x34}, {0x39, 0x02}, {0x35, 0x88}, {0x22, 0x0a}, {0x37, 0x40}, {0x34, 0xa0}, {0x06, 0x02}, {0x0d, 0xb7}, {0x0e, 0x01}, //////////////// /* //176*144 0xff, 0x00, 0xc0, 0xC8, 0xc1, 0x96, 0x8c, 0x00, 0x86, 0x3D, 0x50, 0x9B, 0x51, 0x90, 0x52, 0x2C, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x5a, 0x2C, 0x5b, 0x24, 0x5c, 0x00, 0xd3, 0x7F, //////////// */ //////////////// //320*240 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x92, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x50, 0x5b, 0x3c, 0x5c, 0x00, 0xd3, 0x7F, 0xe0, 0x00, /////////////////// /* 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x35, 0x50, 0x92, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x58, 0x5b, 0x48, 0x5c, 0x00, 0xd3, 0x08, 0xe0, 0x00 */ /* //640*480 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x89, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0xa0, 0x5b, 0x78, 0x5c, 0x00, 0xd3, 0x04, 0xe0, 0x00 */ ///////////////////// /* //800*600 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x35, 0x50, 0x89, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0xc8, 0x5b, 0x96, 0x5c, 0x00, 0xd3, 0x02, 0xe0, 0x00 */ /* //1280*1024 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x00, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x40, 0x5b, 0xf0, 0x5c, 0x01, 0xd3, 0x02, 0xe0, 0x00 */ /* ///////////////////// //1600*1200 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x00, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0x90, 0x5b, 0x2C, 0x5c, 0x05,//bit2->1;bit[1:0]->1 0xd3, 0x02, 0xe0, 0x00 ///////////////////// */ /* //1024*768 0xff, 0x00, 0xc0, 0xC8, 0xc1, 0x96, 0x8c, 0x00, 0x86, 0x3D, 0x50, 0x00, 0x51, 0x90, 0x52, 0x2C, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x5a, 0x00, 0x5b, 0xC0, 0x5c, 0x01, 0xd3, 0x02 */ }; /* JPG 352x288 */ const unsigned char OV2640_352x288_JPEG[][2]= { 0xff, 0x01, 0x12, 0x40, 0x17, 0x11, 0x18, 0x43, 0x19, 0x00, 0x1a, 0x4b, 0x32, 0x09, 0x4f, 0xca, 0x50, 0xa8, 0x5a, 0x23, 0x6d, 0x00, 0x39, 0x12, 0x35, 0xda, 0x22, 0x1a, 0x37, 0xc3, 0x23, 0x00, 0x34, 0xc0, 0x36, 0x1a, 0x06, 0x88, 0x07, 0xc0, 0x0d, 0x87, 0x0e, 0x41, 0x4c, 0x00, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0x64, 0xc1, 0x4b, 0x86, 0x35, 0x50, 0x89, 0x51, 0xc8, 0x52, 0x96, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x57, 0x00, 0x5a, 0x58, 0x5b, 0x48, 0x5c, 0x00, 0xe0, 0x00, }; const unsigned char OV2640_640x480_JPEG[][2]= { 0xff, 0x01, 0x11, 0x01, 0x12, 0x00, 0x17, 0x11, 0x18, 0x75, 0x32, 0x36, 0x19, 0x01, 0x1a, 0x97, 0x03, 0x0f, 0x37, 0x40, 0x4f, 0xbb, 0x50, 0x9c, 0x5a, 0x57, 0x6d, 0x80, 0x3d, 0x34, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x34, 0xa0, 0x06, 0x02, 0x0d, 0xb7, 0x0e, 0x01, 0xff, 0x00, 0xe0, 0x04, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x3d, 0x50, 0x89, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0xa0, 0x5b, 0x78, 0x5c, 0x00, 0xd3, 0x7f, 0xe0, 0x00, }; /* JPG, 0x800x600 */ const unsigned char OV2640_800x600_JPEG[][2]= { 0xff, 0x01, 0x11, 0x01, 0x12, 0x00, 0x17, 0x11, 0x18, 0x75, 0x32, 0x36, 0x19, 0x01, 0x1a, 0x97, 0x03, 0x0f, 0x37, 0x40, 0x4f, 0xbb, 0x50, 0x9c, 0x5a, 0x57, 0x6d, 0x80, 0x3d, 0x34, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x34, 0xa0, 0x06, 0x02, 0x0d, 0xb7, 0x0e, 0x01, 0xff, 0x00, 0xe0, 0x01, 0xc0, 0xc8, 0xc1, 0x96, 0x86, 0x35, 0x50, 0x89, 0x51, 0x90, 0x52, 0x2c, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x57, 0x00, 0x5a, 0xc8, 0x5b, 0x96, 0x5c, 0x00, 0xd3, 0x7f, 0xe0, 0x00, }; /* JPG, 0x1024x768 */ const unsigned char OV2640_1024x768_JPEG[][2]= { 0xff, 0x01, 0x11, 0x0a, 0x12, 0x00, 0x17, 0x11, 0x18, 0x75, 0x32, 0x36, 0x19, 0x01, 0x1a, 0x97, 0x03, 0x0f, 0x37, 0x40, 0x4f, 0xbb, 0x50, 0x9c, 0x5a, 0x57, 0x6d, 0x80, 0x3d, 0x34, 0x39, 0x02, 0x35, 0x88, 0x22, 0x0a, 0x37, 0x40, 0x34, 0xa0, 0x06, 0x02, 0x0d, 0xb7, 0x0e, 0x01, 0xff, 0x00, 0xc0, 0xC8, 0xc1, 0x96, 0x8c, 0x00, 0x86, 0x3D, 0x50, 0x00, 0x51, 0x90, 0x52, 0x2C, 0x53, 0x00, 0x54, 0x00, 0x55, 0x88, 0x5a, 0x00, 0x5b, 0xC0, 0x5c, 0x01, 0xd3, 0x7f, }; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** * @brief Initializes the hardware resources (I2C and GPIO) used to configure * the OV2640 camera. * @param None * @retval None */ #define DIS_BORD_EN 0 void OV2640_CaptureGpioInit(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); // GPIOC->CRL = 0x88888888; // GPIOC->ODR |= 0x00FF; Exit_Init(); //VSYNC } /** * @brief Resets the OV2640 camera. * @param None * @retval None */ void OV2640_Reset(void) { OV2640_WriteReg(OV2640_DSP_RA_DLMT, 0x01); OV2640_WriteReg(OV2640_SENSOR_COM7, 0x80); } /** * @brief Reads the OV2640 Manufacturer identifier. * @param OV2640ID: Pointer to the OV2640 Manufacturer identifier * @retval None */ void OV2640_ReadID(OV2640_IDTypeDef *OV2640ID) { OV2640_WriteReg(OV2640_DSP_RA_DLMT, 0x01); 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); } /** * @brief Configures DCMI/DMA to capture image from the OV2640 camera. * @param ImageFormat: Image format BMP or JPEG * @param BMPImageSize: BMP Image size * @retval None */ void OV2640_Init(ImageFormat_TypeDef ImageFormat) { } void OV2640_Init1(ImageFormat_TypeDef ImageFormat) { } /** * @brief Configures the OV2640 camera in QQVGA mode. * @param None * @retval None */ void OV2640_QQVGAConfig(void) { uint32_t i; OV2640_Reset(); Delay(200); //JPG從這里返回 /* Initialize OV2640 */ for(i=0; i<(sizeof(OV2640_QQVGA)/2); i++) { OV2640_WriteReg(OV2640_QQVGA[i][0], OV2640_QQVGA[i][1]); } } //void OV2640_QQVGAConfig1(void) //{ // uint32_t i; // //OV2640_JPEGConfig(JPEG_176x144); // OV2640_JPEGConfig(JPEG_320x240); // return; // OV2640_Reset(); // Delay(200); // //JPG從這里返回 // // /* Initialize OV2640 */ // for(i=0; i<(sizeof(OV2640_QQVGA)/2); i++) // { // OV2640_WriteReg(OV2640_QQVGA[i][0], OV2640_QQVGA[i][1]); // } //} static const u8 change_reg[][2]= { /* {0x12, 0x46},*/ {0x3a, 0x04}, {0x40, 0xd0},//0xd0->RGB565,0xF0->RGB555 {0x12, 0x14}, {0x32, 0x80}, {0x17, 0x16}, {0x18, 0x04}, {0x19, 0x02}, {0x1a, 0x7b},//0x7a, {0x03, 0x06},//0x0a, {0x0c, 0x00}, {0x3e, 0x00},// {0x70, 0x00},//00 {0x71, 0x00},//0x85測試 {0x72, 0x11}, {0x73, 0x00},// {0xa2, 0x02}, {0x11, 0x02}, {0x7a, 0x20}, {0x7b, 0x1c}, {0x7c, 0x28}, {0x7d, 0x3c}, {0x7e, 0x55}, {0x7f, 0x68}, {0x80, 0x76}, {0x81, 0x80}, {0x82, 0x88}, {0x83, 0x8f}, {0x84, 0x96}, {0x85, 0xa3}, {0x86, 0xaf}, {0x87, 0xc4}, {0x88, 0xd7}, {0x89, 0xe8}, {0x13, 0xe0}, {0x00, 0x00},//AGC {0x10, 0x00}, {0x0d, 0x00}, {0x14, 0x20},//0x38, limit the max gain {0xa5, 0x05}, {0xab, 0x07}, {0x24, 0x75}, {0x25, 0x63}, {0x26, 0xA5}, {0x9f, 0x78}, {0xa0, 0x68}, {0xa1, 0x03},//0x0b, {0xa6, 0xdf},//0xd8, {0xa7, 0xdf},//0xd8, {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x37},//0x07, {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},// {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x0c},/////////////////////// {0x6b, 0x80},//PLL {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, {0x90, 0x00}, {0x91, 0x00}, {0x92, 0x00},//0x19,//0x66 {0x96, 0x00}, {0x9a, 0x80}, {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, {0xb8, 0x0a}, {0x43, 0x14}, {0x44, 0xf0}, {0x45, 0x34}, {0x46, 0x58}, {0x47, 0x28}, {0x48, 0x3a}, {0x59, 0x88}, {0x5a, 0x88}, {0x5b, 0x44}, {0x5c, 0x67}, {0x5d, 0x49}, {0x5e, 0x0e}, {0x64, 0x04}, {0x65, 0x20}, {0x66, 0x05}, {0x94, 0x04}, {0x95, 0x08}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, {0x6f, 0x9f},//0x9e for advance AWB {0x6a, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x13, 0xe7}, {0x15, 0x00}, {0x4f, 0x80}, {0x50, 0x80}, {0x51, 0x00}, {0x52, 0x22}, {0x53, 0x5e}, {0x54, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, {0x3f, 0x00}, {0x75, 0x05}, {0x76, 0xe1}, {0x4c, 0x00}, {0x77, 0x01}, {0x3d, 0xc2}, //0xc0, {0x4b, 0x09}, {0xc9, 0x60}, {0x41, 0x38}, {0x56, 0x40},//0x40, change according to Jim's request {0x34, 0x11}, {0x3b, 0x02},//0x00,//0x02, {0xa4, 0x89},//0x88, {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x4c}, {0x9e, 0x3f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, {0x79, 0x26}, {0x09, 0x03}, {0x55, 0x00}, {0x56, 0x40}, {0x3b, 0xC2},//0x82,//0xc0,//0xc2, //night mode }; /** * @brief Configures the OV2640 camera in QVGA mode. * @param None * @retval None */ u8 ID; void OV2640_QVGAConfig(void) { uint32_t i; OV2640_Reset(); Delay(200); /* Initialize OV2640 */ for(i=0; i<(sizeof(OV2640_QVGA)/2); i++) { OV2640_WriteReg(OV2640_QVGA[i][0], OV2640_QVGA[i][1]); Delay(1); } } /** * @brief Configures the OV2640 camera in JPEG mode. * @param JPEGImageSize: JPEG image size * @retval None */ void OV2640_JPEGConfig(ImageFormat_TypeDef ImageFormat) { uint32_t i; OV2640_Reset(); Delay(200); /* Initialize OV2640 */ for(i=0; i<(sizeof(OV2640_JPEG_INIT)/2); i++) { OV2640_WriteReg(OV2640_JPEG_INIT[i][0], OV2640_JPEG_INIT[i][1]); Delay(1); } /* Set to output YUV422 */ for(i=0; i<(sizeof(OV2640_YUV422)/2); i++) { OV2640_WriteReg(OV2640_YUV422[i][0], OV2640_YUV422[i][1]); Delay(1); } OV2640_WriteReg(0xff, 0x01); OV2640_WriteReg(0x15, 0x00); /* Set to output JPEG */ for(i=0; i<(sizeof(OV2640_JPEG)/2); i++) { OV2640_WriteReg(OV2640_JPEG[i][0], OV2640_JPEG[i][1]); Delay(1); } Delay(100); switch(ImageFormat) { case JPEG_176x144: { for(i=0; i<(sizeof(OV2640_176x144_JPEG)/2); i++) { OV2640_WriteReg(OV2640_176x144_JPEG[i][0], OV2640_176x144_JPEG[i][1]); } break; } case JPEG_320x240: { for(i=0; i<(sizeof(OV2640_320x240_JPEG)/2); i++) { OV2640_WriteReg(OV2640_320x240_JPEG[i][0], OV2640_320x240_JPEG[i][1]); Delay(1); } break; } case JPEG_352x288: { for(i=0; i<(sizeof(OV2640_352x288_JPEG)/2); i++) { OV2640_WriteReg(OV2640_352x288_JPEG[i][0], OV2640_352x288_JPEG[i][1]); } break; } case JPEG_640x480: { for(i=0; i<(sizeof(OV2640_640x480_JPEG)/2); i++) { OV2640_WriteReg(OV2640_640x480_JPEG[i][0], OV2640_640x480_JPEG[i][1]); } break; } case JPEG_800x600: { for(i = 0; i<(sizeof(OV2640_800x600_JPEG)/2); i++) { OV2640_WriteReg(OV2640_800x600_JPEG[i][0], OV2640_800x600_JPEG[i][1]); } break; } case JPEG_1024x768: { for(i=0; i<(sizeof(OV2640_1024x768_JPEG)/2); i++) { OV2640_WriteReg(OV2640_1024x768_JPEG[i][0], OV2640_1024x768_JPEG[i][1]); } break; } default: { for(i=0; i<(sizeof(OV2640_160x120_JPEG)/2); i++) { OV2640_WriteReg(OV2640_160x120_JPEG[i][0], OV2640_160x120_JPEG[i][1]); } break; } } } /** * @brief Configures the OV2640 camera brightness. * @param Brightness: Brightness value, where Brightness can be: * 0x40 for Brightness +2, * 0x30 for Brightness +1, * 0x20 for Brightness 0, * 0x10 for Brightness -1, * 0x00 for Brightness -2, * @retval None */ void OV2640_BrightnessConfig(uint8_t Brightness) { OV2640_WriteReg(0xff, 0x00); OV2640_WriteReg(0x7c, 0x00); OV2640_WriteReg(0x7d, 0x04); OV2640_WriteReg(0x7c, 0x09); OV2640_WriteReg(0x7d, Brightness); OV2640_WriteReg(0x7d, 0x00); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const static u8 OV2640_AUTOEXPOSURE_LEVEL0[]= { 0xFF, 0x01, 0xff, 0x24, 0x20, 0xff, 0x25, 0x18, 0xff, 0x26, 0x60, 0xff, 0x00, 0x00, 0x00 }; const static u8 OV2640_AUTOEXPOSURE_LEVEL1[]= { 0xFF, 0x01, 0xff, 0x24, 0x34, 0xff, 0x25, 0x1c, 0xff, 0x26, 0x70, 0xff, 0x00, 0x00, 0x00 }; const static u8 OV2640_AUTOEXPOSURE_LEVEL2[]= { 0xFF, 0x01, 0xff, 0x24, 0x3e, 0xff, 0x25, 0x38, 0xff, 0x26, 0x81, 0xff, 0x00, 0x00, 0x00 }; const static u8 OV2640_AUTOEXPOSURE_LEVEL3[]= { 0xFF, 0x01, 0xff, 0x24, 0x48, 0xff, 0x25, 0x40, 0xff, 0x26, 0x81, 0xff, 0x00, 0x00, 0x00 }; const static u8 OV2640_AUTOEXPOSURE_LEVEL4[]= { 0xFF, 0x01, 0xff, 0x24, 0x58, 0xff, 0x25, 0x50, 0xff, 0x26, 0x92, 0xff, 0x00, 0x00, 0x00 }; void SCCB_WriteRegs(const u8* pbuf) { while(1) { if((*pbuf == 0) && (*(pbuf + 1) == 0)) { break; } else { OV2640_WriteReg(*pbuf++, *pbuf++); } } } void OV2640_AutoExposure(u8 level) { switch(level) { case 0: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL0); break; case 1: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL1); break; case 2: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL2); break; case 3: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL3); break; case 4: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL4); break; default: SCCB_WriteRegs(OV2640_AUTOEXPOSURE_LEVEL0); break; } } /** * @brief Configures the OV2640 camera Black and white mode. * @param BlackWhite: BlackWhite value, where BlackWhite can be: * 0x18 for B&W, * 0x40 for Negative, * 0x58 for B&W negative, * 0x00 for Normal, * @retval None */ void OV2640_BandWConfig(uint8_t BlackWhite) { OV2640_WriteReg(0xff, 0x00); OV2640_WriteReg(0x7c, 0x00); OV2640_WriteReg(0x7d, BlackWhite); OV2640_WriteReg(0x7c, 0x05); OV2640_WriteReg(0x7d, 0x80); OV2640_WriteReg(0x7d, 0x80); } /** * @brief Configures the OV2640 camera color effects. * @param value1: Color effects value1 * @param value2: Color effects value2 * where value1 and value2 can be: * value1 = 0x40, value2 = 0xa6 for Antique, * value1 = 0xa0, value2 = 0x40 for Bluish, * value1 = 0x40, value2 = 0x40 for Greenish, * value1 = 0x40, value2 = 0xc0 for Reddish, * @retval None */ void OV2640_ColorEffectsConfig(uint8_t value1, uint8_t value2) { OV2640_WriteReg(0xff, 0x00); OV2640_WriteReg(0x7c, 0x00); OV2640_WriteReg(0x7d, 0x18); OV2640_WriteReg(0x7c, 0x05); OV2640_WriteReg(0x7d, value1); OV2640_WriteReg(0x7d, value2); } /** * @brief Configures the OV2640 camera contrast. * @param value1: Contrast value1 * @param value2: Contrast value2 * where value1 and value2 can be: * value1 = 0x28, value2 = 0x0c for Contrast +2, * value1 = 0x24, value2 = 0x16 for Contrast +1, * value1 = 0x20, value2 = 0x20 for Contrast 0, * value1 = 0x1c, value2 = 0x2a for Contrast -1, * value1 = 0x18, value2 = 0x34 for Contrast -2, * @retval None */ void OV2640_ContrastConfig(uint8_t value1, uint8_t value2) { OV2640_WriteReg(0xff, 0x00); OV2640_WriteReg(0x7c, 0x00); OV2640_WriteReg(0x7d, 0x04); OV2640_WriteReg(0x7c, 0x07); OV2640_WriteReg(0x7d, 0x20); OV2640_WriteReg(0x7d, value1); OV2640_WriteReg(0x7d, value2); OV2640_WriteReg(0x7d, 0x06); } /** * @brief Writes a byte at a specific Camera register * @param Addr: OV2640 register address. * @param Data: Data to be written to the specific register * @retval 0x00 if write operation is OK. * 0xFF if timeout condition occured (device not connected or bus error). */ uint8_t OV2640_WriteReg(uint16_t Addr, uint8_t Data) { I2C_WriteByte(Data,Addr,OV2640_DEVICE_WRITE_ADDRESS); return Data; } /** * @brief Reads a byte from a specific Camera register * @param Addr: OV2640 register address. * @retval data read from the specific register or 0xFF if timeout condition * occured. */ uint8_t OV2640_ReadReg(uint16_t Addr) { uint8_t Data[1]; I2C_ReadByte(Data,1,Addr,OV2640_DEVICE_READ_ADDRESS); return Data[0]; } void Delay(unsigned int nCount) { while(nCount > 0) { nCount --; } } void Delay_nMS(unsigned int nCount) { while(nCount > 0) { Delay(0xffff); nCount --; } } /** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/