OpenEdv-开源电子网

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

为什么用DCMI读取OV2640JPEG时要DMA用双缓存模式

[复制链接]

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2016-4-8
在线时间
27 小时
发表于 2016-6-3 12:08:36 | 显示全部楼层 |阅读模式
5金钱
原子例程里有一个300K的缓存区,为什么不直接把数据存在那个缓存里,而是要用DMA的双缓存模式一段一段存进两个小的缓存区,再转到大缓存区里,这样不会影响速度吗?

最佳答案

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

因为直接DMA到外部SRAM,外部SRAM速度跟不上,会丢数据!!! 所以先用内部SRAM缓存一下
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-6-3 12:08:37 | 显示全部楼层
因为直接DMA到外部SRAM,外部SRAM速度跟不上,会丢数据!!!
所以先用内部SRAM缓存一下
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2082
金钱
2082
注册时间
2014-12-19
在线时间
711 小时
发表于 2016-6-3 14:33:27 | 显示全部楼层
以下来自第47章照相机实验:
DMA 接收来自 OV2640 的 JPEG 数据流,首先使用 M0AR(内存 1)来存储,当 M0AR 满了以后,自动切换到 M1AR(内存 2),同时程序读取 M0AR(内存 1)的数据到外部 SRAM;当 M1AR 满了以后,又切回 M0AR,同时程序读取 M1AR(内存 2)的数据到外部 SRAM;依次循环(此时的数据处理,是通过 DMA 传输完成中断实现的,在中断里面处理),直到帧中断,结束一帧数据的采集,读取剩余数据到外部 SRAM,完成一次 JPEG 数据的采集。
这里, M0AR, M1AR 所指向的内存,必须是内部内存,不过由于采用了双缓冲机制,我们就不必定义一个很大的数组,一次性接收所有 JPEG 数据了,而是可以分批次接收,数组可以定义的比较小。

在内存有限的情况下,如果把几乎全部内存用于缓存JPEG数据,那其他任务就没法运行了。这个例子当中必须用到FATFS和SD卡,想必也要占用一些内存。所以采用双缓冲机制是个很好的办法。只要定义的缓冲大小合适,应该不会有影响。
回复

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2016-4-8
在线时间
27 小时
 楼主| 发表于 2016-6-3 14:45:39 | 显示全部楼层
lvehe 发表于 2016-6-3 14:33
以下来自第47章照相机实验:

在内存有限的情况下,如果把几乎全部内存用于缓存JPEG数据,那其他任务就没 ...

为什么不直接存到外部sram里呢?
回复

使用道具 举报

3

主题

347

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
2082
金钱
2082
注册时间
2014-12-19
在线时间
711 小时
发表于 2016-6-3 14:47:08 | 显示全部楼层
zhangyuman 发表于 2016-6-3 14:45
为什么不直接存到外部sram里呢?

你愿意的话也可以啊,原子只是给出一个示例而已。程序千变万化,只要搞懂原理了,自己可以任意调配资源,自由组合,不必拘泥。
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2016-10-17
在线时间
9 小时
发表于 2016-10-17 19:48:24 | 显示全部楼层
这个地方我也有疑问:
如果是因为片外SRAM速度慢的原因,那么在DMA中断里把片内SRAM搬运到片外SRAM的过程同样快不了,还增加了CPU的开销
我想,是不是由于DMA的配置里最大传输数量只支持65535,导致不能传输过大的数据的原因呢。
视频讲解中确实提到是速度的原因,不知道原子哥的例程到底是出于什么考虑呢?
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2017-6-24
在线时间
3 小时
发表于 2017-6-24 20:53:11 来自手机 | 显示全部楼层
这两天用到OV2640了,感觉也疑惑,!我和6楼的想法一致!双缓存的原因不应该是速度问题,应该是内部SRAM不够一次存储
回复

使用道具 举报

9

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2019-10-19
在线时间
46 小时
发表于 2020-5-19 17:12:46 | 显示全部楼层
liuzb029 发表于 2017-6-24 20:53
这两天用到OV2640了,感觉也疑惑,!我和6楼的想法一致!双缓存的原因不应该是速度问题,应该是内部SRAM不 ...

我对比过F407用OV2640,120*480像素,用内部SRAM OK;切换到外部SRAM,偶尔正常,通常是乱码。测试下来,外部SRAM是会出现乱码。 而原子哥的双内存法,确实不理解CPU在搬运其中一块,DMA在写另一个块。CPU比DMA写外部SRAM还快?不理解
回复

