[资料分享] DM642图像处理程序的主要结构

Aguilera   2017-9-24 18:37 楼主

直接从图像处理这块进行学习不是特别适应,以前做单片机时由于单片机的片内资源不是特别多,所以对片内资源掌握的比较好,相关的寄存器配置等都是从底层自己配置,现在学习DSP反而不知道怎样从硬件入手了,只能从顶层向底层倒着来摸索。这是一个简单的图像处理程序,仔细看看,很多地方不懂,只能先了解大概,很多地方可能还没有认识到,在以后的学习中再接着摸索。在源程序的基础之上我加了一些注释,程序如下:

/********************************************************************/
/*                        灰度图
运行结果:在屏幕之中画出一块区域显示灰度图像                                    */
/********************************************************************/
/* 关于csl:
1,用于配置、控制和管理DSP片上外设
2,已为C6000和C5000系列DSP设计了各自的CSL库
3,CSL库函数大多数是用C语言编写的,并已对代码的大小和速度进行了优化
4,CSL库是可裁剪的:即只有被使用的CSL模块才会包含进应用程序中
5,CSL库是可扩展的:每个片上外设的API相互独立,增加新的API,对其他片上外设没有影响 */
#include                  /* 总库,提供外设接口和基本配置 */
// 具体的接口定义,头文件中定义了接口的地址等
#include            /* emifa是一种64位的外部接口,可连接64/32/16/8bit的器件 */
#include          /* 一种两线式串行总线 */
#include     /* 也是一种通用的输入输出接口 */
#include     /* 一些基本中断的定义 */
#include
#include
#include "iic.h"
#include "vportcap.h"
#include "vportdis.h"
#include "sa7121h.h"    /* SAA7121可以将数字信号编程模拟信号和下面的编码芯片一样都采用iic总线 */
#include "TVP51xx.h"    /* 视频编码芯片,将模拟信号进行数字化,这是其进行配置的头文件 */
/*SEEDDM642的emifa的设置结构*/
EMIFA_Config Seeddm642ConfigA ={
    0x00052078,/*gblctl EMIFA(B)global control register value */
         /*将CLK6、4、1使能;将MRMODE置1;使能EK2EN,EK2RATE*/
    0xffffffd3,/*cectl0 CE0 space control register value*/
         /*将CE0空间设为SDRAM*/
    0x73a28e01,/*cectl1 CE1 space control register value*/
         /*Read hold: 1 clock;
           MTYPE : 0000,选择8位的异步接口
           Read strobe :001110;14个clock宽度
           TA:2 clock; Read setup 2 clock;
           Write hold :2 clock; Write strobe: 14 clock
           Write setup :7 clock
           --      ---------------
            \   14c   /1c
            \----------------/ */
    0x22a28a22, /*cectl2 CE2 space control register value*/
       0x22a28a42, /*cectl3 CE3 space control register value*/
    0x57115000, /*sdctl SDRAM control register value*/
    0x0000081b, /*sdtim SDRAM timing register value*/
    0x001faf4d, /*sdext SDRAM extension register value*/
    0x00000002, /*cesec0 CE0 space secondary control register value*/
    0x00000002, /*cesec1 CE1 space secondary control register value*/
    0x00000002, /*cesec2 CE2 space secondary control register value*/
    0x00000073 /*cesec3 CE3 space secondary control register value*/
};
/*SEEDDM642的IIC的设置结构*/
I2C_Config SEEDDM642IIC_Config = {
    0, /* master mode, i2coar;采用主模式   */
    0, /* no interrupt, i2cimr;只写,不读,采用无中断方式*/
    (20-5), /* scl low time, i2cclkl; */
    (20-5), /* scl high time,i2cclkh; */
    1, /* configure later, i2ccnt;*/
    0, /* configure later, i2csar;*/
    0x4ea0, /* master tx mode,     */
            /* i2c runs free,      */
            /* 8-bit data + NACK   */
            /* no repeat mode      */
    (75-1), /* 4MHz clock, i2cpsc */
};
CHIP_Config SEEDDM642percfg = {
CHIP_VP2+\
CHIP_VP1+\
CHIP_VP0+\
CHIP_I2C
};
I2C_Handle hSeeddm642i2c;
int portNumber;
extern SA7121H_ConfParams sa7121hPAL[45];
extern SA7121H_ConfParams sa7121hNTSC[45];
Uint8 vFromat = 0;
Uint8 misc_ctrl = 0x6D;
Uint8 output_format = 0x47;
// 地址为0 for cvbs port1,选择复合信号做为输入
Uint8 input_sel = 0x00;
/*地址为0xf,将Pin27设置成为CAPEN功能*/
Uint8 pin_cfg = 0x02;
/*地址为1B*/
Uint8 chro_ctrl_2 = 0x14;
/*图像句柄的声明*/
VP_Handle vpHchannel0;
VP_Handle vpHchannel1;
VP_Handle vpHchannel2;
/*确定图像的参数*/
int numPixels = 720;//每行720个像素
int numLines = 576;//每帧576行(PAL)

