STM32F407+OV2640的jpeg模式,图像采集esp8266(串口协议)传输给电脑显示

采用野火STM32F407ZGT6核心板通过OV2640摄像头采集图像,用WIFI(esp8266)上传PC端显示,速度只能达到两秒一帧。

#include "stm32f4xx.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "usart.h"
#include "usart2.h"
#include "timer.h"
#include "ov2640.h"
#include "SysTick.h"
#include "esp8266_drive.h"
#include "sta_tcpclent_test.h"
#include "esp8266_public.h"
#include "system.h"
#include "SysTick.h"
#include "dcmi.h" 

//u8 ov2640_mode=1;						//工作模式:0,RGB565模式;1,JPEG模式

#define jpeg_buf_size 31*1024  			//定义JPEG数据缓存jpeg_buf的大小(*4字节)
__align(4) u32 jpeg_buf[jpeg_buf_size];	//JPEG数据缓存buf
volatile u32 jpeg_data_len=0; 			//buf中的JPEG有效数据长度 
volatile u8 jpeg_data_ok=0;				//JPEG数据采集完成标志 
										//0,数据没有采集完;
										//1,数据采集完了,但是还没处理;
										//2,数据已经处理完成了,可以开始下一帧接收

//JPEG尺寸支持列表
const u16 jpeg_img_size_tbl[][2]=
{
	176,144,	//QCIF
	160,120,	//QQVGA
	352,288,	//CIF
	320,240,	//QVGA
	640,480,	//VGA
	800,600,	//SVGA
	1024,768,	//XGA
	1280,1024,	//SXGA
	1600,1200,	//UXGA
};


//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{
//	if(ov2640_mode)//只有在JPEG格式下,才需要做处理.
//	{
		if (jpeg_data_ok==0)	//jpeg数据还未采集完?
		{	
			DMA_Cmd(DMA2_Stream1, DISABLE);//停止当前传输 
			while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){}//等待DMA2_Stream1可配置  
			jpeg_data_len = jpeg_buf_size - DMA_GetCurrDataCounter(DMA2_Stream1);//得到此次数据传输的长度
				
			jpeg_data_ok=1;      //标记JPEG数据采集完按成,等待其他函数处理
		}
		if (jpeg_data_ok==2)	//上一次的jpeg数据已经被处理了
		{
			DMA2_Stream1->NDTR=jpeg_buf_size;	
			DMA_SetCurrDataCounter(DMA2_Stream1,jpeg_buf_size);//传输长度为jpeg_buf_size*4字节
			DMA_Cmd(DMA2_Stream1, ENABLE);			//重新传输
			jpeg_data_ok=0;						//标记数据未采集
		}
//	}
} 

//JPEG测试
//JPEG数据,通过esp8266_wifi  串口3发送给电脑.
void jpeg_test(void)
{
    u32 i=0; 
	u8 *p=0;
    
    ESP8266_Init(115200);    
    ESP8266_STA_TCPClient_Test();
    delay_ms(100);
    
    OV2640_JPEG_Mode();		//jpeg模式

	My_DCMI_Init();			//DCMI配置
	DCMI_DMA_Init((u32)&jpeg_buf,jpeg_buf_size,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);//DCMI DMA配置   
	OV2640_OutSize_Set(800,600);
	DCMI_Start(); 		//启动传输
    delay_ms(500);
        
    led_display(5);
       
    //printf("\r\njpeg_test is ok\r\n"); 
	while(1)
	{      
        if(jpeg_data_ok==1)	//已经采集完一帧图像了
        { 
            if( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON  )
            { 

                GPIO_ResetBits(GPIOC, GPIO_Pin_3);                
                p=(u8*)jpeg_buf;

                ESP8266_USART("S%dS",jpeg_data_len*4);

                for(i=0; i<jpeg_data_len*4; i++)		//dma传输1次等于2字节,所以乘以2.
                {
                    while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);	//循环发送,直到发送完毕  		
                    USART_SendData(USART3, p[i]); 
                } 
                GPIO_SetBits(GPIOC, GPIO_Pin_3);               
            }
                jpeg_data_ok=2;	//标记jpeg数据处理完了,可以让DMA去采集下一帧了.
//            ESP8266_ExitUnvarnishSend();
//            ESP8266_Send_AT_Cmd( "AT+CIPCLOSE", "OK", 0, 500 );//断开服务器       
                delay_ms(20);
        }         
            		
	}    
}


int main(void)
{

    /*系统定时器初始化*/
	SysTick_Init(168);
    
	LED_GPIO_Config();
	Key_GPIO_Config();

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
  
    USART1_Init(115200);
    
    TIM3_Int_Init(10000-1,8400-1); //10Khz计数,1秒钟中断一次

    while(OV2640_Init());
    
    jpeg_test();      
}


猜你喜欢

转载自blog.csdn.net/qq_42403190/article/details/84331892