使用道具 举报

9

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2019-10-19
在线时间
46 小时
发表于 2020-5-19 18:51:55 | 显示全部楼层
我认为DMA 写外部SRAM不是速度问题,而是数据保持时间问题。

模仿LCD的接口设置SRAM时序,DMA将OV2640的数据写到外部SRAM,然后将数据显示在LCD上,还是不正常。但是用内部SRAM就正常(我申请空间120*480).
我觉得不是外部写速度太慢,DMA将数据放到LCD上,写时序很慢,我怀疑是外部SRAM的写操作,NWE变高后,DATA只维持一个时钟,导致的问题。记得早年用NXP的芯片,访问一个黑白LCD,就是这个问题,后来用IO模拟的SRAM时序,就OK了。

        //寄存器清零
        //bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
        //这里我们使用NE1 ,也就对应BTCR[0],[1]。                                    
        FSMC_Bank1->BTCR[4]=0X00000000;
        FSMC_Bank1->BTCR[5]=0X00000000;
        FSMC_Bank1E->BWTR[4]=0X00000000;
        //操作BCR寄存器        使用异步模式
        FSMC_Bank1->BTCR[4]|=1<<12;                //存储器写使能
        FSMC_Bank1->BTCR[4]|=1<<14;                //读写使用不同的时序
        FSMC_Bank1->BTCR[4]|=1<<4;                 //存储器数据宽度为16bit             
        //操作BTR寄存器       
        //读时序控制寄存器                                                             
        FSMC_Bank1->BTCR[5]|=0<<28;                //模式A                                                                     
        FSMC_Bank1->BTCR[5]|=0XF<<0;         //地址建立时间(ADDSET)为15个HCLK 1/168M=6ns*15=90ns       
        //因为液晶驱动IC的读数据的时候,速度不能太快,尤其是个别奇葩芯片。
        FSMC_Bank1->BTCR[5]|=60<<8;          //数据保存时间(DATAST)为60个HCLK        =6*60=360ns
        //写时序控制寄存器  
        FSMC_Bank1E->BWTR[4]|=0<<28;         //模式A                                                                      
        FSMC_Bank1E->BWTR[4]|=9<<0;                //地址建立时间(ADDSET)为9个HCLK=54ns
        //9个HCLK(HCLK=168M),某些液晶驱动IC的写信号脉宽,最少也得50ns。           
        FSMC_Bank1E->BWTR[4]|=8<<8;         //数据保存时间(DATAST)为6ns*9个HCLK=54ns
        //使能BANK1,区域4
        FSMC_Bank1->BTCR[4]|=1<<0;                //使能BANK1,区域1         
回复

使用道具 举报

9

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2019-10-19
在线时间
46 小时
发表于 2020-5-19 19:12:13 | 显示全部楼层
hemanzi 发表于 2020-5-19 18:51
我认为DMA 写外部SRAM不是速度问题,而是数据保持时间问题。

模仿LCD的接口设置SRAM时序,DMA将OV2640的 ...

用正点原子的正常外部SRAM配置时序,执行DMA到外部SRAM,发现DCMI控制出现了这个错误。而数据到LCD的RAM和到内部SRAM,观察不到。
//观察DCMI_SR寄存器 OVR_RIS: 溢出原始中断状态 1:发生数据缓冲区溢出,数据 FIFO 损坏         DMA到SRAM会触发这个错误
回复

使用道具 举报

9

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2019-10-19
在线时间
46 小时
发表于 2020-5-20 08:40:05 | 显示全部楼层
对比原子哥的源代码,LCD RAM和外部SRAM其实是一样的东西,LCD RAM可以直接DMA,而外部SRAM就不行,没有道理啊!我曾怀疑是DMA将地址增加带来了时间开销。就将SRAM缓存数据时,也像LCD RAM一样,地址不增加,发现还是报OVR_RIS错误,即DCMI中FIFO溢出了。将外部SRAM改成LCD RAM的时序(其实这会更慢),也会报这个错误。这个DCMI通过DMA缓存数据到外部SRAM,会DCMI的FIFO溢出,导致传输异常(一旦异常,这帧数据是会抛弃的),不知道究竟是哪里的问题?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 01:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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