您的位置: OpenADSP社区论坛 -> Blackfin专区 -> 新手上路 -> FLOW_AUTO | DI_SEL  如何使用?
本帖共有538个阅读者
发表帖子 发表投票 回复主题
FLOW_AUTO | DI_SEL 如何使用?
bh99(论坛新手)
bh99
头衔:社区公民
帮派:无帮无派
帖数:25
金钱:337
积分:41
注册时间:2012/4/24
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
FLOW_AUTO | DI_SEL 如何使用?

摄像头采集,黑白,240*240。我的目的是把采集数据放到一个240*30行的缓冲区中,每行中断一次,中断中对本行与相邻行的数据进行计算。

我理解  FLOW_AUTO | DI_SEL ,就是每行中断一次,如果缓冲区设置为120行(*pDMA0_Y_COUNT=120),则第121行数据又写到了第1行缓冲区。把2次缓冲区的数据拼起来,就是完整的一帧240行。

我按照这种理解写程序,发现不对,百思不得其解,还请再指教一下。

能否给个摄像头乒乓缓冲区的代码参考一下呢?


#define CMOS_WIDTH 240

#define CMOS_HEIGHT 240

#define BUFFER_HEIGHT 240   //240时采集正常,改为120,60,则不对了

unsigned int lineIndex=0;

void   Video_Frame_Capture(void)
{
    lineIndex=0;
    
   *pPPI_FRAME = CMOS_HEIGHT;  //这里永远是240吧?
    *pPPI_COUNT = CMOS_WIDTH-1;    
    *pPPI_DELAY = 0;      
    *pPPI_CONTROL = 0x01AC;
    
    *pDMA0_START_ADDR = ydata_buffer;    
    *pDMA0_X_COUNT = CMOS_WIDTH>>1;
    *pDMA0_X_MODIFY = 0x2;            
    *pDMA0_Y_COUNT = BUFFER_HEIGHT;    
    *pDMA0_Y_MODIFY = 0x2;                                                
    *pDMA0_PERIPHERAL_MAP = 0x0;            
    *pDMA0_CONFIG =  WNR | WDSIZE_16| DMA2D | RESTART | DI_EN | FLOW_AUTO | DI_SEL;   
    *pDMA0_CONFIG |= DMAEN;
    
    ssync();
    *pPPI_CONTROL |= PORT_EN;
    ssync();                
}

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR)
{    
    int i,j;
    int bufferLine,bufferLineNext,displayLine,displayBufferIndex,bufferIndex,bufferIndexNextLine;
    unsigned char y;
    *pDMA0_IRQ_STATUS = 0x1;  
    
    bufferLine=lineIndex % BUFFER_HEIGHT;  //lineIndex表示中断的次数,也就是摄像头的第几行,从0开始,bufferLine表示摄像头的这行数据存储在DMA缓冲区的哪一行
    bufferIndex=CMOS_WIDTH*bufferLine;     //bufferIndex表示该行第0像素的位置

    displayLine=lineIndex % CMOS_HEIGHT;   //displayLine表示yDisplayBuffer_565的第几行
    displayBufferIndex=2*CMOS_WIDTH*displayLine;  //displayBufferIndex表示第0像素的位置
    

    //把DMA缓冲区的一行数据,搬移到显示缓冲区yDisplayBuffer_565

    for(i=0;i<CMOS_WIDTH;i++)
    {
        y=ydata_buffer[bufferIndex];
        yDisplayBuffer_565[displayBufferIndex+1] = y&0xf8;    
        yDisplayBuffer_565[displayBufferIndex+1] |= (y>>5)&0x07;    
        yDisplayBuffer_565[displayBufferIndex]  = (y<<3)&0xe0;
        yDisplayBuffer_565[displayBufferIndex] |= (y>>3)&0x1f;        
            
        bufferIndex++;
        displayBufferIndex+=2;    
    }
    

    //全部240行搬移完毕后,在屏幕上显示出来
    if(lineIndex==(CMOS_HEIGHT-1))
    {
        Write_pic(yDisplayBuffer_565,CMOS_HEIGHT,CMOS_WIDTH,0,0);
    }
                      
    lineIndex++;                     //每一行中断一次
    lineIndex %= CMOS_HEIGHT;        

}


当设置缓冲区为完整的一帧(240行)时,图像采集正常(正常图像左下、右下两个角是黑的)。此时,*pPPI_FRAME =240,*pDMA0_Y_COUNT = 240;使用1遍缓冲区。

当设置缓冲区为1/2帧(120行)时,图像跳变,正常图像和错位图像交替出现(见图)。此时,*pPPI_FRAME =240,*pDMA0_Y_COUNT = 120;使用2遍缓冲区。设置*pPPI_FRAME =120,现象一样,第1行到第240行的数据能在某个时刻某个位置显示出来,只是不能按顺序拼成完整的一帧。

上传的图片
  2013532327682.jpg [ 15.64 KB 259×260 ] (缩略时请点击查看原图)

 

上传的图片
  20135323272382.jpg [ 17.16 KB 252×256 ] (缩略时请点击查看原图)

 


当设置缓冲区为1/4帧(60行)时,图像滚屏(应该是多个子图交替错位),(见图)。此时,*pPPI_FRAME =240,*pDMA0_Y_COUNT = 60;使用4遍缓冲区。设置*pPPI_FRAME =60,现象一样,第1行到第240行的数据能在某个时刻某个位置显示出来,只是不能按顺序拼成完整的一帧。

上传的图片
  20135323273482.jpg [ 16.22 KB 261×260 ] (缩略时请点击查看原图)

 





「该帖子被 bh99 在 2013-05-04 00:16:37 编辑过」

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2013/5/3 23:31:56
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
1信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
图像交错是你的DMA完成部分数据采集后没有马上启动继续采集,导致部分数据丢失。你的代码中也看不到立刻启动DMA采集的代码,而是进入中断后做了一堆的处理,这会导致你继续采集的图像数据丢失。如果想采集部分数据拼接成一幅图像,必须使用乒乓buffer机制,否则会导致后面的数据丢失。

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2013/5/4 14:40:28
bh99(论坛新手)
bh99
头衔:社区公民
帮派:无帮无派
帖数:25
金钱:337
积分:41
注册时间:2012/4/24
2信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

我理解 FLOW_AUTO了,DMA就永不停息了。每行中断的话,比乒乓缓冲区还多啊。不是这样吗?


这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2013/5/4 16:39:25
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
3信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
DMA是没有停止,当你处理完中断后,再次进入中断,所采的数据就不知道是哪一帧的哪一部分了

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2013/5/5 13:37:27
Powered by OpenADSP Copyright © 2010 www.Openadsp.com. All rights reserved.159236 Call, 1 Queries, Processed in 0.031250 second(s),