基于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</
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值