OV2640 RGB模式下 输出宽度设置问题

2019-07-20 11:12发布

目的:保存一帧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();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
21条回答
基佬夫iscoming
1楼-- · 2019-07-20 22:32
 精彩回答 2  元偷偷看……
基佬夫iscoming
2楼-- · 2019-07-21 01:49
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

摄像头DEMO就是不保存直接传到LCD了啊
正点原子
3楼-- · 2019-07-21 03:26
基佬夫iscoming 发表于 2017-10-30 17:14
摄像头DEMO就是不保存直接传到LCD了啊

你把LCD改成sram很难么?
基佬夫iscoming
4楼-- · 2019-07-21 09:12
 精彩回答 2  元偷偷看……
基佬夫iscoming
5楼-- · 2019-07-21 11:08
 精彩回答 2  元偷偷看……
基佬夫iscoming
6楼-- · 2019-07-21 15:54
本帖最后由 基佬夫iscoming 于 2017-10-31 11:06 编辑
正点原子 发表于 2017-10-31 00:38
你把LCD改成sram很难么?

之前可能表述不太清楚,现在的问题是:
在摄像头实验例程里:
1.帧中断里让DCMI停止,只传一帧。
2.Outsize(1280,720)后直接传输到4.3寸 LCD 上

1280:
捕获.PNG

1280*7209216002.440%25.5%负15%

一周热门 更多>