直接从图像处理这块进行学习不是特别适应,以前做单片机时由于单片机的片内资源不是特别多,所以对片内资源掌握的比较好,相关的寄存器配置等都是从底层自己配置,现在学习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