您的位置: OpenADSP社区论坛 -> Blackfin专区 -> 新手上路 -> PPI例程
本帖共有2578个阅读者
发表帖子 发表投票 回复主题
PPI例程
unconscious(论坛新手)
unconscious
头衔:社区公民
帮派:无帮无派
帖数:67
金钱:746
积分:86
注册时间:2013/8/2
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
PPI例程

andy,我没找到那个例子代码,能不能发给我下或者给我个链接?谢谢啦

具体的问题:1、 采集640*960数据,以下设置是按帧采的是吗?按线的话如何设置?有什么需要注意的?

void Video_Frame_Capture(void)
{

   *pPPI_FRAME   = 960;          
    *pPPI_COUNT   = 1279;    //640*960    
    *pPPI_DELAY   = 0;    
    *pPPI_CONTROL = 0x01AC;      //POLS POLC all 0
    
    *pDMA0_START_ADDR = databuf;    
    *pDMA0_X_COUNT    = 640;
    *pDMA0_X_MODIFY   = 0x1;            
    *pDMA0_Y_COUNT    = 960;    
    *pDMA0_Y_MODIFY   = 0x1;                                                    
    *pDMA0_PERIPHERAL_MAP = 0x0;
    *pDMA0_CONFIG         =  WNR | WDSIZE_8| DMA2D | DI_EN;
    *pDMA0_CONFIG        |= DMAEN;
    ssync();
    *pPPI_CONTROL        |= PORT_EN;
    ssync();

}    

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR)
{    
        CMOS_PPI_Disable();
        *pDMA0_IRQ_STATUS = 0x1;     //开DMA0通道的中断
        captureFinished = 1;        //采集完成标志      
}        

2、现在的需求:一帧图像960行,在采集到第700行时置高IO口,一帧采完再置低。

应该采用什么方法实现以上,并使IO波形与一帧的开始与结束同步呢?

谢谢andy~

3、中断等级设置中*pSIC_IAR2 = 0xfffffff5  这个值是怎么得到的?我没找到相关的说明。PPI的中断等级和TIMER的中断等级可以设为一个吗?



    

  



「该帖子被 unconscious 在 2014-02-17 20:42:22 编辑过」

^_^
等级:论坛新手 参考IP地址:*.*.*.*
2014/2/17 9:28:19
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
1信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
1,看这个代码:
http://www.openadsp.com/bbs/topic.asp?id=1536&boardid=18&tb=1
2, 在中断中做个计数,采一条线计数+1,当为700时,设置IO口电平...
3,帮助文件搜索“SIC_IMASK0”,找到bf51x部分,可以找到 :
Table 5-3. Peripheral Interrupt Events (Part 1)

从里面可以看到SIC_IAR2 的每一位的配置值,这个寄存器时设置中断等级的,每个中断都有一个默认等级,当SIC_IAR2值为0时,等级最高,对应等级为IVG7,为1时对应IVG8。具体你可以看看BF533上相应的教学视频。

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/2/17 20:57:08
unconscious(论坛新手)
unconscious
头衔:社区公民
帮派:无帮无派
帖数:67
金钱:746
积分:86
注册时间:2013/8/2
2信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

uint8_t databuf[640*960];
uint8_t buffer[640];

void Video_Frame_Capture(void)
{
    *pPPI_FRAME   = 960;          
    *pPPI_COUNT   = 1279;    //640*960  
    *pPPI_DELAY   = 0;    
    *pPPI_CONTROL = 0x01AC;      //POLS POLC all 0
    
    *pDMA0_START_ADDR = buffer;    
    *pDMA0_X_COUNT    = 640;
    *pDMA0_X_MODIFY   = 0x1;            
    *pDMA0_Y_COUNT    = 1;   //按线采
    *pDMA0_Y_MODIFY   = 0x1;                                                    
    *pDMA0_PERIPHERAL_MAP = 0x0;
    *pDMA0_CONFIG         =  WNR | WDSIZE_8| DMA2D | DI_EN;            
}

int count = 0;
int i = 0,j = 0;

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR)
{    
        *pDMA0_IRQ_STATUS = 0x1;     //开DMA0通道的中断
         CMOS_PPI_Disable();
        
        count++;  
        
        for(i = 0; i < 640; i++)  //将采到的每一行写入帧图像缓冲区
        {

            databuf[j] = buffer[i];   //buffer为按行采时的数据缓冲区,databuf为一帧图像的数据缓冲区
            j++;
        }

        if(count = 500)  //采到第500行时置高PF13
        {
            *pPORTFIO_DIR      |= PF13;
            *pPORTFIO          |= PF13;  
        }
              
        if(count = 960)  //一帧图像采集完成  将PF13置低
        {
            count = 0;
            captureFinished = 1;        //采集一帧完成标志
            *pPORTFIO          &= ~PF13;
        }
         buffer[640] = 0;
         Video_Frame_Capture();
}

1、麻烦andy帮我看下这块的程序,中断设置中是否有问题,我后打印输出的图像数据第一帧全为0,后面有数据但是图像不对。。PF13的波形也不对

2、根据help中的SIC表,我按以下设置,TIMER2进不了中断。。这个和上面的程序没有关系

void InitInterrupts(void)
{          
    *pSIC_IAR4 = 0xfffffff4;        
    register_handler(ik_ivg12, TIMER2_ISR);        
    *pSIC_IMASK1 = 0x00000004;
}



「该帖子被 unconscious 在 2014-02-19 11:34:29 编辑过」

