目的:保存一帧1280*720的RGB565图片到外部SDRAM。
方法:采用双缓存方式 在407照相机实验 基础上改写程序。
现象和问题:
当 OV2640OutSize_Set(width1,height1); width1超过1164时 LCD上图像扭曲
取1280*720时从串口打印的传输数据总量来看 rgb data size:1733120 明显不够。
并且串口打印信息来看 从1168开始 开始缺少数据了
疑惑:
不清楚是1.摄像头rgb模式下实际输出尺寸的问题还是2.传输方式的问题
关于输出尺寸我觉得:
先是 OV2640_Init()里的 初始化 OV2640,采用SXGA分辨率(1600*1200)
然后调用 OV2640_OutSize_Set(width1,height1); 即可设置输出尺寸
难道 OV2640 RGB模式下 宽度设置在1200附近有什么不同吗?
关于传输方式:
我是直接在407照相机实验例程上改的 (只保留了双缓存原理相关的内容)
关键是width1设置为1164以下显示都正常,所以应该基本上改的是对的啊
实在是想不出来==,求大神指点呐。
串口打印信息: width=720 DMAITTIMES=51 DMAITTIMES0=25 DMAITTIMES1=26 rgb data size=1057280 Cha=20480 width=1000 DMAITTIMES=71 DMAITTIMES0=35 DMAITTIMES1=36 rgb data size=1460480 Cha=20480 width=1164 DMAITTIMES=82 DMAITTIMES0=42 DMAITTIMES1=40 rgb data size:1696640Cha=20480 width=1168 DMAITTIMES=83 DMAITTIMES0=41 DMAITTIMES1=42 rgb data size=1702400 Cha=20480 width=1172 DMAITTIMES=83 DMAITTIMES0=41 DMAITTIMES1=42 rgb data size=1703472 Cha=15792 width=1184 DMAITTIMES=83 DMAITTIMES0=41 DMAITTIMES1=42 rgb data size=1708864 Cha=3904 width=1200 DMAITTIMES=83 DMAITTIMES0=41 DMAITTIMES1=42 rgb data size=1717280 Cha=-10720 width=1280 DMAITTIMES=84 DMAITTIMES0=42 DMAITTIMES1=42 rgb data size=1733120 Cha=-110080 width=1320 DMAITTIMES=85 DMAITTIMES0=44 DMAITTIMES1=41 rgb data size=1750320 Cha=-150480
man.c
#define width1 1164#define height1 720
void rgb_data_process(void){ u16 i; u16 rlen;//剩余数据长度 u16 *pbuf;
if(rgb_data_ok==0) //jpeg数据还未采集完? { DMA_Cmd(DMA2_Stream1,DISABLE); //停止当前传输 while(DMA_GetCmdStatus(DMA2_Stream1) != DISABLE); //等待DMA2_Stream1可配置 rlen=rgb_dma_bufsize-DMA_GetCurrDataCounter(DMA2_Stream1);//得到剩余数据长度 pbuf=RGB+rgb_data_len;//偏移到有效数据末尾,继续添加 if(DMA2_Stream1->CR&(1<<19))for(i=0;i<rlen*2;i++)pbuf=rgbbuf1;//读取buf1里面的剩余数据 else for(i=0;i<rlen*2;i++)pbuf=rgbbuf0;//读取buf0里面的剩余数据 rgb_data_len+=rlen*2; //加上剩余长度 rgb_data_ok=1; //标记JPEG数据采集完按成,等待其他函数处 DCMI_Stop(); } if(rgb_data_ok==2) //上一次的jpeg数据已经被处理了 { DMA_SetCurrDataCounter(DMA2_Stream1,rgb_dma_bufsize);//传输长度为jpeg_buf_size*4字节 DMA_Cmd(DMA2_Stream1,ENABLE); //重新传输 rgb_data_ok=0; //标记数据未采集 rgb_data_len=0; //数据重新开始 } }
void rgb_dcmi_rx_callback(void){ DMAITTIMES++; // printf("
DMAITTIMES=%d
",DMAITTIMES); u16 i; u16 *pbuf; pbuf=RGB+rgb_data_len;//偏移到有效数据末尾 if(DMA2_Stream1->CR&(1<<19))//buf0已满,正常处理buf1 { DMAITTIMES0++; //printf("
DMAITTIMES0000=%d
",DMAITTIMES0); for(i=0;i<rgb_dma_bufsize*2;i++)pbuf=rgbbuf0;//读取buf0里面的数据 rgb_data_len+=rgb_dma_bufsize*2;//偏移 }else //buf1已满,正常处理buf0 { DMAITTIMES1++; //printf("
DMAITTIMES1111=%d
",DMAITTIMES1); for(i=0;i<rgb_dma_bufsize*2;i++)pbuf=rgbbuf1;//读取buf1里面的数据 rgb_data_len+=rgb_dma_bufsize*2;//偏移 } }
void rgb565_test(void){ while(1) { while(1) { if(USART_START==0x16540D) { USART_START=0; break; } Key=KEY_Scan(0); if(Key==KEY0_PRES) break; } DMA_DeInit(DMA2_Stream1); LCD_Clear(WHITE); POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"ALIENTEK STM32F4");
if(once==0) { while(OV2640_Init())//初始化OV2640 { LCD_ShowString(30,130,240,16,16,"OV2640 ERR"); delay_ms(200); LCD_Fill(30,130,239,170,WHITE); delay_ms(200); } delay_ms(2000); once=1; } OV2640_RGB565_Mode(); //RGB565模式 My_DCMI_Init(); //DCMI配置tmp_buff dcmi_rx_callback=rgb_dcmi_rx_callback;//回调函数 DMA_MemoryDataSize_Word DMA_MemoryDataSize_HalfWord DCMI_DMA_Init((u32)rgbbuf0,(u32)rgbbuf1,rgb_dma_bufsize,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);//DCMI DMA配置(双缓冲模式) //OV2640_JPEG_Mode(); //切换为JPEG模式 //OV2640_ImageWin_Set(0,0,1600,1200); OV2640_OutSize_Set(width1,height1);
DCMI_Start();
while(rgb_data_ok!=1); printf("
width=%d DMAITTIMES=%d DMAITTIMES0=%d DMAITTIMES1=%d rgb data size=%d
",width1,DMAITTIMES,DMAITTIMES0,DMAITTIMES1,rgb_data_len*2);
//显示验证 LCD_Clear(WHITE); LCD_SetCursor(0,0); LCD_WriteRAM_Prepare(); for(k=0;k<height1;k++) for(j=0;j<width1;j++) if((k<800)&&(j<480))//720 LCD_WriteRAM(RGB[k*width1+j]); delay_ms(1000); LCD_Clear(WHITE); LCD_SetCursor(0,0); LCD_WriteRAM_Prepare(); for(k=0;k<height1;k++) for(j=0;j<width1;j++) if((k<720)&&(j>=(width1-480))) LCD_WriteRAM(RGB[k*width1+j]);
} }
int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(180); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 usart2_init(42,115200); //初始化串口2波特率为115200 LED_Init(); //初始化LED LCD_Init(); //LCD初始化 KEY_Init(); //按键初始化 SDRAM_Init();
POINT_COLOR=RED;//设置字体为红 {MOD} LCD_ShowString(130,230,200,16,24,"RGB565-MODE");
u8 paddr[20]; //存放P Addr:+p地址的ASCII值 u16 memused=0; u8 i=0; u8 *p=0; u8 *tp=0; u8 sramx=0; //默认为内部sram
my_mem_init(0); //初始化内部内存池 my_mem_init(1); //初始化外部内存池 my_mem_init(2); //初始化CCM内存池 rgbbuf0=mymalloc(SRAMIN,rgb_dma_bufsize*4); rgbbuf1=mymalloc(SRAMIN,rgb_dma_bufsize*4); RGB=mymalloc(SRAMEX,height1*width1*2); img565 = (u16*)mymalloc(1,height1*width1*2);
LCD_ShowString(30,130,200,16,16,"KEY0:Malloc KEY2:Free"); LCD_ShowString(30,150,200,16,16,"KEY_UP:SRAMx KEY1:Read"); POINT_COLOR=BLUE;//设置字体为蓝 {MOD}
rgb565_test();
}
摄像头DEMO就是不保存直接传到LCD了啊
一周热门 更多>