Presentation is loading. Please wait.

Presentation is loading. Please wait.

第7章 汇编语言程序设计 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算

Similar presentations


Presentation on theme: "第7章 汇编语言程序设计 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算"— Presentation transcript:

1 第7章 汇编语言程序设计 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算
第7章 汇编语言程序设计 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算 7.5 FIR滤波器的DSP实现 7.6 IIR数字滤波器的DSP实现 7.7 FFT运算的DSP实现

2 7.1 程序流程控制 7.1.1 程序存储器地址生成 7.1.2 条件操作 7.1.3 分支转移 7.1.4 调用与返回
7.1 程序流程控制 程序存储器地址生成 条件操作 分支转移 调用与返回 重复操作 TMS320C54x中断系统 堆栈的使用 返回首页

3 程序存储器地址生成 程序存储器中存放指令代码、参数表和立即数。程序地址产生逻辑(PAGEN), 包括以下5个寄存器(如图7-1所示): 程序计数器(PC); 重复计数器(RC); 块重复计数器(BRC); 块重复起始地址寄存器(RSA); 块重复结束地址寄存器(REA)。

4 图7-1 程序地址产生逻辑(PAGEN)寄存器
返回本节

5 7.1.2 条件操作 表7-1 条件指令中的各种条件 操作符号 条 件 说 明 AEQ A=0 累加器A等于0 AOV AOV=1
条件操作 表7-1 条件指令中的各种条件 操作符号 条 件 说 明 AEQ A=0 累加器A等于0 AOV AOV=1 累加器A溢出 BEQ B=0 累加器B等于0 BOV BOV=1 累加器B溢出 ANEQ A0 累加器A不等于0 ANOV AOV=0 累加器A不溢出 BNEQ B0 累加器B不等于0 BNOV BOV=0 累加器B不溢出 ALT A<0 累加器A小于0 C C=1 ALU进位位置1 BLT B<0 累加器B小于0 NC C=0 ALU进位位置0 ALEQ A0 累加器A小于等于0 TC TC=1 测试/控制标志位置1 BLEQ B0 累加器B小于等于0 NTC TC=0 测试/控制标志位置0 AGT A>0 累加器A大于0 BIO BIO低 BIO信号电平为低 BGT B>0 累加器B大于0 NBIO BIO高 BIO信号电平为高 AGEQ A0 累加器A大于等于0 UNC 无条件操作 BGEQ B0 累加器B大于等于0

6 可以使用多个条件作为条件指令的操作数,只有所有条件满足时才被认为是满足条件。这种多个条件的组合就构成了指令的多重条件,但必须是特定的条件组合。
表7-2 多条件指令中的条件组合 第1组 第2组 A类 B类 C类 EQ NEQ LEQ GEQ LT GT OV NOV TC NTC C NC BIO NBIO 返回本节

7 选用多重条件时应当注意以下几点: ① 第1组:分为两类,最多可选择两个条件, 组内两类条件可以与/或构成多重条件,但不能用组内同类条件构成与/或多重条件。 当选择两个条件时,累加器必须是同一个。 例如,可以同时选择AGT和AOV,但不能同时选择AGT和BOV。 ② 第2组:分为三类,最多可选三个条件,可以在每类中各选一个条件进行与/或构成多重条件,但不能在同类选两个条件。 例如,可以同时测试TC、C和BIO,但不能同时测试NTC、C和NC。

8 BC sub,BLEQ ; 条件分支转移 【例7-1】 条件操作程序。 则调用start,否则往下执行 若累加器B≤0,则转至sub,
否则,往下执行 CC start,AGEQ,AOV ; 条件调用 若累加器A≥0且溢出, 则调用start,否则往下执行 RC NTC ; 条件返回 若TC = 0,则返回,否则往下执行

9 注意:  若需要多个条件相与时,用单条指令表示。 如:BC new, AGT, AOV 转移条件:AGT和AOV的与逻辑  若需要两个条件相或时,需用两条指令分别表示。 如:若累加器A大于0或溢出,则转移至sub 转移条件:AGT和AOV的或逻辑 BC sub, AGT BC sub, AOV

10 7.1.3 分支转移 通过传送控制到程序存储器的其他位置,分支转移会中断连续的指令流。
分支转移 通过传送控制到程序存储器的其他位置,分支转移会中断连续的指令流。 分支转移指令通过改写PC值,使程序改变流向。其指令分为无条件分支转移、条件分支转移和远分支转移三类。三者都可以带延时操作和不带延时操作。 分支转移指令 分 类 指 令 说 明 无条件 分支转移 B[D] 用该指令指定的地址加载PC BACC[D] 用累加器的低16位指定的地址加载PC 条 件 BC[D] 若满足指令给定条件,用该指令指定的地址加载PC BANG[D] 若当前选择辅助寄存器不等于0,用该指令指定的地址加载PC 远 程 FB[D] 用该指令指定的地址加载PC和XPC FBACC[D] 用累加器的低23位指定的地址加载PC和XPC

11 条件分支转移:要在满足用户一个或多个条件时才执行分支转移; 远程分支转移:允许分支转移到扩展存储器。
无条件分支转移:无条件执行分支转移; 条件分支转移:要在满足用户一个或多个条件时才执行分支转移; 远程分支转移:允许分支转移到扩展存储器。 【例7-2】 分支转移举例。 STM #88H,AR0 LD #1000H,A zhong: SUB AR0,A BC zhong,AGT,AOV ;将操作数#88H装入AR0 ;将操作数#1000H装入ACC ;将A中的内容减去AR0中的 ;内容结果装入A ;若累加器A>0且溢出, ;则转至zhong,否则往下执行

12 CMPR LT,AR1 ;若AR1-AR0<0,则TC=1,否则为0 BC loop, TC ;若AR1-AR0<0,则循环
【例7-3】比较操作后条件分支转移 STM #5,AR ; AR1=5 STM #10,AR0 ; AR0=10 loop: … *AR ; AR1=AR1+1 CMPR LT,AR ;若AR1-AR0<0,则TC=1,否则为0 BC loop, TC ;若AR1-AR0<0,则循环 若AR1=AR0,则顺序执行

13 调用与返回 与分支转移一样,中断当前程的执行,转移到其他位置去执行,子程序调用会中断连续的指令流。但是与分支转移不同的是,这种转移是临时的,执行完调用程序还要返回到被中断的地方继续执行。 当函数的子程序被调用时,紧跟在调用后的下一条指令的地址保存在堆栈中。这个地址用于返回到调用前的程序并继续执行调用前的程序。 子程序调用操作分成三种形式:无条件调用和返回、有条件调用和返回、远调用和远返回,三者都可以带延时操作和不带延时操作。

14 无条件调用是指无条件执行调用。 条件调用和无条件调用操作相同,但是条件调用要在满足一个或多个条件时才执行调用。 远程调用允许对扩展存储器的子程序或函数进行调用。

15 子程序调用指令 分 类 指 令 说 明 无条件调用 CALL[D] 将返回的地址压入堆栈,并用该指令指定的地址加载PC CALA[D]
分 类 指 令 说 明 无条件调用 CALL[D] 将返回的地址压入堆栈,并用该指令指定的地址加载PC CALA[D] 将返回的地址压入堆栈,用累加器A或B指定的地址加载PC 条件调用 CC[D] 如果满足指令给定条件,将返回的地址压入堆栈,并用该 指令指定的地址加载PC 远程调用 FCALL [D] 将XPC和PC压入堆栈,并用该指令指定的地址加载PC和XPC FCALA [D] 将XPC和PC压入堆栈,用累加器的低23位指定的地址加载 PC和XPC

16 子程序返回指令可以使程序重新在被中断的连续指令处继续执行。
返回指令通过将弹出堆栈的值(包含将要执行的下一条指令的地址),送到程序计数器PC来实现返回功能。 C54x可以执行无条件返回和条件返回,并且它们都可以带延时或不带延时操作。

17 子程序返回指令 分 类 指 令 说 明 无条件返回 RET[D] 将堆栈顶部的返回地址加载到PC。 RETE[D]
分 类 指 令 说 明 无条件返回 RET[D] 将堆栈顶部的返回地址加载到PC。 RETE[D] 将堆栈顶部的返回地址加载到PC,并使能可屏蔽中断。 RETF[D] 将RTN寄存器中的返回地址加载到PC,并使能可屏蔽中断。 条件返回 RC[D] 如果满足指令给定条件,将堆栈顶部的返回地址加载到PC。 远程返回 FCALL [D] 将堆栈顶部的值弹出加载到XPC, 将堆栈中下一个值弹出加载到PC。 FCALA [D] 将堆栈中下一个值弹出加载到PC,并使能可屏蔽中断。

