基於TCP連接的OV2640圖像實時傳輸的STM32程序


不多說話

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>&copy; 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****/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM