#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "key.h" #include "sram.h" #include "malloc.h" #include "usmart.h" #include "sdio_sdcard.h" #include "malloc.h" #include "w25qxx.h" #include "ff.h" #include "exfuns.h" #include "fontupd.h" #include "text.h" #include "piclib.h" #include "string.h" #include "math.h" #include "dcmi.h" #include "ov2640.h" #include "beep.h" #include "timer.h" //ALIENTEK 探索者STM32F407开发板 实验42 //照相机 实验 -库函数版本 //技术支持:www.openedv.com //淘宝店铺:http://eboard.taobao.com //广州市星翼电子科技有限公司 //作者:正点原子 @ALIENTEK u8 ov2640_mode=0; //工作模式:0,RGB565模式;1,JPEG模式 #define jpeg_dma_bufsize 5*1024 //定义JPEG DMA接收时数据缓存jpeg_buf0/1的大小(*4字节) volatile u32 jpeg_data_len=0; //buf中的JPEG有效数据长度(*4字节) volatile u8 jpeg_data_ok=0; //JPEG数据采集完成标志 //0,数据没有采集完; //1,数据采集完了,但是还没处理; //2,数据已经处理完成了,可以开始下一帧接收 u32 *jpeg_buf0; //JPEG数据缓存buf,通过malloc申请内存 u32 *jpeg_buf1; //JPEG数据缓存buf,通过malloc申请内存 u32 *jpeg_data_buf; //JPEG数据缓存buf,通过malloc申请内存 //处理JPEG数据 //当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集. void jpeg_data_process(void) { u16 i; u16 rlen;//剩余数据长度 u32 *pbuf; if(ov2640_mode)//只有在JPEG格式下,才需要做处理. { if(jpeg_data_ok==0) //jpeg数据还未采集完? { DMA_Cmd(DMA2_Stream1,DISABLE); //停止当前传输 while(DMA_GetCmdStatus(DMA2_Stream1) != DISABLE); //等待DMA2_Stream1可配置 rlen=jpeg_dma_bufsize-DMA_GetCurrDataCounter(DMA2_Stream1);//得到剩余数据长度 pbuf=jpeg_data_buf+jpeg_data_len;//偏移到有效数据末尾,继续添加 if(DMA2_Stream1->CR&(1<<19))for(i=0;iCR&(1<<19))//buf0已满,正常处理buf1 { for(i=0;iLCD_RAM,0,1,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Disable);//DCMI DMA配置 myfree(SRAMIN,f_jpg); return res; } int main(void) { u8 res; u8 *pname; //带路径的文件名 u8 key; //键值 u8 i; u8 sd_ok=1; //0,sd卡不正常;1,SD卡正常. u8 scale=1; //默认是全尺寸缩放 u8 msgbuf[15]; //消息缓存区 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 LED_Init(); //初始化LED usmart_dev.init(84); //初始化USMART TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次 LCD_Init(); //LCD初始化 FSMC_SRAM_Init(); //初始化外部SRAM. BEEP_Init(); //蜂鸣器初始化 KEY_Init(); //按键初始化 W25QXX_Init(); //初始化W25Q128 my_mem_init(SRAMIN); //初始化内部内存池 my_mem_init(SRAMEX); //初始化内部内存池 my_mem_init(SRAMCCM); //初始化CCM内存池 exfuns_init(); //为fatfs相关变量申请内存 f_mount(fs[0],"0:",1); //挂载SD卡 POINT_COLOR=RED; while(font_init()) //检查字库 { LCD_ShowString(30,50,200,16,16,"Font Error!"); delay_ms(200); LCD_Fill(30,50,240,66,WHITE);//清除显示 delay_ms(200); } Show_Str(30,50,200,16,"Explorer STM32F4开发板",16,0); Show_Str(30,70,200,16,"照相机实验",16,0); Show_Str(30,90,200,16,"KEY0:拍照(bmp格式)",16,0); Show_Str(30,110,200,16,"KEY1:拍照(jpg格式)",16,0); Show_Str(30,130,200,16,"WK_UP:FullSize/Scale",16,0); Show_Str(30,150,200,16,"2014年5月16日",16,0); res=f_mkdir("0:/PHOTO"); //创建PHOTO文件夹 if(res!=FR_EXIST&&res!=FR_OK) //发生了错误 { Show_Str(30,150,240,16,"SD卡错误!",16,0); delay_ms(200); Show_Str(30,170,240,16,"拍照功能将不可用!",16,0); sd_ok=0; } jpeg_buf0=mymalloc(SRAMIN,jpeg_dma_bufsize*4); //为jpeg dma接收申请内存 jpeg_buf1=mymalloc(SRAMIN,jpeg_dma_bufsize*4); //为jpeg dma接收申请内存 jpeg_data_buf=mymalloc(SRAMEX,300*1024); //为jpeg文件申请内存(最大300KB) pname=mymalloc(SRAMIN,30);//为带路径的文件名分配30个字节的内存 while(pname==NULL||!jpeg_buf0||!jpeg_buf1||!jpeg_data_buf) //内存分配出错 { Show_Str(30,190,240,16,"内存分配失败!",16,0); delay_ms(200); LCD_Fill(30,190,240,146,WHITE);//清除显示 delay_ms(200); } while(OV2640_Init())//初始化OV2640 { Show_Str(30,190,240,16,"OV2640 错误!",16,0); delay_ms(200); LCD_Fill(30,190,239,206,WHITE); delay_ms(200); } Show_Str(30,190,200,16,"OV2640 正常",16,0); delay_ms(2000); OV2640_RGB565_Mode(); //JPEG模式 My_DCMI_Init(); //DCMI配置 DCMI_DMA_Init((u32)&LCD->LCD_RAM,0,1,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Disable);//DCMI DMA配置 OV2640_OutSize_Set(lcddev.width,lcddev.height); DCMI_Start(); //启动传输 while(1) { key=KEY_Scan(0);//不支持连按 if(key) { DCMI_Stop(); //停止显示 if(key==WKUP_PRES) { scale=!scale; if(scale==0) { OV2640_ImageWin_Set((1600-lcddev.width)/2,(1200-lcddev.height)/2,lcddev.width,lcddev.height);//1:1真实尺寸 OV2640_OutSize_Set(lcddev.width,lcddev.height); sprintf((char*)msgbuf,"Full Size 1:1"); }else { OV2640_ImageWin_Set(0,0,1600,1200); //全尺寸缩放 OV2640_OutSize_Set(lcddev.width,lcddev.height); sprintf((char*)msgbuf,"Scale"); } LCD_ShowString(30,50,210,16,16,msgbuf);//显示提示内容 delay_ms(800); }else if(sd_ok)//SD卡正常才可以拍照 { sw_sdcard_mode(); //切换为SD卡模式 if(key==KEY0_PRES) //BMP拍照 { camera_new_pathname(pname,0);//得到文件名 res=bmp_encode(pname,0,0,lcddev.width,lcddev.height,0); }else if(key==KEY1_PRES)//JPG拍照 { camera_new_pathname(pname,1);//得到文件名 res=ov2640_jpg_photo(pname); if(scale==0) { OV2640_ImageWin_Set((1600-lcddev.width)/2,(1200-lcddev.height)/2,lcddev.width,lcddev.height);//1:1真实尺寸 OV2640_OutSize_Set(lcddev.width,lcddev.height); }else { OV2640_ImageWin_Set(0,0,1600,1200); //全尺寸缩放 } OV2640_OutSize_Set(lcddev.width,lcddev.height); } sw_ov2640_mode(); //切换为OV2640模式 if(res)//拍照有误 { Show_Str(30,130,240,16,"写入文件错误!",16,0); }else { Show_Str(30,130,240,16,"拍照成功!",16,0); Show_Str(30,150,240,16,"保存为:",16,0); Show_Str(30+42,150,240,16,pname,16,0); BEEP=1; //蜂鸣器短叫,提示拍照完成 delay_ms(100); } }else //提示SD卡错误 { Show_Str(30,130,240,16,"SD卡错误!",16,0); Show_Str(30,150,240,16,"拍照功能不可用!",16,0); } BEEP=0; //关闭蜂鸣器 if(key!=WKUP_PRES)delay_ms(1800);//非尺寸切换,等待1.8秒钟 DCMI_Start(); //停止显示 } delay_ms(10); i++; if(i==20)//DS0闪烁. { i=0; LED0=!LED0; } } }