18 无条件返回是无条件执行返回操作。 条件返回可以给予被调用函数或中断服务程序(ISR)更多的返回方式,以便根据被处理的数据选择返回路径,通过使用条件返回指令来实现返回。 远程返回允许从扩展存储器的子程序或函数返回。

19 【例7-4】 子程序调用举例。 STM #123H,AR0 LD #456H,AR1 CALL new LD AR1,16,A new:MPY AR0,AR1,A RET ;将操作数#123H装入AR0 ;将操作数#456H装入AR1 ;调子程序new ;将AR1的内容左移16位后装入A ;AR0与AR1的内容相乘,结果放入A中 ;子程序返回

20 7.1.5 重复操作 C54x的重复操作是使CPU重复执行一条指令或一段指令。可以分为单指令重复和块程序重复。 实现重复操作的指令:
重复操作 C54x的重复操作是使CPU重复执行一条指令或一段指令。可以分为单指令重复和块程序重复。 实现重复操作的指令: RPT —— 重复执行下条指令; RPTZ—— 累加器清0,并重复执行下条指令; RPTB—— 使下一块指令重复执行。 使用RPT、RPTZ能重复下一条指令;而RPTB用于重复代码块若干次。利用重复指令可实现比BANZ指令更快的循环程序。

21 1 、单指令重复操作 利用RPT和RPTZ可重复执行紧随其后的一条指令。重复次数由该指令的操作数决定,并且等于操作数加1。
若要重复执行N+1次,则重复指令中应规定重复次数为N。该数值保存在16位重复计数器RC中,这个值只能由重复指令(RPT或RPTZ)加载,而不能编程设置RC寄存器中的值。一条指令的最大重复次数为65536。 由于要重复的指令只需要取指一次,对于多周期指令,采用重复操作后,可使多周期指令变成单周期指令,提高运行速度。

22 【例7-5】对数组进行初始化,使x[8]={0,0,0,0,0,0,0,0}。
.bss x, 8 STM #x, AR1 LD #0, A RPT #7 STL A,*AR1+ .bss x, 8 STM #x, AR1 RPTZ A, #7 STL A, *AR1+ 注意: ① 对x[8]中的8个元素置0,重复次数为7,即执行1次STL A,AR1+指令后,再重复执行7次; ② RPTZ指令设定重复次数后,再对累加器清零。

23 在执行重复操作期间,除了RS外所有中断被禁止,直到重复循环完成。
’C54x能响应HOLD信号,若HM = 0,CPU继续执行重复操作,若HM = 1,则暂停重复操作。

24 2 、块程序重复操作 对于整个程序块需要重复操作时,可采用程序块重复操作。
用于块程序重复操作指令为RPTB和RPTBD。程序块的长度由块程序重复指令RPTB的操作数来确定,而重复次数由块重复计数器BRC来决定。 通常RPTB的操作数为程序块的结束地址,而重复次数可用STM指令对BRC进行设定。

25 块重复操作的特点: ① 程序块的起始地址RSA是RPTB指令的下一条指令的地址; ② 块结束地址REA由RPTB指令的操作数规定; ③ 与单指令重复操作不同,块重复操作可以响应中断。

26 块程序重复指令的特点是对任意长程序段的循环开销为0。循环由ST1状态寄存器的块重复标志位(BRAF)和紧跟在ST1状态寄存器后面的存储器映像寄存器控制。
循环过程: ① 将块重复标志位BRAF置1,激活块程序重复循环; ② 将一个取值在0~65535范围里的循环次数N加载到BRC; ③ 块重复指令把块重复的起始地址放在块重复开始地址寄存器RSA中; ④ 块重复指令把块重复的末地址放在块重复结束地址寄存器REA中。

27 【例7-6】对数组x[8]中的每一元素加1。 注 意 .bss x, 8 begin: LD #1,16,B STM #7,BRC
STM #x,AR4 RPTB next-1 ADD *AR4,16,B,A STH A,*AR4+ next: LD #0,B ;设置数组空间 ;立即数1送入BH ;设置重复次数,BRC=7,循环8次 ;数组首地址x送入AR4 ;设置循环结束地址 ;数组数据左移16位与BH相加 ;存入数组结果,并修改地址 ;B清0 注 意 ① 块结束地址REA通常取程序块最后一条指令的下一条指令地址-1; ② 重复次数为7次 ③ RPTB指令可以响应中断。

28 【例7-7】三重循环嵌套程序。 STM #L-1,AR7 1st: 外部 STM #M-1,BRC RPTB 2nd-1 中间
RPT #N-1 内部 2nd: 外部 外部 BANZ 1st,*AR7- 外层 中层 内层

29 TMS320C54x中断系统 1.中断类型 C54x支持软件中断和硬件中断。软件中断由程序指令产生(INTR、TRAP或RESET)。硬件中断由设备的一个信号产生,包括两种类型: ①外部硬件中断由外部中断口的信号触发; ②内部硬件中断由片内外设的信号触发。 软件中断不分优先级,硬件中断有优先级,其中,1为最高优先级。 无论是硬件中断还是软件中断,都属于以下两种类型: (1)可屏蔽中断 (2)非屏蔽中断

30 可屏蔽中断:是可用软件来屏蔽或开放的中断,即通过对中断屏蔽寄存器(IMR)中的相应位和状态寄存器(ST1)中的中断允许控制位INTM编程来屏蔽或开放该中断。TMS320C54x最多可以支持16个用户可屏蔽中断(SINT15~SINT0),但有的处理器只用了其中的一部分。有些中断有两个名称。 非可屏蔽中断:是不能用软件来屏蔽的中断,不受IMR和INTM位的影响。TMS320C54x对这一类中断总是响应的,并从主程序转移到中断服务程序。

31 表7-9 C5402中断源的中断向量及硬件中断优先权

32

33 ’C54x中断系统设置两个中断寄存器,分别为中断标志寄存器IFR和中断屏蔽寄存器IMR。 (1) 中断标志寄存器IFR
2 .中断寄存器 ’C54x中断系统设置两个中断寄存器,分别为中断标志寄存器IFR和中断屏蔽寄存器IMR。 (1) 中断标志寄存器IFR ’C5402中断标志寄存器IFR的结构: 中断标志寄存器IFR是一个存储器映像寄存器,当一个中断出现时,IFR中的相应的中断标志位置1,直到CPU识别该中断为止。 13 12 11 10 9 8 保 留 DMAC5 DMAC4 BXINT1 BRINT1 HPINT INT3 7 6 5 4 3 2 1 TINT1 DMAC0 BXINT0 BRINT0 TINT0 INT2 INT1 INT0

34 在C54x系列芯片中,IFR中5 ~ 0位对应的中断源完全相同,分别为外部中断和通信中断标志寄存位,而15~6位中断源根据芯片的不同,定义的中断源类型不同。有四种情况将清除中断标志:
① 软件和硬件复位,即C54x的复位引脚RS=0; ②中断得到响应处理 ③相应的IFR标志位写1; ④使用相应的中断号响应该中断, 即使用INTR #K指令。

35 (2)中断屏蔽寄存器IMR 中断屏蔽寄存器是一个存储器映像寄存器,主要用于控制中断源的屏蔽和开放。 当状态寄存器ST1中的INTM位为0时,全局中断允许。IMR中的某位置1时,开放相应的中断。由于RS和NMI都不包含在IMR中,因此IMR对这两个中断不能进行屏蔽。

36 中断屏蔽寄存器IMR的结构: 用户可以对IMR寄存器进行读写操作。 保 留 DMAC5 DMAC4 BXINT1 BRINT1 HPINT
13 12 11 10 9 8 保 留 DMAC5 DMAC4 BXINT1 BRINT1 HPINT INT3 7 6 5 4 3 2 1 TINT1 DMAC0 BXINT0 BRINT0 TINT0 INT2 INT1 INT0 用户可以对IMR寄存器进行读写操作。

37 3.中断响应过程 (1)接受中断请求 一个中断可由硬件器件或软件指令提出请求。当产生一个中断时,IFR寄存器中相应的中断标志位被置1。不管中断是否被处理器应答,该标志位都会置1。当相应的中断响应后,该标志位自动被清除。

38 外部硬件中断由外部中断口的信号发出请求,而内部硬件中断由片内外设的信号发出中断请求。
①硬件中断请求 外部硬件中断由外部中断口的信号发出请求,而内部硬件中断由片内外设的信号发出中断请求。 C5402硬件中断的请求信号: 外部中断: INT3 ~ INT0引脚; 非屏蔽中断:RS和NMI引脚; 片内中断:BRINT0、BXINT0、BRINT1和BXINT1(串口中断) TINT0、TINT1(定时器中断); DMAC4、DMAC5(DMA中断); HPINT(HPI中断)。

