采用野火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();
}