STM32/STM8技术论坛
直播中

胡卫伟

7年用户 285经验值
私信 关注
[问答]

STM32 DCMI DMA 640*480相机没有数据输出

烦恼啊 !
DMA_InitStructure.DMA_BufferSize 最大才65536个数据项数目,做320*240的分辨率设置成:
DMA_InitStructure.DMA_BufferSize = 320*240/2;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
这样功能正常,正常摄像。但是想到改成640*480分辨率我就头大了 ,640*480/2 > 65536,设置不了这么大 如果我设置DCMI中断,再设置
DMA_InitStructure.DMA_BufferSize = 320*240/2; 这样就只能得到1/4的数据  再DCMI中断重设DMA ,结果DCMI是一帧中断的, 设的4个DMABUFF得到的不是同一帧数据,于是我换成DMA中断,更改如下:
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;        
DMA_NVIC_Config();
DMA_ITConfig(DMA2_Stream1,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA2_Stream1,ENABLE);                        

//拷贝自神舟开发板例程  结果相机就没有数据输出  唉 !我的天 STM32F4 有没有弄出480*640的分辨率的相机的大师 给个代码让我瞧瞧是用了什么办法

回帖(9)

蔡彦壁

2019-3-7 07:37:38
      用DCMI_CaptureMode_SnapShot方式,当DCMI需要DMA传输640*480*2个字节,假设DMA的传输DMA_BufferSize=640个字节,那么DMA2_Stream1_IRQHandler 里的  DMA_IT_TCIF1中断就会发生480*2次。 也就是说DMA会按照DMA_BufferSize的大小把DCMI的数据全部传输完成,就是循环的覆盖DMA_Memory0BaseAddr里的数据。将DMA的目标地址直接设置为你的外部SRAM地址,然后设置摄像头的DMA传输长度为1,在DMA2_Stream1_IRQHandler 中断里及时把数据copy出去。
举报

蔡彦壁

2019-3-7 07:57:13
本帖最后由 奔跑小蜗牛 于 2014-12-18 16:59 编辑

你当然不能一股脑的把数据往SRAM里塞,塞的太多,时间超时,会造成DMA停止。
DMA传输长度就是指DMA_Buffersize
//DCMI DMA配置
void DCMI_DMA_Init(void)
{  
RCC->AHB1ENR|=1<<22;         //DMA2时钟使能  
         while(DMA2_Stream1->CR&0X01);//等待DMA2_Stream1可配置  
DMA2->LIFCR|=0X3D<<6*1;         //清空通道1上所有中断标志
DMA2_Stream1->FCR=0X0000021;//设置为默认值        

DMA2_Stream1-> PAR=(u32)&DCMI->DR;         //外设地址为: DCMI-> DR
DMA2_Stream1->M0AR=(u32)&(LCD->LCD_RAM);//LCD_RAM 作为目标地址
DMA2_Stream1->NDTR=1;         //传输长度为1
DMA2_Stream1->CR=0;         //先全部复位CR寄存器值   
DMA2_Stream1->CR|=0<<6;         //外设到存储器模式  
DMA2_Stream1->CR|=1<<8;         //循环模式
DMA2_Stream1->CR|=0<<9;         //外设非增量模式
DMA2_Stream1->CR|=0<<10;        //存储器非增量模式
DMA2_Stream1->CR|=2<<11;        //外设数据长度:32位
DMA2_Stream1->CR|=1<<13;        //存储器数据长度:16位
DMA2_Stream1->CR|=2<<16;        //高优先级
DMA2_Stream1->CR|=0<<21;        //外设突发单次传输
DMA2_Stream1->CR|=0<<23;        //存储器突发单次传输
DMA2_Stream1->CR|=1<<25;        //通道1 DCMI通道  
DMA2_Stream1->FCR|=1<<2;        //FIFO模式
DMA2_Stream1->FCR|=3<<0;        //是用全FIFO  
}

把上面的LCD->LCD_RAM改为你的:外部SRAM存放摄像头数据的首地址,SRAM你设置为地址自增,然后传输完一帧要中断,重新设置传输量。 中断你可以采用DCMI的帧中断,到里面再次去设置DMA。这里DMA仅仅负责搬运,不停的将DCMI->DR的数据,搬运到目标地址,一次搬运长度是1.
举报

胡卫伟

2019-3-7 08:08:11
怎么没人回答呢  我的思路是 在DMA里面重新设置DMA缓冲区地址,共设置了4个缓冲区,中断一次传输320*240*2个字节,并变换缓冲区。这样,中断4次 ,640*480的数据就被全部接受了
举报

袁富存

2019-3-7 08:24:14
引用: 屠鸡勇士李运好 发表于 2019-3-7 20:47
怎么没人回答呢  我的思路是 在DMA里面重新设置DMA缓冲区地址,共设置了4个缓冲区,中断一次传输320*240*2个字节,并变换缓冲区。这样,中断4次 ,640*480的数据就被全部接受了

思路不错啊,程序呢
举报

袁富存

2019-3-7 08:41:41
试试DMA  double buffer
举报

何秀珍

2019-3-7 08:55:25
你完全可以建立多个缓冲区,DMA满了转移数据就是
举报

胡卫伟

2019-3-7 09:15:02
引用: 冬冬5241 发表于 2019-3-7 21:03
思路不错啊,程序呢

就是程序没调成功 苦恼着
举报

胡卫伟

2019-3-7 09:25:03
引用: 报纸弟弟麦花 发表于 2019-3-7 20:17
      用DCMI_CaptureMode_SnapShot方式,当DCMI需要DMA传输640*480*2个字节,假设DMA的传输DMA_BufferSize=640个字节,那么DMA2_Stream1_IRQHandler 里的  DMA_IT_TCIF1中断就会发生480*2次。 也就是说DMA会按照DMA_BufferSize的大小把DCMI的数据全部传输完成,就是循环的覆盖DMA_Memory0BaseAddr里的数据。将DMA的 ...

我好像在哪里看到过你写的帖子,我用DMA 中断四次 果然不行 传输出来不是同一帧的 。。。。我有几个问题: 1. 中断次数不需要设定,设置好DMA_Buffersize它就会中断480*2次。
2. 摄像头的DMA传输长度,也是指DMA_Buffersize吧?
3. DMA_Buffersize我如果不设置为1,我设置一次传320*240*2,那么会不会因为中断程序时间长了,导致DMA数据丢失
举报

胡卫伟

2019-3-7 09:35:00
唉,尼玛,突然觉得512的SRAM不够用了
举报

更多回帖

发帖
×
20
完善资料,
赚取积分