39 ②软件中断请求 软件中断是由程序指令产生的中断请求,主要有3条指令:  INTR指令:允许执行任何的可屏蔽中断,包括用户定义的中断(从SINT0到SINT30);  TRAP指令:与INTR指令相同,但不影响状态寄存器ST1的中断方式(INTM)位;  RESET指令:可在程序的任何时候产生,使处理器返回一个预定状态。

40 (2) 中断响应 对于软件中断和非屏蔽中断,CPU将立即响应,进入相应中断服务程序。 对于硬件可屏蔽中断,只要满足以下3种条件后CPU才能响应中断。 ① 当前中断优先级最高。 ② INTM位清0。 ’C54x按照中断优先级响应中断请求。 ③ IMR屏蔽位为1。 在IMR中,中断的相应位为1,表明允许该中断。 当INTM=0,所有可屏蔽中断被使能。 当INTM=1,所有可屏蔽中断被禁止。

41 满足上述条件后,CPU响应中断,终止当前正进行的操作,指令计数器PC自动转向相应的中断向量地址,取出中断服务程序地址,并发出硬件中断响应信号IACK,而清除相应的中断标志位。

42 (3)执行中断服务程序 CPU响应中断后,将进行以下操作: ① 保护现场,将程序计数器PC值压入堆栈; ② 将中断向量的地址加载到PC; ③ 从中断向量所指定的地址开始取指; ④ 执行分支转移,进入中断服务程序; ⑤ 执行中断服务程序直到出现返回指令; ⑥ 从堆栈中弹出返回地址,加载到PC中; ⑦ 继续执行主程序。

43 当执行一个中断服务程序时,有些寄存器必须保存在堆栈中。当程序从ISR返回时,用户软件代码必须恢复这些寄存器的上下文。
使用堆栈操作指令可以将这些寄存器传送到堆栈中,或者从堆栈中取出。 PSHM指令:将MMR寄存器中的内容传送到堆栈中; POPM指令:从堆栈中读出的数据传送到MMR寄存器中; PSHD指令:将数据存储器中的数据传送到堆栈; POPD指令:从堆栈中读出的数据传送到数据存储器中.

44 当保存和恢复上下文时,应考虑如下几点: ① 当使用堆栈保存上下文时,必须按相反的方向执行恢复; ② 当恢复ST1寄存器的BRAF位之前,应该恢复BRC位。如果没有按照这个顺序,BRC=0,则BRAF位将被清除。

45 图7-2 中断操作流程:

46 4.重新映象中断向量地址 中断向量可以映射到程序存储器的任何128字页面的起始位置,除保留区域外。 C54x的中断向量地址是由PMST寄存器中的IPTR(9位中断向量指针)和左移2位后的中断向量序号所组成。 中断向量地址=IPTR+(左移2位的中断向量序号) 例如,IPTR=0001H,INT0的中断向量序号为10H,中断向量的地址为00C0H。 中断向量地址= = 00C0H

47 中断向量号 左移两位后 中断向 量地址 图7-3 中断向量地址的产生 返回本节

48 硬件复位时,IPTR=1FFH,复位向量将映射到程序存储器的511页空间,复位向量地址为FF80H。
当硬件复位后,CPU将从0FF80H开始执行程序。 若对IPTR重新赋值,中断向量可以映射到程序存储器的其他地址。 例如,用0001H加载IPTR,中断向量将被移到0080H单元开始的程序存储器空间。

49 汇编程序文件(timers.asm)如下:
中断矢量表程序举例 汇编程序文件(timers.asm)如下: .mmregs .def _c_int00 STACK .usect "STACK",100h t0_cout .usect "vars",1 ;计数器 t0_flag .usect “vars”,1 ;当前XF输出电平标志。t0_flag=1, 则XF=1; ;t0_flag=0,则XF=0 TVAL .set 1639 ;1640(10(61=1ms,又因中断程序中计数器初值 ;t0_cout=1000,所以定时时间:1ms(1000=1s TIM0 .set 0024H ;定时器0寄存器地址 PRD0 .set 0025H TCR0 .set 0026H .data TIMES .int TVAL ;定时器时间常数 .text

50 *******************************
; 中断矢量表程序段 _c_int00 b start nop NMI rete ;非屏蔽中断 SINT17 .space 4*16 ;各软件中断 SINT18 .space 4*16 SINT19 .space 4*16 SINT20 .space 4*16 SINT21 .space 4*16 SINT22 .space 4*16 SINT23 .space 4*16 SINT24 .space 4*16 SINT25 .space 4*16 SINT26 .space 4*16 SINT27 .space 4*16 SINT28 .space 4*16 SINT29 .space 4*16 SINT30 .space 4*16 INT0 rsbx intm ;外中断0中断 rete nop INT1 rsbx intm ;外中断1中断 INT2 rsbx intm ;外中断2中断 TINT: bd timer ;定时器中断向量 RINT0: rete ;串口0接收中断

51 XINT0: rete ;串口0发送中断 nop SINT6 .space 4*16 ;软件中断 SINT7 .space 4*16 ;软件中断 INT3: rete ;外中断3中断 HPINT: rete ;主机中断 RINT1: rete ;串口1接收中断 XINT1: rete ;串口1发送中断 ****************************************** start: LD #0,DP STM #STACK+100h,SP STM #07FFFh,SWWSR STM #1020h,PMST ;计数器设置为 1000(1s) ST #1000,*(t0_cout) SSBX INTM ;关全部中断 LD #TIMES,A READA TIM ;初始化 TIM,PRD READA PRD0 STM #669h,TCR0 ;初始化TCR0 ;初始化 IMR, 使能 timer0 中断 STM #8,IMR RSBX INTM ;开放全部中断 WAIT: B WAIT *******************************************

52 ;定时器0中断服务子程序 timer: ADDM #-1,*(t0_cout) ;计数器减1 …………. ………………… RETE .end 链接命令文件(timers.cmd)如下 timers.obj /* 输入文件名 */ -o timers.out /*指定输出文件的选项*/ -m timers.map /*指定map文件的选项*/ MEMORY /*MEMORY 伪指令*/ { PAGE 0: RAM1:origin=1000h, length=500h PAGE 1: SPRAM1:origin=0600h, length=20h PAGE 1: SPRAM2:origin=0100h, length=200h } SECTIONS /*SECTIONS伪指令*/ .text : >RAM1 .data : >RAM1 .vars : >SPRAM1 .STACK :>SPRAM2

53 堆栈的使用 堆栈被用于保存中断程序、调用子程序的返回地址,也用于保护和恢复用户指定的寄存器和数据,还可用于程序调用时的参数传递。返回地址是由DSP自动保存的。 用户编写的压栈指令和出栈指令将指定的内容压入和弹出堆栈,SP总是指向最后压入堆栈的数据,压栈之前SP减1,出栈之后SP加1。

54 C54x支持软件堆栈,在用户指定的存储区开辟一块存储区作为堆栈存储器。堆栈的定义及初始化步骤为:
1. 堆栈的设置 C54x支持软件堆栈,在用户指定的存储区开辟一块存储区作为堆栈存储器。堆栈的定义及初始化步骤为: 1)声明具有适当长度的未初始化段; 2)将堆栈指针指向栈底; 3)在链接命令文件(.cmd)中将堆栈段放入内部数据存储区。 返回本节

55 若程序中要使用堆栈,必须先进行设置,如:
size .set stack .usect “STACK”,size STM # stack + size,SP 在RAM中定义一个STACK 的保留空间,共120个单元 保留区的高地址赋给SP, 作为堆栈的栈底 在数据RAM空间开辟一个堆栈区。 设置好堆栈后,就可以使用堆栈了,如: CALL pmad ;(SP)-1→SP,(PC)+2→TOS,pmad→PC RET ;(TOS)→PC,(SP)+1→SP 设置堆栈指针,# stack + size→SP。

56 2. 堆栈区大小的确定 堆栈区的大小可以按照以下步骤来确定: ① 先开辟一个较大的堆栈区,用已知数充填,如: LD # -9224,B
STM # length,AR1 MVMM SP,AR4 loop: STL B,*AR4- BANZ loop,*AR1- ;堆栈区要充填的数0DBF8h加载B ;设置循环次数 ;设置数据指针AR4,SP→AR4 ;循环,充填数据 数据RAM D SP→ AR4→ DBF8 length DBF8 DBF8 DBF8 DBF8 DBF8

57 2. 堆栈区大小的确定 堆栈区的大小可以按照以下步骤来确定: ① 先开辟一个较大的堆栈区,用已知数充填。 ② 运行程序,执行所有堆栈操作。
数据RAM AR4→ DBF8 SP→ ③ 检查堆栈中的数值。 用过的堆栈区就是实际需要的堆栈空间。 SP→ 7AB3 用过的栈区 0013 6B14