^_^
等级:论坛新手 参考IP地址:*.*.*.*
2014/2/19 10:24:00
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
3信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
1. 你进入中断后PPI和DMA已经关闭了,所以每次只能采第一行数据。PPI每次使能,是从一帧的开始 开始采数据的,进入中断后,清除DMA中断标志即可,不能关闭DMA和PPI,你看看我让你下载的那个代码是如何处理的。
2.  *pSIC_IAR4 = 0xfffffff4; 对应的中断等级是IVG11,你是用的是IVG12,应该改为5

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/2/20 0:06:32
unconscious(论坛新手)
unconscious
头衔:社区公民
帮派:无帮无派
帖数:67
金钱:746
积分:86
注册时间:2013/8/2
4信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

int count = 0;
int i = 0,j = 0;

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR)
{    
        *pDMA0_IRQ_STATUS = 0x1;     //清DMA0中断标志
        
        count++;
        if(count == 600)    //采到第600行时置高PF13
        {
            *pPORTFIO_DIR      |= PF13;
            *pPORTFIO          |= PF13;
        }        
        for(i = 0; i < 640; i++)   //将采到的每一行数据放入到图像缓冲区中
        {
            databuf[j] = buffer[i];
            j++;
        }

         buffer[640] = 0;   //采完一行将缓冲区清零
      
        Video_Frame_Capture();
        *pDMA0_START_ADDR = buffer;    
        CMOS_PPI_Enable();    
      
         if(count == 959)     //当采到第960行时表示一帧图像采集结束   将PF13置低
        {
            count = 0;        
            captureFinished = 1;       //采集一帧完成标志
            
            *pPORTFIO          &= ~PF13;  

            DEBUG_STATEMENT( "Success Capture One Frame:  640 * 960\r\n");      
        }        
}

这是我按行采集时中断里的设置,有两个问题:

1、 if(count == 959)   我把这个值换成964 965等都可以,之前的PPI设置 *pPPI_FRAME   = 960; *pPPI_COUNT   = 1279;不是表示采集640*960,吗,为什么会大于960呢? 这里应该怎么设置?  

2、打印出的图片不对,每一行的数据都是一样的。好像只采到了某一行的数据。

麻烦andy帮忙看下哪里有问题,谢谢。。我弄了好久了。。麻烦了


^_^
等级:论坛新手 参考IP地址:*.*.*.*
2014/2/20 15:30:53
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
5信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
你仔细看一下我给你的代码,那个是可以直接运行的。
在一帧图像没有采集完之前,不允许对PPI和DMA做任何的初始化,否则,你只能采到第一行。你的DMA配置也只是配置了采一行。
如果你弄个仿真器的话,调试会方便很多。仅仅靠打印看数据,太累

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/2/21 0:54:31
尊贵身份标志
OpenADSP(管理员)
OpenADSP
头衔:社区公民
帮派:无帮无派
帖数:5195
金钱:34806
积分:6378
注册时间:2011/6/7
6信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
一个仿真器也就1200而已,项目耽误几天,员工工资就比这个钱多了去了。。。

我是OP...
等级:管理员 参考IP地址:*.*.*.*
2014/2/21 8:52:27
unconscious(论坛新手)
unconscious
头衔:社区公民
帮派:无帮无派
帖数:67
金钱:746
积分:86
注册时间:2013/8/2
7信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

现在还在评估,以后不一定会用这个板子,我基本上要用的调完了,现在调一个视频和激光同步的功能,很简单,但是我没有基础,不会,这块也不是项目不是很急。我也在做其他的事情。另一个同事用的其他板子评估,后面如果确定用再买。


^_^
等级:论坛新手 参考IP地址:*.*.*.*
2014/2/21 14:51:07
unconscious(论坛新手)
unconscious
头衔:社区公民
帮派:无帮无派
帖数:67
金钱:746
积分:86
注册时间:2013/8/2
8信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
经过两天的调试,有些问题可以实践出来了,但是理论上还是不太懂
1、andy之前说用TIMER定时器产生和PPI同步的信号,PPI的速度会不匹配。这个具体还不是很理解。

2、根据那个pingpang例程我改为了按线采,即将*pDMA0_Y_COUNT设为1,程序流程和该例程一样,但是还是只能采到一行的数据。

这种采集方法,这样理解对吗 :每一次从一行的开始处采集,该行采集完后,从下一行的开始处进行采集……一帧图像采集完成之后,再初始化并使能PPI,下一帧图像又从第一行开始采集。  

采集时需要将每一行buffer数据放到另一个图像buffer里,没有其他的处理。按行采的话是必须要用乒乓buffer吗?

必须要买仿真器了,这样真的太麻烦。麻烦andy解惑,谢谢。


「该帖子被 unconscious 在 2014-02-26 15:21:07 编辑过」

^_^
等级:论坛新手 参考IP地址:*.*.*.*
2014/2/26 9:17:37
尊贵身份标志
andy(论坛版主)
andy
头衔:社区公民
帮派:无帮无派
帖数:2287
金钱:11132
积分:2263
注册时间:2011/6/8
9信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
1. 之前你提到用定时器定时来计算当前PPI刷了多少条线,由于定时器和PPI是相互独立的,PPI开始采集数据是通过检测场同步信号开始的,所以你的定时器永远不可能定时到 PPI开始采i一个数据时启动,所以你永远不能精确定时采到你需要的行数,而且一旦进入定时器,PPI会停止工作,你后面的图像就会丢掉。
2. 给你的代码是在BF533开发板上经过验证的,摄像头用的好像不是OV9650,你只需给代码移植到BF518上,把摄像头驱动那块换掉,摄像头帧率改慢一点,用5帧以下,运行看看是否能采集到完整的图像。

这家伙很懒,什么也没有留下!
等级:论坛版主 参考IP地址:*.*.*.*
2014/2/26 17:58:51
11
1
1/2
Powered by OpenADSP Copyright © 2010 www.Openadsp.com. All rights reserved.159241 Call, 1 Queries, Processed in 0.015625 second(s),