DSP考试资料.docx
《DSP考试资料.docx》由会员分享,可在线阅读,更多相关《DSP考试资料.docx(66页珍藏版)》请在冰豆网上搜索。
![DSP考试资料.docx](https://file1.bdocx.com/fileroot1/2023-1/1/9504c3cf-4e90-4e1a-b735-5afc3774a0ff/9504c3cf-4e90-4e1a-b735-5afc3774a0ff1.gif)
DSP考试资料
考点:
1.P65~67中断向量表地址(填空)IPVD(高16位)+行列号(中间五位)+000
2.n个引脚定时控制n个灯,要求n个灯依次点亮,延时时间按老师给的设置(类似题)要会画图
3.P298MTYPE域(填空)看手册
4.三种擦除方式要知道怎么编程,程序中涉及到
5.P336、P277CPU时钟频率=(mult/div+1)程序中涉及到
6.P373图9-29
7.画出DSP与存储器原理图(注意双向/单向通信)
一.DSP结构
1.TMS320C55x的硬件结构
CPU结构图P21
C55x有1条32位的程序数据总线(PB),5条16位数据总线(BB、CB、DB、EB、FB)和1条24位的程序地址总线及5条23位的数据地址总线,12条独立总线,这些总线分别与CPU相连。
总线通过存储器接口单元(M)与外部程序总线和数据总线相连,实现CPU对外部存储器的访问。
这种并行的多总线结构,使CPU能在一个CPU周期内完成1次32位程序代码读、3次16位数据读和两次16位数据写。
C55x根据功能的不同将CPU分为4个单元,即指令缓冲单元(I)、程序流程单元(P)、地址流程单元(A)和数据计算单元(D)。
C55x的CPU组成
1)指令缓冲单元(I单元):
书上P23图2-2:
组成:
32×16位指令缓冲队列;指令译码器。
功能:
接收程序代码并放入指令缓冲队列;由指令译码器解释指令,再把指令流传给其它的工作单元
1.指令缓冲队列:
每个机器周期,PB从程序空间传送32位的程序代码至I单元的指令缓冲队列;最大可以存放64个字节的待译码指令,可以执行块循环指令,具有对于分支、调用和返回指令的随机处理能力。
2.指令解码器:
当CPU准备译码时,6个字节的代码从队列发送到I单元的指令译码器;能够识别指令边界,译码8、16、24、32、40和48位的指令,决定2条指令是否并行执行,将译码结果和立即数送至P单元、A单元、D单元
2)程序流单元(P单元)
组成:
程序地址发生器;程序控制逻辑
功能:
产生所有程序空间地址,并送到PAB总线
1.P单元:
产生程序空间地址,并加载地址到PAB;控制指令流顺序
2.程序地址产生逻辑:
产生24位的程序空间取指的地址;可产生顺序地址;也可以I单元的立即数或D单元的寄存器值作为地址
3.程序控制逻辑:
接收来自I单元的立即数,并测试来自A单元或D单元的结果从而执行如下动作:
测试条件执行指令的条件是否成立,把测试结果送程序地址发生器;当中断被请求或使能时,初始化中断服务程序;控制单一指令重复或块指令重复;管理并行执行的指令
3)地址-数据流单元(A单元):
图2-4
组成:
数据地址产生电路(DAGEN);附加16位ALU和1组寄存器
功能:
产生读/写数据空间地址,并送到BAB、CAB、DAB总线
1.A单元算术逻辑电路:
ALU可接收来自I单元的立即数或与存储器、I/O空间、A单元寄存器、D单元寄存器和P单元寄存器进行双向通信。
可完成如下动作:
加法、减法、比较、布尔逻辑、符号移位、逻辑移位和绝对值计算;测试、设置、清空、求补A单元寄存器位或存储器位域;改变或转移寄存器值,循环移位寄存器值,从移位器向一个A单元寄存器送特定值。
2.数据地址产生器单元:
DAGEN产生所有读写数据空间的地址。
可接收来自I单元的立即数或来自A单元的寄存器值;根据P单元指示,对间接寻址方式时选择使用线性寻址还是循环寻址。
4)数据运算单元(D单元)
组成:
1个40位的筒形移位寄存器(barrelshifter);
2个乘加单元(MAC);1个40位的ALU;若干寄存器。
功能:
CPU中最主要的部分,是主要的数据处理部件
1.存储器接口单元(M单元):
是CPU和数据空间或I/O空间
2.移位器:
图2-5
接收来自I单元的立即数,与存储器、I/O空间、D单元寄存器、P单元寄存器、A单元寄存器进行双向通信;把移位结果送至D单元的ALU或A单元的ALU;
实现40位累加器值最大左移31位或最大右移32位;实现16位寄存器、存储器或I/O空间数据最大左移31位或最大右移32位;实现16位立即数最大左移15位;提取或扩张位域,执行位计数;对寄存器值进行循环移位;在累加器的值存入数据空间之前,对它们进行取整/饱和处理。
3.D单元ALU:
可从I单元接收立即数,或与存储器、I/O空间、D单元寄存器、P单元寄存器、A单元寄存器进行双向通信,还可接收移位器的结果;加法、减法、比较、取整、饱和、布尔逻辑以及绝对值运算;在执行一条双16位算术指令时,同时进行两个算术操作;测试、设置、清除以及求D单元寄存器的补码;对寄存器的值进行移动。
4.两个MAC:
可支持乘法和加/减法。
在单个机器周期内,每个MAC可以进行一次17×17位小数或整数乘法运算和一次带有可选的32或40位饱和处理的40位加/减法运算。
MAC的结果送累加器;MAC接收来自I单元的立即数,或来自存储器、I/O空间、A单元寄存器的数据,和D单元寄存器、P单元寄存器进行双向通信;MAC的操作会影响P单元状态寄存器的某些位。
指令流水线:
见书本P25页
DSP器件的六个特点:
哈佛结构,多总线结构,流水线技术,硬件乘法器,多处理单元结构,嵌入式功能。
冯·诺依曼结构:
程序和数据共用同一套总线,对程序和数据需要分时读写,执行速度慢,数据吞吐量低,计算机结构简单,不适于进行高速度的数字信号处理。
哈佛结构:
程序、数据具有独立的存储空间,有独立的程序总线和数据总线,可同时对程序和数据进行寻址和读写访问,执行速度高,数据吞吐量大,计算机结构复杂,非常适于进行高速的数字信号处理。
流水线技术,4级流水线分别为:
取指令,译码,取数,执行。
DSP复位后程序指针指向FF8000H—放置着bootloader(引导程序)
数据空间为128页每页64k
在DSP中有符号,无符号,短整型,整型都是16位。
Ioport类型的指针只有16位
C_int00为c/c++的程序入口地址
中断物理地址模型:
IVPD(16位):
ISP(5位):
000(保留)
IVPD(16位):
中断指针地址+ISP(5位):
中断序列号(32个中断)
复位后IVPD(16位)=FFFF00H
32个中断分为:
不可屏蔽中断如:
软件中断(指令),硬件中断(NMI,RESET)可屏蔽中断{INIM全局中断位IER局部中断位}
ISR中断服务程序;IFR中断标志程序
CPU中有96个寄存器
C55x的存储(数据/程序)空间统一编址,CPU读取程序代码时,使用24位地址访问相关字节,CPU读写数据时,使用23位地址访问相关字,两种情况下地址总线上均为24位,只是数据寻址时地址总线上的最低位强制填充0
C55x存储空间(总共为16M字节或8M字)的划分:
128个主页面(0~127),每个主页面为64K字,主页面0的前192个字节或96个字(000000h~0000BFh)被MMR所占用
CPU使用字地址访问数据空间
字地址为23位的,寻址16位的数据,地址线为24位的,当CPU读/写数据空间时,23位的字地址最低位补一个0成为总地址。
例:
字地址:
00000000000000100000010
地址线:
000000000000001000000100
I/O空间和程序/数据空间是分开的,只能用来访问DSP外设上的寄存器
I/O空间里的字地址宽度是16位,可以访问64K个地址
对于I/O空间的读写是通过数据读总线DAB和数据写总线EAB进行的,读写时要在16位地址前补0
例。
设一条指令从16位地址0102h处读取一个字,则DAB传输的24位地址为000102h。
汇编语言的设计:
COFF目标文件通常包括3个默认段,即
.text段,通常包含可执行代码
.data段,通常包含初始化数据
.bss段,通常为未初始化变量保留存储空间
汇编器通过段伪指令自动识别各个段,并将段名相同的语句汇编在一起;汇编器有5条伪指令可以识别汇编语言程序的各个不同段
.text、.data、.sect创建初始化段
.bss和.usect创建未初始化段
.sect与.usect创建自定义段和子段
C编译器生成的段
C编译器生成的段有两种基本的类型:
初始化段和未初始化段
初始化段有:
.cinit段:
包含初始化数据表格和常数
.pinit段:
包含实时运行时调用的数据表格
.const段:
包含用const定义(不能同时被volatile定义)的字符串常量和数据
.switch段:
包含switch语句所用表
.text段:
包含所有可执行代码
未初始化段保留了存储器空间,一段程序可以在运行期间使用这个空间来生成和存储变量:
.bss段:
为全局和静态变量保留了空间。
在启动和装载的时候,C启动程序或装载程序从.cinit段(通常在ROM中)复制数据并用这些数据来初始化.bss段中的变量
.stack段:
为C系统堆栈分配存储地址。
这个存储地址用来传递变量和局部存储
.sysmem段:
为动态存储分配保留空间。
这个空间被malloc、calloc和realloc函数调用。
如果C程序不使用这些函数,编译器就不会创建.sysmem段
.cio段:
支持CI/O。
这个空间用来作为标签为_CIOBUF_缓冲区。
当任何类型的CI/O被执行(如printf和scanf),就会建立
(a)C程序:
在c代码中访问汇编函数
/*声明汇编函数*/
externintasmfunc(int,int*);
intgvar;/*定义全局变量*/
main()
{
inti;
i=asmfunc(i,&gvar);/*调用函数*/
}
(b)汇编程序:
_asmfunc:
ADD*AR0,T0,T0;T0+gvar=>i,i=T0
RET;
访问.bss段或.usect段中没有初始化的变量:
使用.bss或.usect指令来定义变量
使用.global指令来定义为外部变量
在汇编语言中的变量前加下划线“_”
在C代码中声明变量为外部变量并正常地访问它
从C程序中访问定义在.bss段的变量
(a)C程序:
在c代码中访问汇编变量
externintvar;/*外部变量*/
var=1;/*使用变量*/
(b)汇编语言程序:
.bssvar,1;定义变量
.gloabalbar;声明变量为外部变量
当变量不是被存放在.bss段时,比如用汇编语言定义的查找表并不希望放在RAM中,这时应该定义一个指向该变量的指针并从C语言中对其间接访问。
首先,要定义变量
其次,声明一个指向该变量起始地址的全局指针,这个变量就可以被链接到存储空间的任何地方
最后,在C程序中访问时,必须先声明该对象为extern型,并且不能在其名称前面加下划线,然后就可以正常访问它了
在C代码中访问没有在.bss段中声明的变量。
(a)C程序:
在C代码中访问汇编语言常数
externfloatsine[];/*这就是对象*/
float*sine_p=sine;/*声明指针指向它*/
f=sine_p[2];/*正常访问该对象*/
(b)汇编程序:
.global_sine;声明变量为外部变量
.sect”sine_tab”;创建单独的段
_sine:
;表从此开始
.float0.0
.float0.015987
.float0.022145
(a)C语言程序:
externinttable_size;
/*声明table_size为外部参数*/
#defineTABLE_SIZE((int)(&table_size))
……
……
……
For(i=0;i/*象使用普通符号一样使用该常数*/
(b)汇编语言程序:
嵌入汇编语言
_table_size.set10000;定义常量
.global_table_size;定义该常量为全局常量
#pragmaCODE_SECTION(func_name,”section_name”)
作用:
把C函数func_name的代码配置到由section_name定义的程序段中
#pragmaDATA_SECTION(var_name,”section_name”)
作用:
var_name是包含在C函数内的变量名称,该指令将数据var_name配置到由section_name定义的数据段。
.INTM位
*如果INTM=0,C55x使能所有可屏蔽中断
*如果INTM=1,C55x禁止所有可屏蔽中断
*使用INTM位需要注意的要点:
INTM位能够全局使能或禁止可屏蔽中断,但是它对不可屏蔽中断无效。
在使用INTM位时,要使用状态位清零和置位指令来修改INTM位。
其它能影响INTM位的,只有软件中断指令和软件置位指令。
*CPU响应中断请求时,自动保存INTM位。
特别地,CPU把ST1_55保存到数据堆栈时,INTM位也被保存起来。
*执行中断服务子程序(ISR)之前,CPU自动置位INTM位,禁止所有的可屏蔽中断。
ISR可以通过清零INTM位,来重新开放可屏蔽中断。
*中断返回指令,从数据堆栈恢复INTM位的值。
*在调试器实时仿真模式下,CPU暂停时,忽略INTM位,CPU只处理临界时间中断。
二.LED闪烁(延时函数显示)
#include
#include
#include
#include
voiddelay()
{
inti,j;
for(i=0;i<0x00ff;i++)
for(j=0;j<0xFFFF;j++);
}
voidmain()
{
CSL_init();
PLL_setFreq(1,0xF,0,1,3,3,0);
GPIO_RSET(IODIR,0x80);
for(;;)
{
GPIO_RSET(IODATA,0x0f);
CHIP_FSET(ST1_55,XF,0);
delay();
GPIO_RSET(IODATA,0x8f);
CHIP_FSET(ST1_55,XF,1);
delay();
}
}
三.LED灯的闪烁(定时器做延时)
1)中断初始化函数:
ExternvoidVECSTAR(void)
VoidINTconfig(){
IRQ_setVecs((Uint32)(&VECSTART));//修改IVPH/IVPD
Old_intm=IRQ_globalDisable();//禁止可屏蔽中断源
EventId0=IRQ_EVT_INT0;//获取外部中断ID号
IRQ_clear(EventId0);/*清除中断标志位*/
IRQ_plug(EventId0,&int1);//为外部中断设置服务程序
IRQ_enable(EventId0);/*中断使能*/
IRQ_globalEnable();/*全局中断使能*/
}对于int1有一个中断服务程序interruptvoidint1(){}
INTconfig();调用
TimerCounterRegisters(CNT1–4)
Thetimercounterregister(Figure24)isa64-bitwideregisterconsistingoffour16-bitcountregisters(Figure25):
CNT1,CNT2,CNT3,andCNT4.
#_Inthegeneral-purposetimermode,the64-bittimercounterincrementswhenitisenabledtocount.Thetimercounterregisterisclearedto0atreset.
#_Intheenabledcontinuousmode(ENAMODE=10),the64-bittimercount-erincrementsuntilthevalueinthetimercountermatchesthetimerperiod.Thetimercounterregisterresetsto0andcontinuestoincrementonthenextclockafterthevalueinthetimercountermatchesthetimerperiod.
#_Inthedual32-bittimersmode,the64-bittimercounterregisterisdividedintotwopairsof16-bitregisters:
CNT2:
CNT1andCNT4:
CNT3.Thesetworegisterpairscanbeconfiguredaschainedorunchained。
代码:
定义段在汇编中.sect".vectors"
2)定时器控制灯的闪烁:
#include
#include
#include
#include
#include
#include
GPT_ConfigMyGptConfig={
0,//Emulationmanagementregister
0,//GPIOinterruptcontrolregister
0,//GPIOenableregister
0,//GPIOdirectionregister
0,//GPIOdataregister
0xB9EF,//
0x05F5,//
0,//
0,//
GPT_GPTCTL1_RMK(//
GPT_GPTCTL1_TIEN_NOT_GATED,//Timer没选通
GPT_GPTCTL1_CLKSRC_VBUS,//外部时钟源驱动TINP引脚
GPT_GPTCTL1_ENAMODE_CONTINUOUS,//定时器不断激活模式
GPT_GPTCTL1_PWID_INACTIVE_1CYCLE,//定时器到达周期后TSTAT停止计数时钟
GPT_GPTCTL1_CP_CLOCK_MODE,//时钟模式
GPT_GPTCTL1_INVIN_DONT_INVERT_OUTPUT,//不反相TINP驱动定时器
GPT_GPTCTL1_INVOUT_DONT_INVERT_OUTPUT//不反相的TSTAT驱动TOUT
),
GPT_GPTCTL2_RMK(//
GPT_GPTCTL2_TIEN_NOT_GATED,
GPT_GPTCTL2_CLKSRC_VBUS,
GPT_GPTCTL2_ENAMODE_CONTINUOUS,
GPT_GPTCTL2_PWID_INACTIVE_1CYCLE,
GPT_GPTCTL2_CP_CLOCK_MODE,
GPT_GPTCTL2_INVIN_DONT_INVERT_OUTPUT,
GPT_GPTCTL2_INVOUT_DONT_INVERT_OUTPUT
),
GPT_GPTGCTL1_RMK(//全局控制寄存器
GPT_GPTGCTL1_TDDR34_DEFAULT,
GPT_GPTGCTL1_PSC34_DEFAULT,
GPT_GPTGCTL1_TIMMODE_DEFAULT,//64比特普通模式
GPT_GPTGCTL1_TIM34RS_NOT_IN_RESET,
GPT_GPTGCTL1_TIM12RS_NOT_IN_RESET
)
};
interruptvoidTimer0Isr(void);
externvoidVECSTART(void);
GPT_HandlehGpt;
Uint16EventId0;//定时器0所对应的事件ID号
//通过定义宏来控制两个外围存储器映射的寄存器,从而实现对GPIO口的控制
#defineGPIODIR(*(volatileioportUint16*)(0x3400))
#defineGPIODATA(*(volatileioportUint16*)(0x3401))
voidmain(void)
{
CSL_init();
PLL_setFreq(1,0xF,0,1,3,3,0);
IRQ_setVecs((Uint32)(&VECSTART));//设置IVPH/IVPD开始中断向量表
IRQ_globalDisable();/*禁止中断*/
hGpt=GPT_open(GPT_DEV0,GPT_OPEN_RESET);
EventId0=GPT_getEventId(hGpt);
IRQ_clear(EventId0);/*清除中断溢出标志*/
IRQ_plug(EventId0,&Timer0Isr);
GPT_config(hGpt,&MyGptConfig);
IRQ_enable(EventId0);/*中断使能*/
IRQ_globalEnable();/*使能所有标志性中断*/
GPT_start(hGpt);/*开始定时器*/
GPIODIR=0x80;
for(;;)
{
if(LEDMARK==0)
{
//CHIP_FSET(ST1_55,XF,0);;/*关闭指示灯D5*/
//LEDMARK=1;/*在此行设置短点*/
//}
//else
//{
//CHIP_FSET(ST1_55,XF,1);;/*打开指示灯D5*/
//LEDMARK=0;/*在此行设置短点*/
//}
}/*进入系统循环,等待中断t*/
}
interruptvoidTimer0Isr(void)/*定时器0的中断程序*/
{
if(LEDMARK==0)
{
GPIODATA=0x00;/*关闭指示灯D5*/
LEDMARK=1;/*在此行设置短点*/
}
else
{
GPIODATA=0x80;/*打开指示灯D5*/
LEDMARK=0;/*在此行设置短点*/
}
//GP