58 7.2 数据块传送 C54x有10条数据传送指令,共分为四类: (1) 数据存储器之间的数据传送 MVDK Smem,dmad
7.2 数据块传送 C54x有10条数据传送指令,共分为四类: (1) 数据存储器之间的数据传送 MVDK Smem,dmad MVKD dmad,Smem MVDD Xmem,Ymem 2字 2周期 1字 1周期

59 (2) 数据存储器与MMR之间的数据传送 MVDM dmad,MMR MVMD MMR,dmad MVMM MMRx,MMRy 2字 2周期 1字 1周期 (3) 程序存储器和数据存储器之间的数据传送 MVPD pmad,Smem MVDP Smem,pmad READA Smem WRITA Smem 2字 3周期 2字 4周期 1字 5周期

60 (4) 从PA口读/写数据 PORTR PA,Smem PORTW Smem,PA 2字 2周期 数据传送指令的特点: ① 传送速度比加载和存储指令要快; ② 数据传送不通过累加器; ③ 可寻址程序存储器; ④ 与RPT结合,可实现数据块传送。

61 1.编写汇编源程序为 .mmregs .def _c_int00 .data
TBL: .word0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1 7,18,19 .word 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 PROM: .usect "PROM",20 .bss a,20 .bss x,20 .bss y,20 DATA: .usect "DATA",20 .text

62 _c_int00 b start nop start: STM #a,AR1;a[20]={0,1,2,3,4,5,6,7,8,9,10, ;11,12,13,14,15,16,17,18,19} RPT # ;x[20]={1,1,1,1,1,1,1,1,1,1 MVPD TBL,*AR1+ ;1,1,1,1,1,1,1,1,1,1} STM #x,AR2;将数据存储器中的数组x[20]复制到数组y[20] STM #y,AR3 RPT #19 MVDD *AR2+,*AR3+

63 STM #a,AR1;将数据存储器中的a[20]写入到程序存储器PROM
LD #PROM,A STM #19,AR3 LOOPP: WRITA *AR1+ ADD #1,A,A BANZ LOOPP,*AR3- LD #PROM-1,A ;读程序存储器PROM中20个数据存入DATA STM #DATA,AR1 ST #19,BRC RPTB LOOP2 ADD #1,A,A LOOP2: READA *AR1+ ;该指令为单字指令 WAIT: NOP B WAIT

64 2.建立汇编源程序 点击CCS C5000图标,进入CCS环境,再点击File→New→Source File菜单命令,打开一个空白文档,将汇编源程序逐条输入。 单击File→Save菜单命令,出现如图7-5所示的窗口,选择D:\Program Files\ti \myprojcets\mymove子目录,在“文件名”一栏中输入mymove,并选择保存类型为Assembly Source Files(*.asm),单击“保存”按钮,以上汇编程序被存盘。

65 3.建立链接命令文件 点击File→New→Source File菜单命令,打开一个空白文档,逐条输入链接命令文件。 mymove.obj
-o mymove.out -m mymove.map MEMORY {PAGE 0: RAM: origin=1000h,length=800h RAM1:origin=2000h,length=300h PAGE 1: DARAM1: origin=0100h,length=100h DARAM2: origin=0200h,length=100h }

66 SECTIONS { .data :>RAM PAGE 0 .text :>RAM PAGE 0 PROM : >RAM1 PAGE 0 .bss :>DARAM1 PAGE 1 DATA :>DARAM2 PAGE 1 } 点击File→Save菜单命令,如图7-5所示,选择D:\Program Files\ti\myprojcets\mymove子目录,在“文件名”一栏中输入mymove,并选择保存类型为TI Command Language File(*.cmd),单击“保存”按钮,以上链接命令程序被存盘。

67 4.创建一个新工程 在Project菜单中选择New项,弹出Project Creation(工程创建)窗口,如图7-6所示。在Project一栏键入mymove,然后单击“完成”按钮,CCS将创建一个名为mymove.pjt的工程,此文件保存了工程的设置信息及工程中的文件引用情况。

68 图7-5 保存汇编源程序 图7-6 工程创建窗口

69 5.将有关文件添加到工程中 从Project菜单中选取Add Files to Project命令,选择文件mymove.asm,双击将mymove.asm添加到工程中。 点击Project→Add Files to Project菜单命令,将mymove.cmd添加到工程文件中。 逐层打开如图7-7所示。双击mymove.asm打开文件,可以观察和修改mymove.asm文件的内容。

70 6.汇编、编译和链接产生.out文件 点击Project菜单中的Rebuild All。请注意在监视窗口显示的汇编、编译和链接的相关信息。如果没有错误,将产生mymove.out文件;如果有错,在监视窗口以红色字体显示出错行,用鼠标双击该行,光标跳将至源程序相应的出错行。修改错误后,重新汇编、链接。

71 7.加载并运行.out文件 执行菜单命令File→Load Program,选择mymove.out并打开,将Rebuild All生成的程序加载到DSP中。CCS将自动打开一个反汇编窗口,显示加载程序的反汇编指令。 点击Debug→Run菜单命令运行程序,单步执行程序则点击Debug→StepInto菜单命令,或按F8键。

72 当结果数据错误时,可检查源程序并进行修改。修改完毕,可重新汇编、链接,再加载运行.out文件,直到结果正确。
8.观察运行结果 点击View→Memory菜单命令,将出现如图7-8所示的选项窗口,将Address改为0x0100,单击OK按钮,将在汇编窗口显示选定的数据空间的内容。 当结果数据错误时,可检查源程序并进行修改。修改完毕,可重新汇编、链接,再加载运行.out文件,直到结果正确。 返回本节

73 7.3 定点数的基本算术运算 加法、减法和乘法运算 定点除法运算 返回首页

74 7.3.1 加法、减法和乘法运算 1.定点DSP中数据的表示方法 (1) 数的定标 采用小数运算时,设定小数点在16位中的位置称为定标。
加法、减法和乘法运算 1.定点DSP中数据的表示方法 (1) 数的定标 采用小数运算时,设定小数点在16位中的位置称为定标。 小数点在16位数中的位置不同,可以表示不同大小和不同精度的小数。 数的定标通常有Q表示法,如Q0,Q1,…,Q15。Q越大,可以表示的数的范围越小,但精度越高。 在具体的定点程序中,必须根据具体情况适当选择合适的定标。

75 表7-10 Q表示、S表示及数值范围

76 (2)小数的表示方法 C54x采用基于2的补码小数表示形式。每个16位数用1个符号位(最高位)、Q个整数位、15-Q个小数位来表示。 采用2的补码小数(Q15格式),其位权值为: MSB …… …… LSB …… 2-15 例如: —— = 2.625

77 将十进制小数乘以32 768,并将整数乘积转换成16进制数。
Q15格式2的补码小数表示方法: 将十进制小数乘以32 768,并将整数乘积转换成16进制数。 正数:乘以32 768,整数转换成16进制数; 负数:其绝对值乘以32 768,整数取反加1。 图7-9 DSP定点运算中小数的表示

78 1×32 768=7FFFH 0.5×32 768=4000H 0.25×32 768=2000H 0×32 768=0000H (0.25×32 768)补=E000H (0.5×32 768)补=C000H (1×32 768)补=8000H 如: 1 —— 7FFFH 0.5 —— 4000H 0.25 —— 2000H 0 —— 0000H -0.25 —— E000H -0.5 —— C000H -1 —— 8000H 注意:汇编时,不能直接写成十进制小数。 如:0.907 —— .word *907/1000

79 2.16位定点加法和16位定点减法 C54x中提供了多条用于加法的指令,如ADD、ADDC、ADDM和ADDS。其中,ADDS用于无符号数的加法运算,ADDC用于带进位的加法运算而ADDM专用于立即数的加法。 C54x中提供了多条用于减法的指令,如SUB、SUBB、SUBC和SUBS。其中,SUBS用于无符号数的减法运算,SUBB用于带进位的减法运算,而SUBC为条件减法指令。 注意:在做加、减运算时,如果两个操作数的定标不一样,在运算前要进行小数点的调整,为保证运算精度,需要使Q值小的数调整为与另一个数的Q值一样大。

80 【例7-8】 x=5.625,y=-0.625,求x+y。 解: x=5.625,采用Q3.12格式表示的十六进制码为5A00H; y=-0.625,采用Q.15格式表示的十六进制码为B000H。 将y表示为Q3.12格式时,将它右移3位,因为是负数,所以整数部分符号位扩展后结果为F600H。将F600H加到5A00H上,结果为5000H,x+y的Q3.12格式的值等于5。

