DM642图像处理程序的主要结构
直接从图像处理这块进行学习不是特别适应,以前做单片机时由于单片机的片内资源不是特别多,所以对片内资源掌握的比较好,相关的寄存器配置等都是从底层自己配置,现在学习DSP反而不知道怎样从硬件入手了,只能从顶层向底层倒着来摸索。这是一个简单的图像处理程序,仔细看看,很多地方不懂,只能先了解大概,很多地方可能还没有认识到,在以后的学习中再接着摸索。在源程序的基础之上我加了一些注释,程序如下:
1 /********************************************************************/ 2 /* 灰度图 3 运行结果:在屏幕之中画出一块区域显示灰度图像 */ 4 /********************************************************************/ 5 /* 关于csl: 6 1,用于配置、控制和管理DSP片上外设 7 2,已为C6000和C5000系列DSP设计了各自的CSL库 8 3,CSL库函数大多数是用C语言编写的,并已对代码的大小和速度进行了优化 9 4,CSL库是可裁剪的:即只有被使用的CSL模块才会包含进应用程序中 10 5,CSL库是可扩展的:每个片上外设的API相互独立,增加新的API,对其他片上外设没有影响 */ 11 #include <csl.h> /* 总库,提供外设接口和基本配置 */ 12 // 具体的接口定义,头文件中定义了接口的地址等 13 #include <csl_emifa.h> /* emifa是一种64位的外部接口,可连接64/32/16/8bit的器件 */ 14 #include <csl_i2c.h> /* 一种两线式串行总线 */ 15 #include <csl_gpio.h> /* 也是一种通用的输入输出接口 */ 16 #include <csl_irq.h> /* 一些基本中断的定义 */ 17 #include <csl_chip.h> 18 #include <csl_dat.h> 19 #include "iic.h" 20 #include "vportcap.h" 21 #include "vportdis.h" 22 #include "sa7121h.h" /* SAA7121可以将数字信号编程模拟信号和下面的编码芯片一样都采用iic总线 */ 23 #include "TVP51xx.h" /* 视频编码芯片,将模拟信号进行数字化,这是其进行配置的头文件 */ 24 /*SEEDDM642的emifa的设置结构*/ 25 EMIFA_Config Seeddm642ConfigA ={ 26 0x00052078,/*gblctl EMIFA(B)global control register value */ 27 /*将CLK6、4、1使能;将MRMODE置1;使能EK2EN,EK2RATE*/ 28 0xffffffd3,/*cectl0 CE0 space control register value*/ 29 /*将CE0空间设为SDRAM*/ 30 0x73a28e01,/*cectl1 CE1 space control register value*/ 31 /*Read hold: 1 clock; 32 MTYPE : 0000,选择8位的异步接口 33 Read strobe :001110;14个clock宽度 34 TA:2 clock; Read setup 2 clock; 35 Write hold :2 clock; Write strobe: 14 clock 36 Write setup :7 clock 37 -- --------------- 38 / 14c /1c 39 /----------------/ */ 40 0x22a28a22, /*cectl2 CE2 space control register value*/ 41 0x22a28a42, /*cectl3 CE3 space control register value*/ 42 0x57115000, /*sdctl SDRAM control register value*/ 43 0x0000081b, /*sdtim SDRAM timing register value*/ 44 0x001faf4d, /*sdext SDRAM extension register value*/ 45 0x00000002, /*cesec0 CE0 space secondary control register value*/ 46 0x00000002, /*cesec1 CE1 space secondary control register value*/ 47 0x00000002, /*cesec2 CE2 space secondary control register value*/ 48 0x00000073 /*cesec3 CE3 space secondary control register value*/ 49 }; 50 /*SEEDDM642的IIC的设置结构*/ 51 I2C_Config SEEDDM642IIC_Config = { 52 0, /* master mode, i2coar;采用主模式 */ 53 0, /* no interrupt, i2cimr;只写,不读,采用无中断方式*/ 54 (20-5), /* scl low time, i2cclkl; */ 55 (20-5), /* scl high time,i2cclkh; */ 56 1, /* configure later, i2ccnt;*/ 57 0, /* configure later, i2csar;*/ 58 0x4ea0, /* master tx mode, */ 59 /* i2c runs free, */ 60 /* 8-bit data + NACK */ 61 /* no repeat mode */ 62 (75-1), /* 4MHz clock, i2cpsc */ 63 }; 64 CHIP_Config SEEDDM642percfg = { 65 CHIP_VP2+/ 66 CHIP_VP1+/ 67 CHIP_VP0+/ 68 CHIP_I2C 69 }; 70 I2C_Handle hSeeddm642i2c; 71 int portNumber; 72 extern SA7121H_ConfParams sa7121hPAL[45]; 73 extern SA7121H_ConfParams sa7121hNTSC[45]; 74 Uint8 vFromat = 0; 75 Uint8 misc_ctrl = 0x6D; 76 Uint8 output_format = 0x47; 77 // 地址为0 for cvbs port1,选择复合信号做为输入 78 Uint8 input_sel = 0x00; 79 /*地址为0xf,将Pin27设置成为CAPEN功能*/ 80 Uint8 pin_cfg = 0x02; 81 /*地址为1B*/ 82 Uint8 chro_ctrl_2 = 0x14; 83 /*图像句柄的声明*/ 84 VP_Handle vpHchannel0; 85 VP_Handle vpHchannel1; 86 VP_Handle vpHchannel2; 87 /*确定图像的参数*/ 88 int numPixels = 720;//每行720个像素 89 int numLines = 576;//每帧576行(PAL) 90 91 /*确定处理的范围*/ 92 /*A */ 93 /* */ 94 /* D*/ 95 int intAPixels = 190; 96 int intALines = 59; 97 int intDPixels = 530; 98 int intDLines = 229; 99 /******************************/ 100 /*****画矩形边框函数的声明*****/ 101 void drawRectangle(); 102 /*消去彩色*/ 103 void removeColor(); 104 /*采集与显示缓冲区的首址*/ 105 Uint32 capYbuffer = 0x80000000; 106 Uint32 capCbbuffer = 0x800675c0; 107 Uint32 capCrbuffer = 0x8009b0a0; 108 Uint32 disYbuffer = 0x80100000; 109 Uint32 disCbbuffer = 0x801675c0; 110 Uint32 disCrbuffer = 0x8019b0a0; 111 Uint32 tempYbuffer = 0x80200000; //临时 112 Uint32 tempCbbuffer = 0x80300000; //临时 113 Uint32 tempCrbuffer = 0x80400000; //临时 114 /*图像格式标志*/ 115 Uint8 NTSCorPAL = 0; 116 extern far void vectors(); 117 extern volatile Uint32 capNewFrame; 118 extern volatile Uint32 disNewFrame; 119 /*此程序可将四个采集口的数据经过Video Port0送出*/ 120 void main() 121 { 122 Uint8 addrI2C; 123 int i; 124 125 /*-------------------------------------------------------*/ 126 /* perform all initializations */ 127 /*-------------------------------------------------------*/ 128 /*Initialise CSL,初始化CSL库*/ 129 CSL_init(); 130 CHIP_config(&SEEDDM642percfg); 131 /*----------------------------------------------------------*/ 132 /*EMIFA的初始化,将CE0设为SDRAM空间,CE1设为异步空间 133 注,DM642支持的是EMIFA,而非EMIF*/ 134 EMIFA_config(&Seeddm642ConfigA); 135 /*----------------------------------------------------------*/ 136 /*中断向量表的初始化*/ 137 //Point to the IRQ vector table 138 IRQ_setVecs(vectors); 139 IRQ_nmiEnable(); 140 IRQ_globalEnable(); 141 IRQ_map(IRQ_EVT_VINT1, 11); 142 IRQ_map(IRQ_EVT_VINT0, 12); 143 IRQ_reset(IRQ_EVT_VINT1); 144 IRQ_reset(IRQ_EVT_VINT1); 145 /*打开一个数据拷贝的数据通路*/ 146 DAT_open(DAT_CHAANY, DAT_PRI_LOW, DAT_OPEN_2D); 147 /*----------------------------------------------------------*/ 148 /*进行IIC的初始化*/ 149 hSeeddm642i2c = I2C_open(I2C_PORT0,I2C_OPEN_RESET); 150 I2C_config(hSeeddm642i2c,&SEEDDM642IIC_Config); 151 /*----------------------------------------------------------*/ 152 /*进行TVP5150pbs的初始化*/ 153 /*选择TVP5150,设置第三通路*/ 154 GPIO_RSET(GPGC,0x0);/*将GPIO0不做为GPINT使用*/ 155 GPIO_RSET(GPDIR,0x1);/*将GPIO0做为输出*/ 156 GPIO_RSET(GPVAL,0x0);/*GPIO0输出为高,选择IIC1总线,配置 157 第二路,即为U21*/ 158 addrI2C = 0xBA >>1; 159 _IIC_write(hSeeddm642i2c, addrI2C,0x00, input_sel); 160 _IIC_write(hSeeddm642i2c, addrI2C,0x03, misc_ctrl); 161 _IIC_write(hSeeddm642i2c, addrI2C,0x0D, output_format); 162 _IIC_write(hSeeddm642i2c, addrI2C,0x0F, pin_cfg); 163 _IIC_write(hSeeddm642i2c, addrI2C,0x1B, chro_ctrl_2); 164 /*回读当前摄像设备的格式*/ 165 _IIC_read(hSeeddm642i2c, addrI2C,0x8c, &vFromat); 166 vFromat = vFromat & 0xff; 167 switch (vFromat) 168 { 169 case TVP51XX_NTSCM: 170 case TVP51XX_NTSC443: 171 NTSCorPAL = 1;/*系统为NTSC的模式*/ 172 break; 173 case TVP51XX_PALBGHIN: 174 case TVP51XX_PALM: 175 NTSCorPAL = 0;/*系统为PAL的模式*/ 176 break; 177 default: 178 NTSCorPAL = 2;/*系统为不支持的模式*/ 179 break; 180 } 181 if(NTSCorPAL ==2) 182 { 183 /*系统不支持的模式,重新配置*/ 184 for(;;) 185 {} 186 } 187 /*----------------------------------------------------------*/ 188 /*进行SAA7121H的初始化*/ 189 GPIO_RSET(GPVAL,0x0);/*GPIO0输出为低,选择IIC1总线,配置图像输出*/ 190 addrI2C = 0xB8 >>1; /*选择第0路的I2C的地址*/ 191 /*将第0路的视频输入口的数据口设为高阻状态, 192 使能SCLK,将第27脚设为输入*/ 193 _IIC_write(hSeeddm642i2c, addrI2C,0x03, 0x1); 194 /*配置SAA7121H*/ 195 GPIO_RSET(GPVAL,0x1);/*GPIO0输出为低,选择IIC1总线,配置图像输出*/ 196 /*初始化Video Port0*/ 197 /*将Vedio Port1设为encoder输出*/ 198 portNumber = 0; 199 vpHchannel0 = bt656_8bit_ncfd(portNumber); 200 addrI2C = 0x88 >>1; 201 for(i =0; i<43; i++) 202 { 203 if(NTSCorPAL == 1) 204 { 205 _IIC_write(hSeeddm642i2c, 206 addrI2C, 207 (sa7121hNTSC[i].regsubaddr), 208 (sa7121hNTSC[i].regvule)); 209 } 210 else 211 { 212 _IIC_write(hSeeddm642i2c, 213 addrI2C, 214 (sa7121hPAL[i].regsubaddr), 215 (sa7121hPAL[i].regvule)); 216 } 217 } 218 219 /*----------------------------------------------------------*/ 220 /*初始化Video Port1*/ 221 /*将Vedio Port1设为采集输入*/ 222 portNumber = 1; 223 vpHchannel1 = bt656_8bit_ncfc(portNumber); 224 bt656_capture_start(vpHchannel1); 225 /*等待第一帧数据采集完成*/ 226 while(capNewFrame == 0){} 227 /*采集完成,将数据存入显示缓冲区,并清采集完成的标志*/ 228 capNewFrame =0; 229 for(i=0;i<numLines;i++) 230 { 231 /*传送临时Y缓冲区*/ 232 DAT_copy((void *)(capYbuffer + i * numPixels), 233 (void *)(tempYbuffer + i * numPixels), 234 numPixels); 235 /*传送临时Cb缓冲区*/ 236 DAT_copy((void *)(capCbbuffer + i * (numPixels >> 1)), 237 (void *)(tempCbbuffer + i * (numPixels >> 1)), 238 numPixels>>1); 239 /*传送临时Cr缓冲区*/ 240 DAT_copy((void *)(capCrbuffer + i * (numPixels >> 1)), 241 (void *)(tempCrbuffer + i * (numPixels >> 1)), 242 numPixels>>1); 243 } 244 /* 画边框,消去彩色灯操作都需要在缓冲区中进行 */ 245 /*画边框*/ 246 drawRectangle(); 247 248 /*消去彩色*/ 249 removeColor(); 250 /* 再将缓冲区的内容送入显示区 */ 251 for(i=0;i<numLines;i++) 252 { 253 /*传送Y缓冲区*/ 254 DAT_copy((void *)(tempYbuffer + i * numPixels), 255 (void *)(disYbuffer + i * numPixels), 256 numPixels); 257 /*传送Cb缓冲区*/ 258 DAT_copy((void *)(tempCbbuffer + i * (numPixels >> 1)), 259 (void *)(disCbbuffer + i * (numPixels >> 1)), 260 numPixels>>1); 261 /*传送Cr缓冲区*/ 262 DAT_copy((void *)(tempCrbuffer + i * (numPixels >> 1)), 263 (void *)(disCrbuffer + i * (numPixels >> 1)), 264 numPixels>>1); 265 } 266 267 268 /*启动显示模块*/ 269 bt656_display_start(vpHchannel0); 270 /*建立一个死循环实时采集和播放*/ 271 for(;;) 272 { 273 /*当采集区的数据已经采集好,而显示缓冲区的数据已空*/ 274 if((capNewFrame == 1)&&(disNewFrame == 1)) 275 { 276 /*将数据装入显示缓冲区,并清采集完成的标志*/ 277 capNewFrame =0; 278 disNewFrame =0; 279 for(i=0;i<numLines;i++) 280 { 281 /*传送临时Y缓冲区*/ 282 DAT_copy((void *)(capYbuffer + i * numPixels), 283 (void *)(tempYbuffer + i * numPixels), 284 numPixels); 285 /*传送临时Cb缓冲区*/ 286 DAT_copy((void *)(capCbbuffer + i * (numPixels >> 1)), 287 (void *)(tempCbbuffer + i * (numPixels >> 1)), 288 numPixels>>1); 289 /*传送临时Cr缓冲区*/ 290 DAT_copy((void *)(capCrbuffer + i * (numPixels >> 1)), 291 (void *)(tempCrbuffer + i * (numPixels >> 1)), 292 numPixels>>1); 293 } 294 295 /*画边框*/ 296 drawRectangle(); 297 298 /*消去彩色*/ 299 removeColor(); 300 301 for(i=0;i<numLines;i++) 302 { 303 /*传送Y缓冲区*/ 304 DAT_copy((void *)(tempYbuffer + i * numPixels), 305 (void *)(disYbuffer + i * numPixels), 306 numPixels); 307 /*传送Cb缓冲区*/ 308 DAT_copy((void *)(tempCbbuffer + i * (numPixels >> 1)), 309 (void *)(disCbbuffer + i * (numPixels >> 1)), 310 numPixels>>1); 311 /*传送Cr缓冲区*/ 312 DAT_copy((void *)(tempCrbuffer + i * (numPixels >> 1)), 313 (void *)(disCrbuffer + i * (numPixels >> 1)), 314 numPixels>>1); 315 } 316 317 } 318 319 } 320 321 for(;;) 322 {} 323 /*----------------------------------------------------------*/ 324 /*采集与回放*/ 325 326 } 327 328 /*画矩形边框函数的定义*/ 329 void drawRectangle() 330 { 331 int i,j; 332 /*画上边*/ 333 //奇数行 334 for(i=intALines-4;i<intALines;i++) 335 { 336 for(j=intAPixels-6;j<intDPixels+6;j++) 337 { 338 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 339 } 340 } 341 342 //偶数行 343 for(i=numLines/2+intALines-4;i<numLines/2+intALines;i++) 344 { 345 for(j=intAPixels-6;j<intDPixels+6;j++) 346 { 347 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 348 } 349 } 350 351 /*画下边*/ 352 //奇数行 353 for(i=intDLines;i<intDLines+4;i++) 354 { 355 for(j=intAPixels-6;j<intDPixels+6;j++) 356 { 357 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 358 } 359 } 360 361 //偶数行 362 for(i=numLines/2+intDLines;i<numLines/2+intDLines+4;i++) 363 { 364 for(j=intAPixels-6;j<intDPixels+6;j++) 365 { 366 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 367 } 368 } 369 370 /*画左边*/ 371 //奇数行 372 for(i=intALines;i<intDLines;i++) 373 { 374 for(j=intAPixels-6;j<intAPixels;j++) 375 { 376 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 377 } 378 } 379 380 //偶数行 381 for(i=numLines/2+intALines;i<numLines/2+intDLines;i++) 382 { 383 for(j=intAPixels-6;j<intAPixels;j++) 384 { 385 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 386 } 387 } 388 389 390 /*画右边*/ 391 //奇数行 392 for(i=intALines;i<intDLines;i++) 393 { 394 for(j=intDPixels;j<intDPixels+6;j++) 395 { 396 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 397 } 398 } 399 400 //偶数行 401 for(i=numLines/2+intALines;i<numLines/2+intDLines;i++) 402 { 403 for(j=intDPixels;j<intDPixels+6;j++) 404 { 405 *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0x00; 406 } 407 } 408 } 409 /*消去彩色*/ 410 void removeColor() 411 { 412 int i,j; 413 //方框内奇数行 414 for(i=intALines;i<intDLines;i++) 415 { 416 for(j=intAPixels/2;j<intDPixels/2;j++) 417 { 418 *(Uint8 *)(tempCbbuffer + i * (numPixels >> 1) + j) = 0x80; 419 *(Uint8 *)(tempCrbuffer + i * (numPixels >> 1) + j) = 0x80; 420 } 421 } 422 423 //方框内偶数行 424 for(i=numLines/2+intALines;i<numLines/2+intDLines;i++) 425 { 426 for(j=intAPixels/2;j<intDPixels/2;j++) 427 { 428 *(Uint8 *)(tempCbbuffer + i * (numPixels >> 1) + j) = 0x80; 429 *(Uint8 *)(tempCrbuffer + i * (numPixels >> 1) + j) = 0x80; 430 } 431 } 432 } 433 434
★emouse 思·睿博客文章★
原创文章转载请注明:http://emouse.cnblogs.com