DSP时钟设计.docx
《DSP时钟设计.docx》由会员分享,可在线阅读,更多相关《DSP时钟设计.docx(19页珍藏版)》请在冰豆网上搜索。
DSP时钟设计
时钟设计
绪论
DSP(digitalsignalprocessor)是一种独特的微处理器,是以数字信号来处理大量信息的器件。
其工作原理是接收模拟信号,转换为0或1的数字信号。
再对数字信号进行修改、删除、强化,并在其他系统芯片中把数字数据解译回模拟数据或实际环境格式。
它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。
它的强大数据处理能力和高运行速度,是最值得称道的两大特色。
DSP微处理器(芯片)一般具有如下主要特点:
(1)在一个指令周期内可完成一次乘法和一次加法;
(2)程序和数据空间分开,可以同时访问指令和数据;
(3)片内具有快速RAM,通常可通过独立的数据总线在两块中同时访问;
(4)具有低开销或无开销循环及跳转的硬件支持;
(5)快速的中断处理和硬件I/O支持;
(6)具有在单周期内操作的多个硬件地址产生器;
(7)可以并行执行多个操作;
(8)支持流水线操作,使取指、译码和执行等操作可以重叠执行。
当然,与通用微处理器相比,DSP微处理器(芯片)的其他通用功能相对较弱些。
DSP的优点:
对元件值的容限不敏感,受温度、环境等外部因素影响小;
容易实现集成;VLSI
可以分时复用,共享处理器;
方便调整处理器的系数实现自适应滤波;
可实现模拟处理不能实现的功能:
线性相位、多抽样率处理、级联、易于存储等;
可用于频率非常低的信号。
1设计任务及目的
1.1设计任务
(1)通过查看书籍,总结以前学过的东西,明确设计时钟的思路
(2)使用芯片设计时钟,使用数码管显示时间,使用键盘修改时间
(3)总结设计过程,对实验结果做出总结
1.2设计目的
(1)通过课程设计,巩固已学过的知识,并在学过的基础上深化已学知识。
(2)通过动手做软件和硬件设计,能够熟练掌握数字信号处理技术,增加对基础知识的消化和理解。
(3)在课程设计的过程中培养讨论探究问题的能力。
2设计原理
2.1电路的设计
2.1.1时钟电路的设计原则
(1)系统中要求多个不同频率的时钟信号时,首选可编程时钟芯片,这样有利于时钟信号的同步;
(2)单一时钟信号时,一般的应用建议选择晶体时钟电路;
(3)多个同频时钟信号时,可选择有源的晶振作为时钟电路;
(4)尽量使用dsp片内的pll,降低片外时钟频率,提高系统的稳定性;
(5)c6000、c5510、c5409a、c5416、c5420、c5421和c5441等dsp片内无振荡电路,不能用晶体时钟电路;
(6)vc5401、vc5402、vc5409和f281x等dsp时钟信号的电平为1.8v,建议采用晶体时钟电路;
2.1.2C5509简介
C5509是一种具有高处理能力和低功耗特性的16位定点DSP芯片,适用于定时器时钟等实时嵌入应用场合。
与其它'C55X芯片一样,'C5509具有高度灵活的可操作性和高速的处理能力。
其性能特点如下:
操作速率可达100MIPS;具有先进的多总线结构,三条16位数据存储器总线和一条程序存储器总线;40位算术逻辑单元(ALU),包括一个40位桶形移位器和两个40位累加器;一个17×17乘法器和一个40位专用加法器,允许16位带/不带符号的乘法;整合维特比加速器,用于提高维特比编译码的速度;单周期正规化及指数译码;8个辅助寄存器及一个软件栈,允许使用业界最先进的定点DSPC语言编译器;数据/程序寻址空间为1M×16bit,内置4K×16bitROM和16K×16bitRAM;内置可编程等待状态发生器、锁相环时钟产生器、两个多通道缓冲串口、一个与外部处理器通信的8位并行HPI口、两个16位定时器以及6通道DMA控制器且低功耗。
'C55X系列片上集成有192K存储空间:
64K字程序空间、64K数据空间、64K字I/O空间,它具有23条外部程序地址线,可寻址1M字的外部程序空间,因此增设了额外的存储映射程序技术扩展寄存器XPC,以及6条扩展程序空间寻址指令,整个程序空间分成16页。
同时可寻址64K外部数据空间、64K外部I/O空间。
RAM包括两种类型,一是只可以一次寻址的SARAM,二是可以两次寻址的DARAM。
此外,还有数据存储器0页映射的25个特殊功能寄存器。
与'C55X系列的其它芯片相比,'5509具有高性能、低功耗和低价格等特点。
它采用6级流水线,且当RPT(重复指令)时,一些多周期的指令就变成了单周期的指令;芯片内部RAM和ROM可根据PMST寄存器中的OVLY和DROM位灵活设置。
2.1.3设计时钟时的注意事项
(1)需要倍频的DSP需要配置好PLL周边配置电路,主要是隔离和滤波;
(2)20MHz以下的晶体晶振基本上都是基频的器件,稳定度好,20MHz以上的大多是谐波的(如3次谐波、5次谐波等等),稳定度差,因此强烈建议使用低频的器件,毕竟倍频用的PLL电路需要的周边配置主要是电容、电阻、电感,其稳定度和价格方面远远好于晶体晶振器件;
(3)时钟信号走线长度尽可能短,线宽尽可能大,与其它印制线间距尽可能大,紧靠器件布局布线,必要时可以走内层,以及用地线包围;
(4)通过背板从外部引入时钟信号时有特殊的设计要求,需要详细参考相关的资料。
2.2模块知识
2.2.1中断和定时器
中断,指的是当某个事件发生时,暂停当前的操作,转向中断服务程序,执行完后再返回继续原来的操作。
这使得DSP能够处理多个任务。
DSP有许多中断源,可以设置中断控制寄存器来确定响应哪些中断而不理会哪些中断。
使用定时器首先要对它初始化,基本步骤如下:
1.关掉中断
2.停止定时器运行。
3.设定时器的定时长度
4.允许定时器中断
5.运行定时器
6.打开中断
定时器实际上可以有20个比特的周期寄存器。
它对CLKOUT信号计数,先将PSC(TCR中的D6-D9位)减1,直到PSC为0,然后用TDDR(TCR中的低4位)重新装入PSC,同时将TIM减1,直到TIM减为0。
这时CPU发出TINT中断,同时在TOUT引脚输出一个脉冲信号,脉冲宽度为CLKOUT一致。
然后用PRD重新装入TIM,重复下去直到系统或定时器复位。
计算公式:
TINT的频率=1/(tc*(TDDR+1)*(PRD+1)),tc为CLKOUT的周期。
定时器初始化步骤:
1.对TCR的TSS位写一以停止定时器
2.装载PRD
3.初始化TCR中的TDDR,并对TCR中的TSS置0,启动定时器
要开放定时中断,必须假定(INTM=1):
1.对IFR中的TINT写1以清除待决的定时器中断
2.对IMR中的TINT置1,使能定时器中断
3.使能全部中断,INTM置0
在RESET后,TIM和PRD被设置为最大值(FFFFh)。
TCR中的TDDR置0。
定时器启动。
2.2.2LED数码管显示电路
LED数码管是由若干个发光二极管按一定的规律排列而成的,当某个发光二极管导通时,相应的段就会被点亮。
根据内部发光二极管连接方式的不同,LED数码管可以分为共阳极和共阴极两类。
本文采用共阳极显示方式,段码值从0到9依次为:
Ox0C0、OxF9、Ox0A4、Ox0BO、0x99、0x92、0x82、0x0F8、Ox80、0x90。
数码管显示驱动方式可以分为动态(扫描)驱动和静态驱动,以下是三种设计方案:
(1)静态驱动方式
该方式中,各个LED数码管同时显示各自的字符,并维持不变,直到显示下一个字符为止。
这种方式下,每一个数码管要对应一个8位驱动存储器,8个数码管共需64根驱动线,因而需要较多芯片,显示面板面积较大。
(2)采用8根位选线的动态驱动显示
这是将所有数码管相同的段选线并联,各数码管位选线轮流选通,分时多路复用。
这种方案在任一时刻只有一位数码管被选中发光,然后利用人眼的视觉暂留特点实现同时显示的效果。
本显示面板有8个数码管,只需要8个位驱动线和8个段驱动线。
但8位循环显示时,每一位数码管的发光时间只占1/8循环时间,可能导数码管显示闪烁。
(3)采用4位分组动态驱动显示
这是将两个LED数码管共用一根位选线。
这种方案相对于方案2少用一个8位驱动器,每一位发光时间有1/4循环,因而比较容易保证数码管显示不闪烁。
2.2.3用键盘修改时间
用键盘修改时间,有两种方式:
(1)增减方式,。
当键入“1”时,直接秒++,然后判断进位2.当键入“2”时,直接分++,然后判断进位。
(2)数字键直接修改。
当键入“F”时,进入下一级菜单功能;等待当键入数字,将数字写入时判断数字合理性;等待当键入下一个数字,将数字写入分判断数字合理性。
3设计过程
3.1设计过程概述
首先了解5402DSP定时器的工作原理、操作过程、以中断、定时器的原理。
编写定时器初始化程序,在电脑中运行编写的原程序和命令文件。
准确无误后接通硬件设备,使用键盘修改时间,使用数码管显示时间,通过定时中断服务程序刷新数码管。
分析定时器初始化程序中与定时器有关的控制寄存器的设置。
各模块设计过程如下:
3.2设计具体过程
3.2.1中断的初始化
;initinterrupt(中断初始化)
bsetintm
mov#1,@ivpd
mov#1,@ivph
mov#10h,@ier0;ier0.tint0=1
mov#10h,@dbier0
mov#0,@ier1
mov#0ffffh,@ifr0;
mov#0ffffh,@ifr1;
callsdram_init
3.2.2定时器的初始化
;timerinit
mov#pdp_timer0,pdp
mov#04f0h,port(tcr0);*tcr0=0x04f0;
mov#0h,port(tim0);*tim0=0;
mov#0ffffh,port(prd0);*prd0=0x0ffff;
mov#15h,port(prsc0);*prsc0=15;
mov#0e0h,port(tcr0);*tcr0=0x00e0;
bclrintm;enableinterupt
bsetAR3LC
amov#led,xar2
mov#6,bk03
amov#led_i,xar3
mov#led_i,bsa23
mov#0,ar3
loop:
NOP
bloop
_Timer0:
mov*ar3+,*ar2;breakpoint
reti
.end
3.2.3数码管显示
unsignedintLEDCode[30]={0xc000,0xf900,0xA400,0xB000,0x9900,0x9200,0x8200,0xF800,0x8000,0x9000,0x8800,0x8300,0xc600,0xa100,0x8600,0x8e00,0x8c00,0xbf00,0xa700,0xff00,0x4000,0x7900,0x2400,0x3000,0x1900,0x1200,0x0200,0x7800,0x0000,0x1000}
LEDReg=6
SpiaRegs.SPITXBUF=LEDCode[LEDReg]
显示程序循环8次,修改8个LED
for(i=0,i<8,i++){SpiaRegs.SPITXBUF=LEDCode[LEDReg[i]]
while(SpiaRegs.SPISTS.bit.INT_FLAG!
=1)
{SpiaRegs.SPIRXBUF=SpiaRegs.SPIRXBUF;}
修改显示内容,只要改LEDReg[i],例:
LEDReg[0]=8;LEDReg[1]=7;
3.2.4用键盘修改时间
键盘的编程:
初始化GPIOB、GPIOE,建立变量KEYIN控制GPIOE输出KEYA;两次读入GPIOB的高8位,如果相同且有0出现则说明有键按下;数据送到KEYIN的低8位;控制GPIOE输出KEYB两次读入GPIOB的高8位,如果相同且有0出现则说明有键按下;数据送到KEYIN的高8位;等待键的释放,完成键的读取
程序如下:
intKeyinvoidKeyscan(void)
{unsignedintkey1R,key2R;
GPBDIR&=0x00FF;
GPEDAT=0xFFF8;
for(i=0;i<100;i++)
{key1R=GPBDAT;}
for(i=0;i<30000;i++)
{
if(key1R!
=GPBDAT)
key1R=0xffff;
GPEDAT=0xFFF9;}
}
for(i=0;i<100;i++)
{key2R=GPBDAT;}
for(i=0;i<30000;i++)
{if(key2R!
=GPBDAT)
key2R=0xffff;
Keyin=key2R&0xff00+key1R/256;
}
intKeyinvoidWaitKeyin(void)
{inttemp;
while(Keyin==0xFFFF)
{Keyscan();
temp=Keyin;}
while(Keyin!
=0xFFFF)
{Keyscan();}
switch(temp)
{caseK1:
Keyin=1;
break;
caseK2:
Keyin=2;
break;……
caseKf:
Keyin=f;;
break;
default:
Keyin=0x10;break;}
4流程图
图4.1中断服务程序框图
图4.2定时器初始化程序
图4.3用键盘修改时间流程图
图4.4数码管显示时间流程图
5运行结果及分析
软件仿真无误,0个错误,0个警告
以上程序运行无误,完成了时钟设计要求,使用dsp芯片设计时钟;使用数码管显示时间;使用键盘修改时间。
实现了用DSP定时器做时钟的设计,掌握了使用中断服务程序的编程方法。
6总结
通过两周的DSP课程设计,我学到了课本上以外的知识,提高了自己的动手能力,加深了对所学的知识的了解。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,才会有更大的运用空间。
在重新翻阅课本和老师的指导之下,也成功的完成了试验,从抽象的理论回到了丰富的实践创造,细致的了解了DSP设计的全过程,我利用此次难得的机会,努力完成实验,严格要求自己,认真学习DSP的基础理论,利用空余时间认真学习一些课本内容以外的相关知识,掌握了一些基本的实践技能。
课程设计是培养我们综合运用所学知识,发现、提出、分析、解决问题的一个过程,是对我们所学知识及综合能力的一次考察。
随着科学技术日新月异的不断发展,信息技术在不断的变化发展当中,这就要求我们用相应的知识来武装自己,夯实基础,为将来走向工作岗位,贡献社会做好充分的准备。
在这次课程设计中,要感谢老师的细心教导,和同学的帮助,最终我顺利的完成了这次课程设计。
7致谢
本次课程设计的内容是时钟的设计,首先你要感谢沈阳理工大学给我这次实践的机会。
以后这样的实践机会不多,很难得。
感谢实验室人员为我们提供了良好的实验环境,感谢老师的辛勤指导,当我们有疑问时提供给我们思路,而不是给答案,养成我们独立自主,创新思考的能力,在老师的指导下,我不仅顺利的完成课程设计,而且巩固了DSP说学的理论知识,更既有利于以后在这方面的学习与研究,在这里向老师致以真诚的感谢!
8参考文献
[1]逸民梁晓雯等,《基于DSP的现代电子系统设计》,电子工业出版社
[2]刘益成,《TMS320C54XDSP应用程序设计》,北京航空航天大学出版社
[3]郑红,吴冠编著,《TMS320C54XDSP应用系统设计》,北京航空航天大学出版社,2002.5。
[4]彭启琮.《TMS320C540×实用教程》.成都:
电子科技大学出版社,1999
[5]孙宗瀛《TMS320C5xDSP原理设计与应用》清华大学出版社2002
9附录
9.1程序清单
9.1.1时钟设计源程序.asm
.mmregs
.def_c_int00
.refsdram_init;参考外部变量
led.set400001h
tim0.set0x1000;
prd0.set0x1001;
tcr0.set0x1002;
prsc0.set0x1003;
sysr.set0x07fd;
clkmd.set0x1c00;
pdp_timer0.settim0/128
STACK.usect".stack",200h
SYSSTACK.usect".sysstack",200h
.data
led_i.word0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff
.sect".vectors"
rsv:
;resetvector
B_c_int00;branchtoCentrypoint
NOP
.align8
nmi:
.loop8
nop
.endloop
int0:
.loop8
nop
.endloop
int2:
.loop8
nop
.endloop
tint0:
B_Timer0
nop
.align8
.text
_c_int00:
amov#0,xdp
amov#STACK+100h,xsp
amov#STACK+200h,xssp
;initinterrupt(中断初始化)
bsetintm
mov#1,@ivpd
mov#1,@ivph
mov#10h,@ier0;ier0.tint0=1
mov#10h,@dbier0
mov#0,@ier1
mov#0ffffh,@ifr0;
mov#0ffffh,@ifr1;
callsdram_init
;timerinit
mov#pdp_timer0,pdp
mov#04f0h,port(tcr0);*tcr0=0x04f0;
mov#0h,port(tim0);*tim0=0;
mov#0ffffh,port(prd0);*prd0=0x0ffff;
mov#15h,port(prsc0);*prsc0=15;
mov#0e0h,port(tcr0);*tcr0=0x00e0;
bclrintm;enableinterupt
bsetAR3LC
amov#led,xar2
mov#6,bk03
amov#led_i,xar3
mov#led_i,bsa23
mov#0,ar3
loop:
NOP
bloop
_Timer0:
mov*ar3+,*ar2;breakpoint
reti
.end
9.1.2数码管源程序.C
ignedintLEDCode[30]={0xc000,0xf900,0xA400,0xB000,0x9900,0x9200,0x8200,0xF800,0x8000,0x9000,0x8800,0x8300,0xc600,0xa100,0x8600,0x8e00,0x8c00,0xbf00,0xa700,0xff00,0x4000,0x7900,0x2400,0x3000,0x1900,0x1200,0x0200,0x7800,0x0000,0x1000}
LEDReg=6
SpiaRegs.SPITXBUF=LEDCode[LEDReg]
for(i=0,i<8,i++){SpiaRegs.SPITXBUF=LEDCode[LEDReg[i]]
while(SpiaRegs.SPISTS.bit.INT_FLAG!
=1)
{SpiaRegs.SPIRXBUF=SpiaRegs.SPIRXBUF;}
9.1.3键盘源程序.C
intKeyinvoidKeyscan(void)
{unsignedintkey1R,key2R;
GPBDIR&=0x00FF;
GPEDAT=0xFFF8;
for(i=0;i<100;i++)
{key1R=GPBDAT;}
for(i=0;i<30000;i++)
{
if(key1R!
=GPBDAT)
key1R=0xffff;
GPEDAT=0xFFF9;}
}
for(i=0;i<100;i++)
{key2R=GPBDAT;}
for(i=0;i<30000;i++)
{if(key2R!
=GPBDAT)
key2R=0xffff;
Keyin=key2R&0xff00+key1R/256;
}
intKeyinvoidWaitKeyin(void)
{inttemp;
while(Keyin==0xFFFF)
{Keyscan();
temp=Keyin;}
while(Keyin!
=0xFFFF)
{Keyscan();}
switch(temp)
{caseK1:
Keyin=1;
break;
caseK2:
Keyin=2;
break;……
caseKf:
Keyin=f;;
break;
default:
Keyin=0x10;break;}
.end
9.1.4命令文件.CMD
-stack200h
-sysstack200h
MEMORY
{PAGE0:
MMR:
origin=0000000h,length=00000c0h
SPRAM:
origin=00000c0h,length=0000040h
VECS:
origin=0000100h,length=0000100h
DARAM0:
origin=0000200h,length=0001E00h
DARAM1:
origin=0002000h,length=0002000h
DARAM2:
origin=0004000h,length=0002000h
DARAM3:
origin=0006000h,length=00020