81 3.16位定点整数乘法 C54x中提供了大量的乘法运算指令,其结果都是32位,放在累加器A或B中。乘数在C54x的乘法指令中很灵活,可以是T寄存器、立即数、存储单元和累加器A或B的高16位。在C54x中,一般对数据的处理都当做有符号数,如果是无符号数相乘,使用MPYU指令,这是一条专门用于无符号数乘法运算的指令,其他指令都是有符号数的乘法。

82 在整数乘法编程时,应事先复位FRCT位,
如: RSBX FRCT LD x , T MPY y ,A STH A ,z_h STL A , z_l 若乘积未大于16位二进制能表示的范围,则只需要保存低16位即可。

83 4.Q15定点小数乘法运算 两个16位整数相乘,乘积总是“向左增长”,这就意味着多次相乘后乘积将会很快超出定点器件的数据范围。而且要将32位乘积保存到数据存储器,就要耗费两个机器周期以及两个字的程序和RAM单元。然而,两个Q15的小数相乘,乘积总是“向右增长”,这就意味着超出定点器件数据范围的将是不太感兴趣的部分。

84 小数乘法与冗余符号位 小数乘法实例: 0.5(-0.375) = (0.5) × (-0.375) (-0100) ( )

85 乘 积: = 位二进制 扩展为8位后,乘积: = 出错原因:两带符号数相乘,其结果带有2个符号位。 S x x x (Q3格式) 如: 左移1位: 结果: × S y y y (Q3格式) S S z z z z z z (Q6格式)

86 在小数乘法编程时,应事先设置FRCT位,
如: SSBX FRCT MPY *AR2,*AR3,A STH 只需要保存高16位即可完成了Q15*Q15=Q15的小数乘法。为了提高精度,还可以使用RND或MPYR指令对低16位做四舍五入处理后再保存高16位。

87 有些情况下,运算过程中为了既满足数值的动态范围又保证一定的精度,必须采用Q0与Q15之间的表示方法。
5.混合表示法 有些情况下,运算过程中为了既满足数值的动态范围又保证一定的精度,必须采用Q0与Q15之间的表示方法。 例如:数值1. 125显然用Q15格式无法表示,而若用Q0格式表示,则最接近的数是1,精度无法保证。因此,数1.125最佳的表示法是Q14格式。 返回本节

88 例如:1.125×1.5 = 。 (1.125 ) ;Q14 × (1.5 ) ;Q14 = ;Q28 32位的乘积: 左移一位后: 保留高16位: ( Q13) 由于Q14的最大值不大于2,因此,2个Q14数相乘得到的乘积不大于4,理论上用Q13表示乘积。由于1.6875不大于2,所以还可以将16位积左移一位后用Q14表示。 再左移一位: ( Q14)

89 【例7-9】使用C54X汇编语言编程计算z1=x1+y1、z2x1-y1、 z3=x1×y1、z4=x2×y2。
.title "suanshu.asm" .mmregs def start,_c_int bss x1,1 .bss x2, bss y1,1 .bss y2, bss z1,1 .bss z2,1 .bss z3_h,1 .bss z3_l,1 .bss z4, v1 .set H ; x v2 .set H ; y v3 .set H ; 0.5(fraction)----x v4 .set 00b548H ; (fraction)-----y2

90 _c_int00. b start. nop. nop start:. LD. #x1 , DP. ST. #v1 , x1. ST
_c_int00 b start nop nop start: LD #x1 , DP ST #v1 , x ST #v2 , y1 ; * * * * * * * * * * test ADD * * * * * * * * * * * * LD x1 , A ; load x1 -> A ADD y1 , A ; A + y1 -> A STL A , z1 ; save A(low 16 bits) ->z1 NOP ; * * * * * * * * * * test SUB * * * * * * * * * * * * LD x1 , A SUB y1 , A STL A,z2 NOP

91 ; * * * * * * * * * * test MPY (integer) * * * * * * * * * * * * RSBX FRCT ; 准备整数乘法 LD x1 , T ; x1 -> T MPY y1 ,A ; x1*y1 -> A (result is 32 bit) STH A , z3_h ; 乘法结果高16位在 z3_h单元中 STL A , z3_l ; 乘法结果低16位在z3_l单元中 NOP ST #v3 , x ST #v4 , y2 ; * * * * * * * * * * test MPY ((fraction) * * * * * * * * * * * * * ; * * * * * * * 0.5*( )= (0x0daa4) * * * * * * * * SSBX FRCT ; 准备小数乘法 LD x2 , 16 ,A ; load x2 into A (high 16 bits) MPYA y2 ; x2*y2 -> B, and y2 -> T STH B , z ; 结果在 z4 单元中 nop end: B end

92 【例7-10】使用双操作数指令编程计算y= 。 ;*** 编制计算小数乘法运算的程序段。其中数据均为小数***
;*** 编制计算小数乘法运算的程序段。其中数据均为小数*** ;***a1=0.1 a2=0.2 a3=-0.3 a4=0.4 *** ;***x1=0.8 x2=0.6 x3=-0.4 x4=-0.2*** .mmregs .def start,_c_int00 .bss x,4 .bss a,4 .bss y,1 .data table: .word 1*32768/10 .word 2*32768/10 .word -3*32768/10

93 .word 4*32768/ word 8*32768/ word 6*32768/ word -4*32768/ word -2*32768/ text _c_int00 b start nop nop start: SSBX FRCT STM #0,SWWSR STM #x,AR RPT # MVPD table,*AR STM #x,AR STM #a,AR STM #y,AR4 RPTZ A,# MAC *AR2+,*AR3+,A STH A,*AR4 done: B done .end

94 7.3.2 定点除法运算 条件减法指令: SUBC Smem, src 功能:(src)-(Smem)<<15→ALU输出端
定点除法运算 条件减法指令: SUBC Smem, src 功能:(src)-(Smem)<<15→ALU输出端 若ALU输出0,则(ALU输出)<<1+1→src 否则(src)<<1→src 在’C54x中没有除法器硬件,也没有专门的除法指令。但是,利用条件减法指令(SUBC)和重复指令(RPT)可实现两个无符号数的除法运算。 重复指令: RPT #K 功能:RC=#K,重复执行下条指令K+1次。

95 除法一般用有规律的减法去做,如: 0 0 0 0 1 1 商3 0011 0 0 0 0 1 0 1 0 被除数10 0 0 0 0 除数3
   商3 0011  被除数10  除数3 被除数位置不动 商位置不动 除数右移

96 现设累加器为8位,高字、低字各用4位表示,来说明10/3的实现过程。
(1)除数的最低有效位对齐被除数的最高有效位(除数左移3位)后相减: -  (2)不够减,放弃结果,将被除数左移一位再减: (3)不够减,放弃结果,将被除数左移一位再减:

97 -  (4)够减,将结果左移一位后加1,再做最后一次减: (5)够减果,将结果左移一位加1得到最后结果: ,即商为0011=3(低4位),余数为0001=1(高4位)

98 1. |被除数|<|除数| num 例: 编写0.4÷(-0.8)的程序 num den .bss num,1 quot
AR1 数据存储器 1. |被除数|<|除数| num quot 例: 编写0.4÷(-0.8)的程序 num 0.4 分子 .bss num,1 den -0.8 分母 .bss den,1 quot .bss quot,1 : .data : table .word 4*32768/10 ;0.4 .word -8*32768/10 ;-0.8 table 0.4 -0.8 .text start: STM #num,AR1 RPT #1 MVPD table,*AR1+

99 1. |被除数|<|除数| 例: 编写0.4÷(-0.8)的程序 num den LD @den,16,A quot
AR1 quot 0.4 : -0.8 数据存储器 num den quot table 1. |被除数|<|除数| 例: 编写0.4÷(-0.8)的程序 LD @den,16,A 0.8 ;分母送AH MPYA @num -0.5 ;商符号送B ABS A ;取分母绝对值 (num)×AH → B, 即分子×分母→B,取符号。 STH LD @num,16,A ;分子送AH ABS A ;取分子绝对值 RPT #14 SUBC @den,A ;15次减法循环 完成除法 XC 1,BLT ;若B<0,则变号 NEG A STL ;保存商

100 1. |被除数|<|除数| 例: 编写0.4÷(-0.8)的程序 运行结果: 被除数 除 数 商(十六进制) 商(十进制)
除 数 商(十六进制) 商(十进制) 4*32 768/100(0.4) -8*32 768/100(-0.8) 0xC000 -0.5 -128 1 024 0xF000 -0.125

101 2. |被除数|>|除数| 例: 编写16384÷512的程序 .bss num,1 .bss den,1 .bss quot,1
.data table .word .word 512 .text start: STM #num,AR1 RPT #1 MVPD table,*AR1+ ;16 384 ;512 ;传送2个数据至分子、分母单元