/*确定处理的范围*/
/*A             */
/*              */
/*             D*/
int intAPixels = 190;
int intALines = 59;
int intDPixels = 530;
int intDLines = 229;
/******************************/
/*****画矩形边框函数的声明*****/
void drawRectangle();
/*消去彩色*/
void removeColor();
/*采集与显示缓冲区的首址*/
Uint32 capYbuffer = 0x80000000;
Uint32 capCbbuffer = 0x800675c0;
Uint32 capCrbuffer = 0x8009b0a0;
Uint32 disYbuffer = 0x80100000;
Uint32 disCbbuffer = 0x801675c0;
Uint32 disCrbuffer = 0x8019b0a0;
Uint32 tempYbuffer = 0x80200000;   //临时
Uint32 tempCbbuffer = 0x80300000;   //临时
Uint32 tempCrbuffer = 0x80400000;   //临时
/*图像格式标志*/
Uint8 NTSCorPAL = 0;
extern far void vectors();
extern volatile Uint32 capNewFrame;
extern volatile Uint32 disNewFrame;
/*此程序可将四个采集口的数据经过Video Port0送出*/
void main()
{
Uint8 addrI2C;
int i;

/*-------------------------------------------------------*/
/* perform all initializations                           */
/*-------------------------------------------------------*/
/*Initialise CSL,初始化CSL库*/
CSL_init();
CHIP_config(&SEEDDM642percfg);
/*----------------------------------------------------------*/
/*EMIFA的初始化,将CE0设为SDRAM空间,CE1设为异步空间
注,DM642支持的是EMIFA,而非EMIF*/
EMIFA_config(&Seeddm642ConfigA);
/*----------------------------------------------------------*/
/*中断向量表的初始化*/
//Point to the IRQ vector table
    IRQ_setVecs(vectors);
    IRQ_nmiEnable();
    IRQ_globalEnable();
    IRQ_map(IRQ_EVT_VINT1, 11);
    IRQ_map(IRQ_EVT_VINT0, 12);
    IRQ_reset(IRQ_EVT_VINT1);
    IRQ_reset(IRQ_EVT_VINT1);
    /*打开一个数据拷贝的数据通路*/
    DAT_open(DAT_CHAANY, DAT_PRI_LOW, DAT_OPEN_2D);
/*----------------------------------------------------------*/
/*进行IIC的初始化*/
hSeeddm642i2c = I2C_open(I2C_PORT0,I2C_OPEN_RESET);
I2C_config(hSeeddm642i2c,&SEEDDM642IIC_Config);
/*----------------------------------------------------------*/
/*进行TVP5150pbs的初始化*/
/*选择TVP5150,设置第三通路*/
GPIO_RSET(GPGC,0x0);/*将GPIO0不做为GPINT使用*/
GPIO_RSET(GPDIR,0x1);/*将GPIO0做为输出*/
GPIO_RSET(GPVAL,0x0);/*GPIO0输出为高,选择IIC1总线,配置
         第二路,即为U21*/
addrI2C = 0xBA >>1;
    _IIC_write(hSeeddm642i2c, addrI2C,0x00, input_sel);
    _IIC_write(hSeeddm642i2c, addrI2C,0x03, misc_ctrl);
    _IIC_write(hSeeddm642i2c, addrI2C,0x0D, output_format);
    _IIC_write(hSeeddm642i2c, addrI2C,0x0F, pin_cfg);
    _IIC_write(hSeeddm642i2c, addrI2C,0x1B, chro_ctrl_2);
    /*回读当前摄像设备的格式*/
    _IIC_read(hSeeddm642i2c, addrI2C,0x8c, &vFromat);
    vFromat = vFromat & 0xff;
switch (vFromat)
{
   case TVP51XX_NTSCM:
   case TVP51XX_NTSC443:
    NTSCorPAL = 1;/*系统为NTSC的模式*/
    break;
   case TVP51XX_PALBGHIN:
   case TVP51XX_PALM:
    NTSCorPAL = 0;/*系统为PAL的模式*/
    break;
   default:
    NTSCorPAL = 2;/*系统为不支持的模式*/
    break;
}
if(NTSCorPAL ==2)
{
   /*系统不支持的模式,重新配置*/
   for(;;)
   {}
}     
/*----------------------------------------------------------*/
/*进行SAA7121H的初始化*/
GPIO_RSET(GPVAL,0x0);/*GPIO0输出为低,选择IIC1总线,配置图像输出*/        
addrI2C = 0xB8 >>1; /*选择第0路的I2C的地址*/
/*将第0路的视频输入口的数据口设为高阻状态,
   使能SCLK,将第27脚设为输入*/
_IIC_write(hSeeddm642i2c, addrI2C,0x03, 0x1);
/*配置SAA7121H*/
GPIO_RSET(GPVAL,0x1);/*GPIO0输出为低,选择IIC1总线,配置图像输出*/
/*初始化Video Port0*/
/*将Vedio Port1设为encoder输出*/
portNumber = 0;
vpHchannel0 = bt656_8bit_ncfd(portNumber);
addrI2C = 0x88 >>1;           
for(i =0; i<43; i++)
{
   if(NTSCorPAL == 1)
   {
    _IIC_write(hSeeddm642i2c,
        addrI2C,
        (sa7121hNTSC.regsubaddr),
        (sa7121hNTSC.regvule));
   }
   else
   {
    _IIC_write(hSeeddm642i2c,
        addrI2C,
        (sa7121hPAL.regsubaddr),
        (sa7121hPAL.regvule));
   }  
}

/*----------------------------------------------------------*/
/*初始化Video Port1*/
/*将Vedio Port1设为采集输入*/
portNumber = 1;
vpHchannel1 = bt656_8bit_ncfc(portNumber);
bt656_capture_start(vpHchannel1);
/*等待第一帧数据采集完成*/
while(capNewFrame == 0){}
/*采集完成,将数据存入显示缓冲区,并清采集完成的标志*/
capNewFrame =0;
for(i=0;i {
   /*传送临时Y缓冲区*/
   DAT_copy((void *)(capYbuffer + i * numPixels),
              (void *)(tempYbuffer + i * numPixels),
              numPixels);
     /*传送临时Cb缓冲区*/
     DAT_copy((void *)(capCbbuffer + i * (numPixels >> 1)),
              (void *)(tempCbbuffer + i * (numPixels >> 1)),
              numPixels>>1);
   /*传送临时Cr缓冲区*/
     DAT_copy((void *)(capCrbuffer + i * (numPixels >> 1)),
              (void *)(tempCrbuffer + i * (numPixels >> 1)),
              numPixels>>1);     
}
/* 画边框,消去彩色灯操作都需要在缓冲区中进行 */
    /*画边框*/   
    drawRectangle();
   
/*消去彩色*/
    removeColor();
/* 再将缓冲区的内容送入显示区 */
    for(i=0;i {
   /*传送Y缓冲区*/
     DAT_copy((void *)(tempYbuffer + i * numPixels),
              (void *)(disYbuffer + i * numPixels),
              numPixels);
     /*传送Cb缓冲区*/
     DAT_copy((void *)(tempCbbuffer + i * (numPixels >> 1)),
              (void *)(disCbbuffer + i * (numPixels >> 1)),
              numPixels>>1);
   /*传送Cr缓冲区*/
     DAT_copy((void *)(tempCrbuffer + i * (numPixels >> 1)),
              (void *)(disCrbuffer + i * (numPixels >> 1)),
              numPixels>>1);   
}

   
/*启动显示模块*/
bt656_display_start(vpHchannel0);
/*建立一个死循环实时采集和播放*/
for(;;)
{
   /*当采集区的数据已经采集好,而显示缓冲区的数据已空*/
   if((capNewFrame == 1)&&(disNewFrame == 1))
   {
    /*将数据装入显示缓冲区,并清采集完成的标志*/
    capNewFrame =0;
    disNewFrame =0;
    for(i=0;i     {
     /*传送临时Y缓冲区*/
     DAT_copy((void *)(capYbuffer + i * numPixels),
                (void *)(tempYbuffer + i * numPixels),
                numPixels);
       /*传送临时Cb缓冲区*/
       DAT_copy((void *)(capCbbuffer + i * (numPixels >> 1)),
                (void *)(tempCbbuffer + i * (numPixels >> 1)),
                numPixels>>1);
     /*传送临时Cr缓冲区*/
       DAT_copy((void *)(capCrbuffer + i * (numPixels >> 1)),
                (void *)(tempCrbuffer + i * (numPixels >> 1)),
                numPixels>>1);      
    }
        
      /*画边框*/   
      drawRectangle();   
     
    /*消去彩色*/
            removeColor();
   
         for(i=0;i     {
     /*传送Y缓冲区*/
       DAT_copy((void *)(tempYbuffer + i * numPixels),
                (void *)(disYbuffer + i * numPixels),
                numPixels);
       /*传送Cb缓冲区*/
       DAT_copy((void *)(tempCbbuffer + i * (numPixels >> 1)),
                (void *)(disCbbuffer + i * (numPixels >> 1)),
                numPixels>>1);
     /*传送Cr缓冲区*/
       DAT_copy((void *)(tempCrbuffer + i * (numPixels >> 1)),
                (void *)(disCrbuffer + i * (numPixels >> 1)),
                numPixels>>1);   
    }   
   
   }
  
}

for(;;)
{}
/*----------------------------------------------------------*/
/*采集与回放*/
  
}

/*画矩形边框函数的定义*/
void drawRectangle()
{
    int i,j;
    /*画上边*/
    //奇数行
    for(i=intALines-4;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

//偶数行
for(i=numLines/2+intALines-4;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

/*画下边*/
//奇数行
    for(i=intDLines;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

//偶数行
for(i=numLines/2+intDLines;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

/*画左边*/
//奇数行
    for(i=intALines;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

//偶数行
for(i=numLines/2+intALines;i {
     for(j=intAPixels-6;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}


/*画右边*/
//奇数行
    for(i=intALines;i {
     for(j=intDPixels;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}

//偶数行
    for(i=numLines/2+intALines;i {
     for(j=intDPixels;j      {
     *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00;
     }
}
}
/*消去彩色*/
void removeColor()
{
int i,j;
//方框内奇数行
for(i=intALines;i {
     for(j=intAPixels/2;j      {
            *(Uint8 *)(tempCbbuffer + i * (numPixels >> 1) + j) = 0x80;
            *(Uint8 *)(tempCrbuffer + i * (numPixels >> 1) + j) = 0x80;
     }   
}

//方框内偶数行
for(i=numLines/2+intALines;i {
     for(j=intAPixels/2;j      {  
            *(Uint8 *)(tempCbbuffer + i * (numPixels >> 1) + j) = 0x80;
            *(Uint8 *)(tempCrbuffer + i * (numPixels >> 1) + j) = 0x80;
     }   
}  


回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复