STM32F407驱动ov2640摄像头采集图像,通过esp8266(串口协议)上传服务器显示

采用秉火STM32开发板 Cortex-M4小型系统板 STM32F407ZGT6核心板

ov2640介绍:

OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA(1632*1232)图像传感器。该传感器体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制,可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/10位影像数据。UXGA最高15帧/秒(SVGA可达30帧,CIF可达60帧)。 
注:SCCB总线可以看成IIC总线的简化版

摄像头操作:

一.初始化时钟 
二.初始化OV2640: 
1. 初始化IO口 
2. 上电,并复位 
3. 执行初始化序列 
三.设置图像窗口设置和图像输出大小设置,可以调整图像大小或者缩放模式 
四.初始化DCMI: 
1. 配置相关引脚的复用功能,使能DCMI时钟。 
2. 设置DCMI工作模式及PCLK/HSYNC/VSYNC等参数。 
3. 设置DMA 
4. 启动DCMI传输。即设置DCMI->CR的最低位为1


esp8266介绍:

esp8266是wifi串口模块,功能简单来讲就是:从wifi接收到数据,串口输出;从串口接收数据,wifi输出数据。

esp8266三个模式

1、串口无线 WIFI(COM-AP) 串口无线 WIFI(COM-AP)模式,模块作为无线 WIFI 热点,允许其他 WIFI 设备连接 到本模块,实现串口与其他设备之间的无线(WIFI)数据转换互传。该模式下,根据应用场景的不同,可以设置 3 个子模式:TCP 服务器、TCP 客户端,UDP。这三个子模式先不细究。总之都可以进行数据传输。

2、串口无线 STA(COM-STA)模式,模块作为无线 WIFI STA,用于连接到无线网络,实 现串口与其他设备之间的无线(WIFI)数据转换互传。该模式下,根据应用场景的不同, 可以设置 3 个子模式:TCP 服务器、TCP 客户端,UDP。

3、串口无线 AP+STA(COM-AP+STA)模式,模块既作无线 WIFI AP,又作无线 STA, 其他 WIFI 设备可以连接到该模块,模块也可以连接到其他无线网络,实现串口与其他设备 之间的无线(WIFI)数据转换互传。该模式下,根据应用场景的不同,可以设置 9 个子模 式:(TCP 服务器、TCP 客户端,UDP)||(TCP 服务器、TCP 客户端,UDP)。

一、把ov2640摄像头、esp8266模块与stm32f4核心板连接起来,如下图

二、main.c代码

#include "stm32f4xx.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" 


#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数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{

		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  
    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);   

	while(1)
	{      
        if(jpeg_data_ok==1)	//已经采集完一帧图像了
        { 

                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去采集下一帧了.
    
                delay_ms(20);
        }         
            		
	}    
}


int main(void)
{

    /*系统定时器初始化*/
	SysTick_Init(168);
   
    
    TIM3_Int_Init(10000-1,8400-1); //10Khz计数,1秒钟中断一次

    while(OV2640_Init()); //初始化ov2640摄像头
    
    jpeg_test();      
}


三、测试结果(速度只能达到两秒一帧)

猜你喜欢

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