102 2. |被除数|>|除数| 例: 编写16384÷512的程序 LD @den,16,A MPYA @num ABS A
STH LD @num,A RPT #15 SUBC @den,A XC 1,BLT NEG A STL ;将分母移到累加器A(31~16) ;(num)*A(32~16)→B,获取商的符号 ;分母取绝对值 ;分母绝对值存回原处 ;分子→A(15~0) ;分子取绝对值 ;16次减法重复操作,完成除法 ;如果B<0(商是负数),则需要变号 ;保存商

103 2. |被除数|>|除数| 例: 编写16384÷512的程序 运行结果:
除 数 商(十六进制) 商(十进制) 16 384 512 0xC020 32 66*32 768/100(0.66) -33*32 768/100(-0.33) 0xFFFE -2 注意:SUBC指令仅对无符号数进行操作,因此先对被除数和除数取绝对值,然后利用乘法操作获取商的符号,最后通过条件操作指令给商加上适当的符号。

104 【例7-11】编写0.4÷(-0.8)的程序。 .title "chuf.asm" .mmregs .def start,_c_int00 .bss num,1 .bss den,1 .bss quot,1 .data table word 4*32768/ ;0.4 .word -8*32768/10 ;-0.8 .text _c_int00 b start nop

105 start: STM #num,AR1 RPT #1 MVPD table,*AR1+ ;传送2个数据至分子、分母单元 STM #den,AR1 LD *AR1-,16,A ;将分母移到累加器A(31-16) MPYA *AR ;(num)*(A(32-16))->B,获取商的符号 ;(在累加器B中) ABS A ;分母取绝对值 STH A,*AR ;分母绝对值存回原处 LD *AR1+,16,A ;分子->A(32-16) ABS A ;分子取绝对值 RPT # ;15次减法循环,完成除法 SUBC *AR1,A XC 1,BLT ;如果B<0(商是负数)则需要变号 NEG A STL A,*(quot) ;保存商 .END

106 7.4 长字运算和并行运算 长字运算 并行运算 返回首页

107 7.4.1 长字运算 ’C54x可以利用32位长操作数进行长字运算。 长字指令: DLD Lmem,dst ;dst=Lmem 单周期
长字运算 ’C54x可以利用32位长操作数进行长字运算。 长字指令: DLD Lmem,dst DST src,Lmem DADD Lmem,src[,dst] DSUB Lmem,src[,dst] DRSUB Lmem,src[,dst] ;dst=Lmem 单周期 ;Lmem=src 双周期 ;dst=src+Lmem 单周期 ;dst=src-Lmem 单周期 ;dst=Lmem-src 单周期

108 指令中给出的地址为偶地址,则存储器低地址存放高16位操作数。
1. 偶地址排列 长字的排列方式 偶地址排列 奇地址排列 指令中给出的地址为偶地址,则存储器低地址存放高16位操作数。 如: DLD *AR3+,A 执行前:A 00 0000 数据存储器 0100h 6 C A C 0101h B D 9 0 AR3 0100 高字 执行后:A 低字 00 0000 6CAC BD90 AR3 0100 0101 0102

109 指令中给出的地址为奇地址,则存储器低地址存放低16位操作数。
2. 奇地址排列 指令中给出的地址为奇地址,则存储器低地址存放低16位操作数。 如: DLD *AR3+,A 执行前:A 00 0000 数据存储器 0100h 6 C A C 0101h B D 9 0 AR3 0101 低字 高字 执行后:A 00 0000 BD90 6CAC AR3 0101 0103 0102

110 【例7-12】编写计算Z32=X32+Y32的程序 .title "ADD32" .mmregs .def start,_c_int00
.bss xhi , 2,1,1 .bss yhi , 2,1,1 .bss zhi , 2,1, 1 .data table long H .long 1020B30AH .text _c_int00 b start nop start: LD #xhi ,DP STM #xhi,AR1 RPT #3 MVPD table,*AR1+ DLD xhi , A DADD yhi , A DST A ,zhi END: B END .end

