OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6109|回复: 21

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

[复制链接]

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
发表于 2017-10-29 13:07:59 | 显示全部楼层 |阅读模式
20金钱
目的:保存一帧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:1696640
Cha=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("\r\nDMAITTIMES=%d\r\n",DMAITTIMES);
       
        u16 i;
        u16 *pbuf;
        pbuf=RGB+rgb_data_len;//偏移到有效数据末尾
        if(DMA2_Stream1->CR&(1<<19))//buf0已满,正常处理buf1
        { DMAITTIMES0++;       
                //printf("\r\nDMAITTIMES0000=%d\r\n",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("\r\nDMAITTIMES1111=%d\r\n",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("\r\n width=%d DMAITTIMES=%d  DMAITTIMES0=%d  DMAITTIMES1=%d  rgb data size=%d \r\n",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;//设置字体为红色          
        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;//设置字体为蓝色

        rgb565_test();

}

最佳答案

查看完整内容[请看2#楼]

是的,在RGB模式下,无法采集这么大区域的图像的。 我测试过1024*600都到不了。 你强制设置这么大,就会发现最后会有一批数据丢失。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-10-29 13:08:00 | 显示全部楼层
基佬夫iscoming 发表于 2017-11-1 15:31
我把pclk从例程的36M降到12/9/7.2M,看得出屏幕刷新速度确实变慢了,不过分界线仍在那个位置.OV2640输出 ...

是的,在RGB模式下,无法采集这么大区域的图像的。
我测试过1024*600都到不了。
你强制设置这么大,就会发现最后会有一批数据丢失。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-29 13:11:22 | 显示全部楼层
顶顶顶顶顶顶顶顶顶
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-10-30 01:16:56 | 显示全部楼层
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-30 16:53:18 | 显示全部楼层
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

原子哥,你好。
我记得把数据写到LCD的GRAM 当数据量超过lcd总的像素点数时 是会从头开始覆盖显示的,虽然大尺寸不能看出正常图像但是最终数据显示结束时会有一个分界线。
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-30 17:02:28 | 显示全部楼层
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

所以在407开发板上用摄像头实验的DEMO试了一下

1.在帧中断里调用了DCMI_Stop();让只传输一帧。
2.试验了
OV2640_OutSize_Set(1100,720);
OV2640_OutSize_Set(1164,720);
.......
OV2640_OutSize_Set(1280,720);
OV2640_OutSize_Set(1400,720);  

结果如图:

回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-30 17:04:05 | 显示全部楼层
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

发现 1280 1400 尺寸的分界线 比预计差了很多,并且是负的,说明是少数据的 也就是实际开窗有问题啊

回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-30 17:07:50 | 显示全部楼层
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

图图图兔兔图图图兔兔
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-30 17:14:14 | 显示全部楼层
正点原子 发表于 2017-10-30 01:16
你先搞定显示在lcd上面,再来看保存的问题。
显示在lcd上面,参考我们OV5640的设置即可。

摄像头DEMO就是不保存直接传到LCD了啊
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-10-31 00:38:38 | 显示全部楼层
基佬夫iscoming 发表于 2017-10-30 17:14
摄像头DEMO就是不保存直接传到LCD了啊

你把LCD改成sram很难么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-31 10:44:47 | 显示全部楼层
正点原子 发表于 2017-10-31 00:38
你把LCD改成sram很难么?

分界线反应出 数据明显少了啊
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-31 10:51:05 | 显示全部楼层
正点原子 发表于 2017-10-31 00:38
你把LCD改成sram很难么?

分界线反应出 数据明显少了啊
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-31 10:53:55 | 显示全部楼层
本帖最后由 基佬夫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*720
921600
2.4
40%
25.5%
负15%

就是这个分界线  1280*720的数据量 刷屏2.4次 应该占屏40%左右,而图中的分界线 我量出来 占比25.5%



1164: 1164c.PNG

1164*720
838080
2.1825
18.25%
18.60%
0.35%

宽度1164及以下 测得若干尺寸都符合预期了

那不就是 实际输出的宽度没有达到1280吗?



回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-10-31 11:07:24 | 显示全部楼层
请原谅,语文不好,求解答啊
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-11-1 00:29:30 | 显示全部楼层
基佬夫iscoming 发表于 2017-10-31 10:53
之前可能表述不太清楚,现在的问题是:
在摄像头实验例程里:
1.帧中断里让DCMI停止,只传一帧。

输出尺寸太大了,MCU会处理不过来!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-11-1 00:29:43 | 显示全部楼层
减少输出尺寸试试先
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-11-1 14:39:23 | 显示全部楼层
正点原子 发表于 2017-11-1 00:29
减少输出尺寸试试先

减少输出尺寸:   宽度1164及以下 测得分界线都符合预期。超过1164 尺寸设得越大缺少的数据越多。
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-11-1 14:42:39 | 显示全部楼层
正点原子 发表于 2017-11-1 00:29
输出尺寸太大了,MCU会处理不过来!

MCU会处理不过来,怎么理解? LCD写入时钟跟不上? 求解答
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-11-1 15:31:55 | 显示全部楼层
本帖最后由 基佬夫iscoming 于 2017-11-1 15:37 编辑
正点原子 发表于 2017-11-1 00:29
减少输出尺寸试试先

我把pclk从例程的36M降到12/9/7.2M,看得出屏幕刷新速度确实变慢了,不过分界线仍在那个位置.OV2640输出速度低了,其他不变,还是缺数据,怎么解释呢?  难道按照例程的配置 OV2640在RGB模式下根本就无法实际输出1280*720的尺寸???

回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-11-2 20:15:35 | 显示全部楼层
正点原子 发表于 2017-11-2 01:11
是的,在RGB模式下,无法采集这么大区域的图像的。
我测试过1024*600都到不了。
你强制设置这么大,就 ...

好吧,现在只能尝试输出YUV 看能不能达到尺寸了
回复

使用道具 举报

2

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2017-9-26
在线时间
22 小时
 楼主| 发表于 2017-11-2 20:16:01 | 显示全部楼层
正点原子 发表于 2017-11-2 01:11
是的,在RGB模式下,无法采集这么大区域的图像的。
我测试过1024*600都到不了。
你强制设置这么大,就 ...

有几个问题能给点指导意见吗?
在摄像头例程里:
1.输出YUV格式数据,OV2640的寄存器配置方面:只写入例程里的ov2640_yuv422_reg_tbl 就可以了吗
2.在1的基础上能否输出1280*720的尺寸的YUV数据?
3.把OV2640输出YUV422 再转成RGB565 可行吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-11-3 01:22:12 | 显示全部楼层
基佬夫iscoming 发表于 2017-11-2 20:16
有几个问题能给点指导意见吗?
在摄像头例程里:
1.输出YUV格式数据,OV2640的寄存器配置方面:只写入 ...

我没用过YUV格式,你可以试试
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-19 01:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表