1.71k likes | 1.91k Views
第 7 章 汇编语言程序设计. 7.1 程序流程控制 7.2 数据块传送 7.3 定点数的基本算术运算 7.4 长字运算和并行运算 7.5 FIR 滤波器的 DSP 实现 7.6 IIR 数字滤波器的 DSP 实现 7.7 FFT 运算的 DSP 实现. 7.1 程序流程控制. 7.1.1 程序存储器地址生成 7.1.2 条件操作 7.1.3 分支转移 7.1.4 调用与返回 7.1.5 重复操作 7.1.6 TMS320C54x 中断系统 7.1.7 堆栈的使用. 返回首页. 7.1.1 程序存储器地址生成.
E N D
第7章汇编语言程序设计 • 7.1 程序流程控制 • 7.2 数据块传送 • 7.3 定点数的基本算术运算 • 7.4 长字运算和并行运算 • 7.5 FIR滤波器的DSP实现 • 7.6 IIR数字滤波器的DSP实现 • 7.7 FFT运算的DSP实现
7.1 程序流程控制 • 7.1.1 程序存储器地址生成 • 7.1.2 条件操作 • 7.1.3 分支转移 • 7.1.4 调用与返回 • 7.1.5 重复操作 • 7.1.6 TMS320C54x中断系统 • 7.1.7 堆栈的使用 返回首页
7.1.1 程序存储器地址生成 程序存储器中存放指令代码、参数表和立即数。程序地址产生逻辑(PAGEN),包括以下5个寄存器(如图7-1所示): 程序计数器(PC); 重复计数器(RC); 块重复计数器(BRC); 块重复起始地址寄存器(RSA); 块重复结束地址寄存器(REA)。
7.1.2 条件操作 表7-1 条件指令中的各种条件
可以使用多个条件作为条件指令的操作数,只有所有条件满足时才被认为是满足条件。这种多个条件的组合就构成了指令的多重条件,但必须是特定的条件组合。可以使用多个条件作为条件指令的操作数,只有所有条件满足时才被认为是满足条件。这种多个条件的组合就构成了指令的多重条件,但必须是特定的条件组合。 表7-2 多条件指令中的条件组合 返回本节
选用多重条件时应当注意以下几点: ①第1组:分为两类,最多可选择两个条件, 组内两类条件可以与/或构成多重条件,但不能用组内同类条件构成与/或多重条件。 当选择两个条件时,累加器必须是同一个。 例如,可以同时选择AGT和AOV,但不能同时选择AGT和BOV。 ② 第2组:分为三类,最多可选三个条件,可以在每类中各选一个条件进行与/或构成多重条件,但不能在同类选两个条件。 例如,可以同时测试TC、C和BIO,但不能同时测试NTC、C和NC。
【例7-1】条件操作程序。 BC sub,BLEQ; 条件分支转移 若累加器B≤0,则转至sub, 否则,往下执行 CC start,AGEQ,AOV; 条件调用 若累加器A≥0且溢出, 则调用start,否则往下执行 RC NTC; 条件返回 若TC = 0,则返回,否则往下执行
注意: 若需要多个条件相与时,用单条指令表示。 如:BC new, AGT, AOV 转移条件:AGT和AOV的与逻辑 若需要两个条件相或时,需用两条指令分别表示。 如:若累加器A大于0或溢出,则转移至sub 转移条件:AGT和AOV的或逻辑 BC sub, AGT BC sub, AOV
7.1.3 分支转移 通过传送控制到程序存储器的其他位置,分支转移会中断连续的指令流。 分支转移指令通过改写PC值,使程序改变流向。其指令分为无条件分支转移、条件分支转移和远分支转移三类。三者都可以带延时操作和不带延时操作。
无条件分支转移:无条件执行分支转移; 条件分支转移:要在满足用户一个或多个条件时才执行分支转移; 远程分支转移:允许分支转移到扩展存储器。 【例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,否则往下执行
【例7-3】比较操作后条件分支转移 STM #5,AR1; AR1=5 STM#10,AR0; AR0=10 loop:… … *AR1+; AR1=AR1+1 … … CMPR LT,AR1;若AR1-AR0<0,则TC=1,否则为0 BC loop, TC;若AR1-AR0<0,则循环 若AR1=AR0,则顺序执行
7.1.4 调用与返回 与分支转移一样,中断当前程的执行,转移到其他位置去执行,子程序调用会中断连续的指令流。但是与分支转移不同的是,这种转移是临时的,执行完调用程序还要返回到被中断的地方继续执行。 当函数的子程序被调用时,紧跟在调用后的下一条指令的地址保存在堆栈中。这个地址用于返回到调用前的程序并继续执行调用前的程序。 子程序调用操作分成三种形式:无条件调用和返回、有条件调用和返回、远调用和远返回,三者都可以带延时操作和不带延时操作。
无条件调用是指无条件执行调用。 条件调用和无条件调用操作相同,但是条件调用要在满足一个或多个条件时才执行调用。 远程调用允许对扩展存储器的子程序或函数进行调用。
子程序返回指令可以使程序重新在被中断的连续指令处继续执行。子程序返回指令可以使程序重新在被中断的连续指令处继续执行。 返回指令通过将弹出堆栈的值(包含将要执行的下一条指令的地址),送到程序计数器PC来实现返回功能。 C54x可以执行无条件返回和条件返回,并且它们都可以带延时或不带延时操作。
无条件返回是无条件执行返回操作。 条件返回可以给予被调用函数或中断服务程序(ISR)更多的返回方式,以便根据被处理的数据选择返回路径,通过使用条件返回指令来实现返回。 远程返回允许从扩展存储器的子程序或函数返回。
【例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中 ;子程序返回
7.1.5 重复操作 C54x的重复操作是使CPU重复执行一条指令或一段指令。可以分为单指令重复和块程序重复。 实现重复操作的指令: RPT ——重复执行下条指令; RPTZ——累加器清0,并重复执行下条指令; RPTB——使下一块指令重复执行。 使用RPT、RPTZ能重复下一条指令;而RPTB用于重复代码块若干次。利用重复指令可实现比BANZ指令更快的循环程序。
1 、单指令重复操作 利用RPT和RPTZ可重复执行紧随其后的一条指令。重复次数由该指令的操作数决定,并且等于操作数加1。 若要重复执行N+1次,则重复指令中应规定重复次数为N。该数值保存在16位重复计数器RC中,这个值只能由重复指令(RPT或RPTZ)加载,而不能编程设置RC寄存器中的值。一条指令的最大重复次数为65536。 由于要重复的指令只需要取指一次,对于多周期指令,采用重复操作后,可使多周期指令变成单周期指令,提高运行速度。
【例7-5】对数组进行初始化,使x[8]={0,0,0,0,0,0,0,0}。【例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指令设定重复次数后,再对累加器清零。
在执行重复操作期间,除了RS外所有中断被禁止,直到重复循环完成。 ’C54x能响应HOLD信号,若HM = 0,CPU继续执行重复操作,若HM = 1,则暂停重复操作。
2 、块程序重复操作 对于整个程序块需要重复操作时,可采用程序块重复操作。 用于块程序重复操作指令为RPTB和RPTBD。程序块的长度由块程序重复指令RPTB的操作数来确定,而重复次数由块重复计数器BRC来决定。 通常RPTB的操作数为程序块的结束地址,而重复次数可用STM指令对BRC进行设定。
块重复操作的特点: ① 程序块的起始地址RSA是RPTB指令的下一条指令的地址; ② 块结束地址REA由RPTB指令的操作数规定; ③ 与单指令重复操作不同,块重复操作可以响应中断。
块程序重复指令的特点是对任意长程序段的循环开销为0。循环由ST1状态寄存器的块重复标志位(BRAF)和紧跟在ST1状态寄存器后面的存储器映像寄存器控制。块程序重复指令的特点是对任意长程序段的循环开销为0。循环由ST1状态寄存器的块重复标志位(BRAF)和紧跟在ST1状态寄存器后面的存储器映像寄存器控制。 循环过程: ① 将块重复标志位BRAF置1,激活块程序重复循环; ② 将一个取值在0~65535范围里的循环次数N加载到BRC; ③ 块重复指令把块重复的起始地址放在块重复开始地址寄存器RSA中; ④ 块重复指令把块重复的末地址放在块重复结束地址寄存器REA中。
【例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指令可以响应中断。
【例7-7】三重循环嵌套程序。 STM #L-1,AR7 1st: 外部 STM #M-1,BRC RPTB 2nd-1 中间 中间 RPT #N-1 内部 中间 中间 2nd:外部 外部 BANZ 1st,*AR7- 外层 中层 内层
7.1.6 TMS320C54x中断系统 1.中断类型 • C54x支持软件中断和硬件中断。软件中断由程序指令产生(INTR、TRAP或RESET)。硬件中断由设备的一个信号产生,包括两种类型: ①外部硬件中断由外部中断口的信号触发; ②内部硬件中断由片内外设的信号触发。 软件中断不分优先级,硬件中断有优先级,其中,1为最高优先级。 无论是硬件中断还是软件中断,都属于以下两种类型: (1)可屏蔽中断 (2)非屏蔽中断
可屏蔽中断:是可用软件来屏蔽或开放的中断,即通过对中断屏蔽寄存器(IMR)中的相应位和状态寄存器(ST1)中的中断允许控制位INTM编程来屏蔽或开放该中断。TMS320C54x最多可以支持16个用户可屏蔽中断(SINT15~SINT0),但有的处理器只用了其中的一部分。有些中断有两个名称。可屏蔽中断:是可用软件来屏蔽或开放的中断,即通过对中断屏蔽寄存器(IMR)中的相应位和状态寄存器(ST1)中的中断允许控制位INTM编程来屏蔽或开放该中断。TMS320C54x最多可以支持16个用户可屏蔽中断(SINT15~SINT0),但有的处理器只用了其中的一部分。有些中断有两个名称。 非可屏蔽中断:是不能用软件来屏蔽的中断,不受IMR和INTM位的影响。TMS320C54x对这一类中断总是响应的,并从主程序转移到中断服务程序。
表7-9 C5402中断源的中断向量及硬件中断优先权
2 .中断寄存器 ’C54x中断系统设置两个中断寄存器,分别为中断标志寄存器IFR和中断屏蔽寄存器IMR。 (1)中断标志寄存器IFR 中断标志寄存器IFR是一个存储器映像寄存器,当一个中断出现时,IFR中的相应的中断标志位置1,直到CPU识别该中断为止。 ’C5402中断标志寄存器IFR的结构:
①软件和硬件复位,即C54x的复位引脚RS=0; 在C54x系列芯片中,IFR中5 ~ 0位对应的中断源完全相同,分别为外部中断和通信中断标志寄存位,而15~6位中断源根据芯片的不同,定义的中断源类型不同。有四种情况将清除中断标志: ②中断得到响应处理 ③相应的IFR标志位写1; ④使用相应的中断号响应该中断, 即使用INTR #K指令。
当状态寄存器ST1中的INTM位为0时,全局中断允许。IMR中的某位置1时,开放相应的中断。由于RS和NMI都不包含在IMR中,因此IMR对这两个中断不能进行屏蔽。 (2)中断屏蔽寄存器IMR 中断屏蔽寄存器是一个存储器映像寄存器,主要用于控制中断源的屏蔽和开放。
中断屏蔽寄存器IMR的结构: 用户可以对IMR寄存器进行读写操作。
3.中断响应过程 (1)接受中断请求 一个中断可由硬件器件或软件指令提出请求。当产生一个中断时,IFR寄存器中相应的中断标志位被置1。不管中断是否被处理器应答,该标志位都会置1。当相应的中断响应后,该标志位自动被清除。
①硬件中断请求 外部硬件中断由外部中断口的信号发出请求,而内部硬件中断由片内外设的信号发出中断请求。 C5402硬件中断的请求信号: 外部中断:INT3 ~ INT0引脚; 非屏蔽中断:RS和NMI引脚; 片内中断:BRINT0、BXINT0、BRINT1和BXINT1(串口中断) TINT0、TINT1(定时器中断); DMAC4、DMAC5(DMA中断); HPINT(HPI中断)。
②软件中断请求 软件中断是由程序指令产生的中断请求,主要有3条指令: INTR指令:允许执行任何的可屏蔽中断,包括用户定义的中断(从SINT0到SINT30); TRAP指令:与INTR指令相同,但不影响状态寄存器ST1的中断方式(INTM)位; RESET指令:可在程序的任何时候产生,使处理器返回一个预定状态。
(2)中断响应 对于软件中断和非屏蔽中断,CPU将立即响应,进入相应中断服务程序。 对于硬件可屏蔽中断,只要满足以下3种条件后CPU才能响应中断。 ①当前中断优先级最高。 ②INTM位清0。 ’C54x按照中断优先级响应中断请求。 当INTM=0,所有可屏蔽中断被使能。 当INTM=1,所有可屏蔽中断被禁止。 ③IMR屏蔽位为1。 在IMR中,中断的相应位为1,表明允许该中断。
满足上述条件后,CPU响应中断,终止当前正进行的操作,指令计数器PC自动转向相应的中断向量地址,取出中断服务程序地址,并发出硬件中断响应信号IACK,而清除相应的中断标志位。
(3)执行中断服务程序 CPU响应中断后,将进行以下操作: ①保护现场,将程序计数器PC值压入堆栈; ②将中断向量的地址加载到PC; ③从中断向量所指定的地址开始取指; ④执行分支转移,进入中断服务程序; ⑤执行中断服务程序直到出现返回指令; ⑥从堆栈中弹出返回地址,加载到PC中; ⑦继续执行主程序。
当执行一个中断服务程序时,有些寄存器必须保存在堆栈中。当程序从ISR返回时,用户软件代码必须恢复这些寄存器的上下文。当执行一个中断服务程序时,有些寄存器必须保存在堆栈中。当程序从ISR返回时,用户软件代码必须恢复这些寄存器的上下文。 使用堆栈操作指令可以将这些寄存器传送到堆栈中,或者从堆栈中取出。 PSHM指令:将MMR寄存器中的内容传送到堆栈中; POPM指令:从堆栈中读出的数据传送到MMR寄存器中; PSHD指令:将数据存储器中的数据传送到堆栈; POPD指令:从堆栈中读出的数据传送到数据存储器中.
当保存和恢复上下文时,应考虑如下几点: ① 当使用堆栈保存上下文时,必须按相反的方向执行恢复; ②当恢复ST1寄存器的BRAF位之前,应该恢复BRC位。如果没有按照这个顺序,BRC=0,则BRAF位将被清除。
4.重新映象中断向量地址 中断向量可以映射到程序存储器的任何128字页面的起始位置,除保留区域外。 C54x的中断向量地址是由PMST寄存器中的IPTR(9位中断向量指针)和左移2位后的中断向量序号所组成。 中断向量地址=IPTR+(左移2位的中断向量序号) 例如,IPTR=0001H,INT0的中断向量序号为10H,中断向量的地址为00C0H。 中断向量地址=000000001 1000000 = 00C0H
中断向量号左移两位后 中断向量地址 图7-3 中断向量地址的产生 返回本节
硬件复位时,IPTR=1FFH,复位向量将映射到程序存储器的511页空间,复位向量地址为FF80H。硬件复位时,IPTR=1FFH,复位向量将映射到程序存储器的511页空间,复位向量地址为FF80H。 当硬件复位后,CPU将从0FF80H开始执行程序。 若对IPTR重新赋值,中断向量可以映射到程序存储器的其他地址。 例如,用0001H加载IPTR,中断向量将被移到0080H单元开始的程序存储器空间。
中断矢量表程序举例 汇编程序文件(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
SINT28 .space 4*16 SINT29 .space 4*16 SINT30 .space 4*16 INT0 rsbx intm ;外中断0中断 rete nop nop INT1 rsbx intm ;外中断1中断 rete nop nop INT2 rsbx intm ;外中断2中断 rete nop nop TINT: bd timer ;定时器中断向量 nop nop nop RINT0: rete ;串口0接收中断 nop nop nop ******************************* ; 中断矢量表程序段 _c_int00 b start nop nop NMI rete ;非屏蔽中断 nop nop nop 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