111 -o add32.out -m add32.map MEMORY {PAGE 0: RAM: origin=1000h,length=80h PAGE 1: DARAM1: origin=0100h,length=500h } SECTIONS { .text :>RAM PAGE 0 .data :>RAM PAGE 0 .bss :>DARAM1 PAGE 1

112 运算过程: X64: x3 x2 x1 x0 S64=s3s2s1s0 Y64: y3 y2 y1 y0 + s1s0=x1x0+y1y0
【例7-13】编写计算W64=X64+Y64-Z64的程序 运算过程: X64: x3 x2 x1 x0 S64=s3s2s1s0 Y64: y3 y2 y1 y0 + C s1s0=x1x0+y1y0 S64: s3 s2 s1 s0 s3s2=x3x2+y3y2+C Z64: z3 z2 z1 z0 - Z64=z3z2z1z0 C′ w1w0=s1s0-z1z0 W64: w3 w2 w1 w0 w3w2=s3s2-z3z2- C′

113 .title "ADDSUB64" .mmregs .def start,_c_int00 .bss x1 , 2 ,1,1 .bss x3 , 2 ,1,1 .bss y1 , 2 ,1,1 .bss y3 , 1 .bss y2 , 1 .bss z1 , 2 ,1,1 .bss z3 , 1 .bss z2 , 1 .bss w1 , 2 ,1,1 .bss w3 , 2 ,1,1 table .long H ;x1x0 .long 02468ACEH ;x3x2

114 .long H ;y1y0 .word 1357H,2468H ;y3,y2 .long H ;z1z0 .word 1020H,0B30AH ;z3,z2 .text _c_int00 b start nop start: LD #x1 ,DP STM #x1,AR1 RPT #11 MVPD table,*AR1+ DLD x1,A ; A = X1 X0 DADD y1,A ; A= X1 X0 + Y1 Y0,产生进位C DLD x3,B ; B = X3 X2

115 ADDC y2,B ; B = X3 X Y2 + C ADD y3,16,B ; B = X3 X2 + Y3 Y2 + C DSUB z1,A ; A= X1 X0 + Y1 Y0-Z1Z0,产生借位C' DST A,w1 ; W1W0= X1 X0 + Y1 Y0-Z1Z0 SUBB z2,B ; B = X3 X2 + Y3 Y2 + C - 00 Z2-C' SUB z3,16,B ; B = X3 X2 + Y3 Y2 + C -Z3 Z2-C' DST B,w3 ; W3 W2= X3 X2 + Y3 Y2 + C - Z3 Z2-C' END: B END .end

116 乘法指令: x1 x0 运算过程: 乘法运算: y1 y0 MPYU Smem,dst w0=x0y0L U×U x0×y0 x1×y0
;dst=U(T)×U(Smem) x1×y0 S×U S×U w1=x0y0H+x1y0L+y1x0L MACSU Xmem,Ymem,src y1×x0 S×U S×S y1×x1 S×S ;src=U(Xmem)×S(Ymem)+src w2=x1y0H+y1x0H+y1x1L w3 w2 w1 w0 MAC Xmem,Ymem,src w3=y1x1H S U U U ;src=S(Xmem)×S(Ymem)+src

117 STM #x0,AR2 STM #y0,AR3 LD *AR2,T MPYU *AR3+,A STL A,@w0 LD A,-16,A
MACSU *AR2+,*AR3-,A MACSU *AR3+,*AR2,A STL MAC *AR2,*AR3,A STL STH ;AR2←x0 RAM x0 x1 y0 y1 w0 w1 w2 w3 ;AR3←y0 ;T=x0 AR2→ ;A=u(x0)×u(y0) AR2→ ;(w0)←A AR3→ AR3→ ;A=x0y0H AR3→ AR3→ ;A=y1x0+x0y0H ;A=x1y0+y1x0+x0y0H ;(w1)←A ;A=y1x0H+x1y0H ;A=y1x1+y1x0H+x1y0H ;(w2)←A ;(w3)←A

118 7.4.2并行运算 并行运算就是同时利用D总线和E总线,通过并行指令来实现数据的加载和算术运算。 D总线用来执行加载或算术运算。
并行指令: 并行加载和乘法指令 并行加载和存储指令 并行存储和乘法指令 并行存储和加/减指令

119 并行加载和乘法指令: LD||MAC[R] LD||MAS[R] 例如: LD Xmem,dst1 ||MAC[R] Ymem,[,dst2] 功能:dst1=Xmem<<16; dst2=dst2+T*Ymem。

120 并行加载和存储指令: ST||LD 例如: ST src,Ymem ||LD Xmem,dst 功能:Ymem=src>>(16-ASM); dst=Xmem<<16。

121 并行存储和乘法指令: ST||MPY ST||MAC[R] ST||MAS[R] 例如: ST src,Ymem ||MAC[R] Xmem,dst 功能:Ymem=src>>(16-ASM); dst=dst+T*Xmem。

122 并行存储和加/减指令: ST||ADD ST||SUB 例如: ST src,Ymem ||ADD Xmem,dst 功能:Ymem=src>>(16-ASM); dst=dst+Xmem。

123 注 意 并行指令均为单字单周期指令; 并行指令先存储,后加载或算术运算; 并行指令的操作均在累加器的高位中 进行,并且大多数指令受ASM位的影响。

124 【例7-15】编写计算z=x+y和f=e+d的程序
· bss x,3 · bss d,3 STM #x,AR5 STM #d,AR2 LD #0,ASM LD *AR5+,16,A ADD *AR5+,16,A ST A,*AR5 ||LD *AR2+,B ADD *AR2+,16,B STH B, *AR2 · bss x,3 · bss d,3 STM #x,AR5 x y z …… d e f STM #d,AR2 LD #0,ASM LD *AR5+,16,A ADD *AR5+,16,A ST A,*AR5 ||LD *AR2+,B ADD *AR2+,16,B STH B, *AR2

125 7.5 FIR滤波器的DSP实现 线性缓冲区法 循环缓冲区法 系数对称FIR滤波器的DSP实现 返回首页

126 设FIR滤波器的系数为h(0),h(1), ...,h(N-1),X(n)表示滤波器在n时刻的输入,则n时刻的输出为:
数字滤波是DSP的最基本应用,利用MAC(乘、累加)指令和循环寻址可以方便地完成滤波运算。两种常用的数字滤波器:FIR(有限冲激响应)滤波器和IIR(无限冲激响应)滤波器的DSP实现。 设FIR滤波器的系数为h(0),h(1), ...,h(N-1),X(n)表示滤波器在n时刻的输入,则n时刻的输出为: (7-1)

127 如图7-10所示为横截型(又称直接型或卷积型)FIR数字滤波器的结构图。
(7-2) 其对应的滤波器传递函数为: 如图7-10所示为横截型(又称直接型或卷积型)FIR数字滤波器的结构图。 图7-10 横截型FIR数字滤波器的结构图

128 线性缓冲区法 线性缓冲区法又称延迟线法。其方法是:对于n=N的FIR滤波器,在数据存储器中开辟一个N单元的缓冲区,存放最新的N个样本;滤波时从最老的样本开始,每读一个样本后,将此样本向下移位;读完最后一个样本后,输入最新样本至缓冲区的顶部。 以上过程,可以用N=6的线性缓冲区示意图来说明,如图7-11所示

129 图7-11 N=6的线性缓冲区示意图 返回本节

130 循环缓冲区法 图7-12说明了使用循环寻址实现FIR滤波器的方法。对于N级FIR滤波器,在数据存储区开辟一个称为滑窗的具有N个单元的缓冲区,滑窗中存放最新的N个输入样本值。每次输入新的样本时,新的样本将改写滑窗中最老的数据,其他数据则不需要移动。

131 图7-12 FIR滤波器循环缓冲区存储器图

132 【例7-12】用循环缓冲区和双操作数寻址方法编写实现FIR滤波的程序。
设计一个FIR低通滤波器,通带边界频率为1500Hz,通带波纹小于1dB;阻带边界频率为2000Hz,阻带衰减大于40dB;采样频率为8000Hz。FIR滤波器的设计可以用MATLAB窗函数法进行。

133 2.产生滤波器输入信号的文件 按照通常的程序调试方法,先用Simulator逐步调试各子程序模块,再用硬件仿真器在实际系统中与硬件仪器联调。使用CCS的Simulator进行滤波器特性测试时,需要输入时间信号x(n)。本例设计一个采样频率Fs为8000Hz,输入信号频率为1000Hz和2500Hz的合成信号,通过设计的低通滤波器将2500Hz信号滤掉,余下1000Hz信号。

134 FIR数字滤波器汇编程序fir.asm如下:
.mmregs .global start .def start,_c_int00 INDEX .set 1 KS .set ;输入样本数据个数 COEF_FIR .sect "COEF_FIR" ;FIR滤波器系数 N set ;FIR滤波器阶数

135 .word 0,158,264,-290,-1406,-951,3187,9287,12272 .word9287,3187,-951,-1406,-290,264,158,0 .data INPUT .copy "firin.inc" ;输入数据在数据区0x2400 OUTPUT .space ;输出数据在数据区0x2500 COEFTAB .usect "FIR_COEF",N DATABUF .usect "FIR_BFR",N BOS .usect "STACK",0Fh TOS .usect "STACK",1 .text .asg AR0,INDEX_P

136 .asg AR4,DATA_P ;输入数据x(n)循环缓冲区指针
.asg AR5,COEF_P ;FIR系数表指针 .asg AR6,INBUF_P ;模拟输入数据指针 .asg AR7,OUTBUF_P ;FIR滤波器输出数据指针 _c_int00 b start nop nopstart: SSBx FRCT ;小数乘法编程时,设置FRCT(小数方式)位 MVPD #COEF_FIR,*COEF_P+ STM #INDEX,INDEX_P

137 FIR_TASK: STM #INPUT,INBUF_P STM #OUTPUT,OUTBUF_P
STM #DATABUF,DATA_P ;数据循环缓冲区清零 RPTZ A,#N-1 STL A,*DATA_P+ STM #(DATABUF+N-1),DATA_P;数据循环缓冲区指针指向x[n-(N-1)] STM #COEFTAB,COEF_P STM #COEFTAB,COEF_P ;将FIR系数从程序存储器移到数据存储器 RPT #N-1 FIR_TASK: STM #INPUT,INBUF_P STM #OUTPUT,OUTBUF_P

138 STM #KS-1,BRC RPTBD LOOP-1 STM #N,BK ;FIR循环缓冲区大小 LD *INBUF_P+,A ;装载输入数据 FIR_FILTER: ;FIR滤波运算 STL A,*DATA_P+% ;用最新的样本值替代最旧的样本值 RPTZ A,N-1 MAC *DATA_P+0%,*COEF_P+0%,A STH A,*OUTBUF_P+ LOOP: EEND B EEND .end

139 对应以上汇编程序的链接命令文件fir.cmd如下:
fir.obj -m fir.map -o fir.out MEMORY { PAGE 0: ROM1(RIX) :ORIGIN=0080H,LENGTH=100H PAGE 1: INTRAM1(RW) :ORIGIN=2400H,LENGTH=0200H INTRAM2(RW) :ORIGIN=2600H,LENGTH=0100H

140 INTRAM3(RW) :ORIGIN=2700H,LENGTH=0100H
B2B(RW) :ORIGIN=0070H,LENGTH=10H } SECTIONS { .text : {}>ROM1 PAGE 0 .data : {}>INTRAM1 PAGE 1 FIR_COEF: {}>INTRAM2 PAGE 1 FIR_BFR : {}>INTRAM3 PAGE 1 .stack : {}>B2B PAGE 1

141 5.CCS集成开发环境下上机操作过程 (1)在CCS上建立fir工程并运行fir.out程序。 (2)观察输入信号的波形及频谱(如图7-13~7-15所示)。 (3)观察输出信号的波形及频谱(如图7-16、7-17所示 )。

142 图7-13 Graph 属性设置窗口

143 图7-14 输入信号的时域波形 图7-15 输入信号的频谱图

144 图7-16 滤波器输出信号时域波形 图7-17 滤波器输出信号频谱图 返回本节

145 7.5.3 系数对称FIR滤波器的DSP实现 1.在数据存储器中开辟两个循环缓冲区:
New循环缓冲区中存放N/2=4个新数据(设N=8);Old循环缓冲区中存放4个老数据。循环缓冲区的长度为N/2。缓冲区指针AR2指向New 缓冲区中最新的数据;AR3指向Old 缓冲区中最老的数据,并在程序存储器中设置系数表,如图7-18所示。

146 2.(AR2)+(AR3)→AH(累加器A的高位)
(AR2)-1→AR2,(AR3)-1→AR3 3.将累加器B清0,重复执行以下操作N/2次(i=0,1,2,3): (AH)×系数ai+(B)→B,系数指针(PAR)加1 (AR2)+(AR3)→AH,AR2 和AR3减1 并保存或输出结果(结果在BH中)。

147 5.输入一个新的数据替代New 缓冲区中最老的数据 重复执行步骤2~5。
4.修正数据指针 将AR2和AR3分别指向New缓冲区中最新的数据和Old 缓冲区中最老的数据。用New 缓冲区最老的数据替代Old 缓冲区中最老的数据,如图7-18中箭头所示。Old 缓冲区指针减1。 5.输入一个新的数据替代New 缓冲区中最老的数据 重复执行步骤2~5。 返回本节

148 7.6 IIR数字滤波器的DSP实现 IIR数字滤波器的传递函数H(z)为: 其对应的差分方程为:
(7-3) (7-4) 返回首页

149 图7-19 直接形式的二阶IIR数字滤波器

150 图7-20 存放输入、输出变量和滤波器系数的缓冲区
图7-20 存放输入、输出变量和滤波器系数的缓冲区

151 在MATLAB中设计IIR滤波器,程序为:
【例7-15】设计一个三阶的切比雪夫Ⅰ型带通数字滤波器,其采样频率Fs =16kHz,其通频带3.2kHz<f<4.8kHz,内损耗不大于1dB;f <2.4kHz和f >5.6kHz为阻带,其衰减大于20dB。 1.IIR滤波器的设计 在MATLAB中设计IIR滤波器,程序为: wp=[3.2,4.8];ws=[2.4,5.6];rp=1;rs=20 [n,wn]=cheb1ord(wp/8,ws/8,rp,rs) [b,a]=cheby1(n,rp,wn) 设计结果为:

152 N=3 wn = b0= a0= b1=0 a1=0 b2= a2= b3=0 a3=0 b4= a4= b5=0 a5=0 b6= a6=

153 使用CCS的Simulator进行滤波器特性的测试时,需要输入时间信号x(n)。 #include <stdio.h>
2.产生滤波器输入信号的文件 使用CCS的Simulator进行滤波器特性的测试时,需要输入时间信号x(n)。 #include <stdio.h> #include <math.h> void main() { int i; double f[256]; FILE *fp; if((fp=fopen("iirin.inc","wt"))==NULL) printf("can't open file! \n"); return; }

154 { f[i]=sin(2*3.14159*i*4000/16000)+sin(2*3.14159*i*6500/16000);
fprintf(fp,"INPUT: .sect %cINPUT %c\n",'"','"'); for(i=0;i<=255;i++) { f[i]=sin(2* *i*4000/16000)+sin(2* *i*6500/16000); fprintf(fp," .word %1d\n",(long)(f[i]*32768/2)); } fclose(fp);

155 该程序将产生名为iirin.inc的输入信号程序,内容如下:
INPUT: .sect "INPUT" .word 0 .word .word .word -314 .word .word .word 6270 .word .word 然后,在DSP汇编语言程序中通过.copy汇编命令将生成的数据文件iirin.inc复制到汇编程序中,作为IIR滤波器的输入数据。

156 3.直接型IIR数字滤波器汇编源程序的编写
直接型IIR数字滤波器汇编程序diir.asm如下: ********直接型IIR数字滤波器通用程序********** .title "diir.asm" .mmregs .global start .def start,_c_int00 N .set 16 .copy "iirin.inc" ;输入信号x(n)数据 table ;IIR滤波器系数 .word 63, 0, -188, 0, 188, 0, -63 .word 0, 11675, 0, 9663, 0, 2948 .data

157 BN .usect "BN",N+1 AN .usect "AN",N+1 INBUF .usect "INBUF",256;输入缓冲区在数据区0x2400 OUTPUT .usect "OUTPUT",256;输出缓冲区在数据区0x2600 .text .asg AR0,INDEX_P .asg AR2,XN_P .asg AR3,ACOFF_P .asg AR4,YN_P .asg AR5,BCOFF_P _c_int00 b start nop start: SSBX FRCT

158 SSBX OVM SSBX SXM STM #BN+N,AR1 RPT #N MVPD #table,*AR1-; ;将bi由程序区存放到数据区 STM #AN+N-1,AR1 RPT #N-1 MVPD #table+N+1,*AR1- ;将ai由程序区存放到数据区 STM #OUTPUT,AR1 RPTZ A,#255 STL A,*AR1+ ;输出数据缓冲区清零 STM #INBUF,AR1 RPT #255 MVPD #INPUT,*AR1+ ;将输入数据由程序区

159 STM #OUTPUT,YN_P STM #INBUF,XN_P STM #N-1,INDEX_P STM #255,BRC RPTB LOOP-1 IIR: SUB A,A STM #BN,BCOFF_P STM #AN,ACOFF_P RPT #N-1 ;计算前向通道 MAC *XN_P+,*BCOFF_P+,A MAC *XN_P,*BCOFF_P,A

160 LOOP: EEND B EEND .end MAR *XN_P-0 ;将AR2指针指向x(n-N) RPT #N-1 ;计算反馈通道
MAC *YN_P+,*ACOFF_P+,A STH A,*YN_P-0 ;保存y(n) LOOP: EEND B EEND .end

161 4.IIR滤波器链接命令文件的编写 对应以上汇编程序的链接命令文件diir.cmd如下: diir.obj -o diir.out -m diir.map MEMORY { PAGE 0: ROM: ORIGIN=0080H, LENGTH=1000H PAGE 1: SPRAM: ORIGIN=0060H,LENGTH=0020H DARAM: ORIGIN=0080H, LENGTH=1380H RAM1: ORIGIN=2400H, LENGTH=0200H RAM2: ORIGIN=2600H, LENGTH=0200H } SECTIONS

162 { .text :>ROM PAGE 0 .data :>DARAM PAGE 1 BN :>DARAM PAGE 1 AN :>DARAM PAGE 1 INBUF :>RAM1 PAGE 1 OUTPUT :>RAM2 PAGE 1 } 返回本节

163 7.7 FFT运算的DSP实现 7.7.1 基二实数FFT运算的算法 7.7.2 FFT运算模拟信号的产生及输入
观察信号时域波形及其频谱 返回首页

164 7.7.1 基二实数FFT运算的算法 该算法主要分为以下四步。 第一步,输入数据的组合和位倒序
把输入序列作位倒序是为了在整个运算最后的输出中得到的序列是自然顺序。如图7-21所示。 第二步,N点复数FFT 在DATA数据处理缓冲器里进行N点复数FFT运算。如图7-22所示。

165 第三步,分离复数FFT的输出为奇部分和偶部分 分离FFT输出为RP、RM、IP和IM四个序列,即偶实数、奇实数、偶虚数和奇虚数四部分。
第四步,产生2N点的复数FFT输出序列 产生2N=256个点的复数输出,它与原始的256个点的实输入序列的DFT一致。如图7-24所示。 返回本节

166 FFT运算模拟信号的产生及输入 产生模拟输入信号可以有两种方法,第一种方法是用C语言程序产生mdata.inc文件,然后,在DSP汇编语言程序中通过.copy汇编命令将生成的数据文件mdata.inc复制到汇编程序中,如例7-12和例7-15,数据起始地址标号为INPUT,段名为INPUT。第二种方法是首先建立与输入信号对应的数据流文件mdata.dat,其数据格式如下: 0x1f400x1f40 …… 返回本节

167 7.7.3 实序列FFT汇编源程序及链接命令文件 【例7-16】256点实序列FFT的DSP实现。 256点实序列FFT汇编源程序如下:
************************************* *Radix-2,DIT,Real-input FFT Program * * fft.asm * .mmregs .global reset,start,sav_sin,sav_idx,sav_grp .def start,_c_int00 .data

168 DATA .space 1024 .copy "mdata1.inc" ; mdata1.inc为模拟输入信号数据,起始地址标号INPUT N .set 128 ;复数点数 LOGN .set ;蝶形级数 sav_grp .usect "tempv",3 ;定义组变量值 sav_sin .set sav_grp+1 ;定义旋转因子表 sav_idx .set sav_grp+2 OUTPUT .usect "OUTPUT",256 ;信号功率谱 BOS .usect "stack",0Fh ;定义堆栈 TOS .usect "stack",1 .copy "twiddle1.inc" ;正弦表系数由twiddle1.inc文件给出,起始地址标号TWI1

169 返回本节 .copy "twiddle2.inc" ;余弦表系数由twiddle2.inc文件给出,起始地址标号TWI2 .text
_c_int00 b start nop start: STM #TOS,SP LD #0,DP SSBX FRCT ***************************************************************** 返回本节

170 观察信号时域波形及其频谱 经程序计算得到的信号功率谱放在数据存储区0x2000开始的256个单元中。在CCS中选择View→Graph→Time/Frequency命令,选择程序区0x9000开始的256个单元中,Display Type分别选择为FFT Magnitude和Single Time,则信号频谱图及其时域波形如图7-25上半部分所示。将起始地址改为0x2000,page选项改为data,Sampling Rate为256,Display Type为Single Time,如图7-25。

171 图 输入信号时域波形、频谱图及其功率谱 返回本节


Download ppt "第7章 汇编语言程序设计 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算"

Similar presentations


Ads by Google