54DSP十天速成10.docx

上传人:b****6 文档编号:5804238 上传时间:2023-01-01 格式:DOCX 页数:22 大小:32.72KB
下载 相关 举报
54DSP十天速成10.docx_第1页
第1页 / 共22页
54DSP十天速成10.docx_第2页
第2页 / 共22页
54DSP十天速成10.docx_第3页
第3页 / 共22页
54DSP十天速成10.docx_第4页
第4页 / 共22页
54DSP十天速成10.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

54DSP十天速成10.docx

《54DSP十天速成10.docx》由会员分享,可在线阅读,更多相关《54DSP十天速成10.docx(22页珍藏版)》请在冰豆网上搜索。

54DSP十天速成10.docx

54DSP十天速成10

实验一 新手上路]

来自中国视频教程基地

初学者编写的第一个程序通常是控制XF引脚的变化,然后用示波器测量XF脚波形或观察与相接的LED。

这个程序也常常用来测度一下DSP能否正常工作。

实验1.1 最简单的程序:

控制XF引脚周期性变化

实验目的:

通过简单的程序了解DSP程序的结构,熟悉CCS开发环境。

*************************************************************

*最简单的程序:

TestXF1.asm

*循环对XF位置1和清0,用示波器可以在XF脚检测到电平高低周期性变化

*常用于检测DSP是否工作。

*************************************************************

.mmregs ;预定义的寄存器

.def CodeStart ;定义程序入口标记

.text ;程序区

CodeStart:

 ;程序入口

SSBX XF ;XF置1

RPT #999 ;重复执行1000次空指令产生延时

NOP

RSBX XF ;XF清0

RPT #999 ;重复执行1000次空指令产生延时

NOP 

B CodeStart ;跳转到程序开头循环执行

.end 

NOP指令执行时间为一个时钟周期,设DSP工作频率是50MHz,可以估算出XF引脚电平的变化频率约为:

50M/2000=25kHz

在没有示波器的情况下,就要将程序1.1稍作改进,增加延时,用一个延时子程序将XF脚电平变化频率降到肉眼可分辨的程度,就可以用LED来显示电平的变化,程序如下:

实验1.2 子程序调用

实验目的:

学习子程序的调用

*************************************************************

*TestXF2.asm

*对TestXF1.asm稍作改进,用延时子程序设置较长的延时,

*可以用试验板上的LED看到XF引脚电平的变化

*************************************************************

.mmregs ;预定义的寄存器

.def CodeStart ;定义程序入口标记

.text ;程序区

CodeStart:

 ;程序入口

SSBX XF ;XF置1

CALL Delay ;调用延时程序

RSBX XF ;XF清0

CALL Delay ;调用延时程序

B CodeStart ;跳转到程序开头循环执行

**************************************************************

*延时子程序:

Delay

*用两级减一计数器来延时。

调整AR1和AR2的大小LED闪烁的频率不同

**************************************************************

Delay:

 

STM #999,AR1 ;循环次数1000

LOOP1:

 STM #4999, AR2 ;循环次数5000

LOOP2:

 BANZ LOOP2,*AR2- ;如果AR2不等于0,AR2减1,再判断

BANZ LOOP1,*AR1- ;如果AR1不等于0,AR1减1,跳转到LOOP1

RET

.end

**************************************************************

*注意这种延时方法并不精确,需要精确定时必须用定时器。

*按此法延时的近似公式为:

4*(AR2+1)*(AR1+1)*时钟周期

*当DSP工作在50MHz(时钟周期20ns),AR1=999, AR2=4999时

*延时约为400ms,则LED闪烁的周期为800ms,频率1.25Hz

**************************************************************

设计指导:

1.源代码书写格式

源代码的书写有一定的格式,初学者往往容易忽视。

简单归纳如下:

1.每一行代码分为三个区:

标号区、指令区和注释区。

标号区必须顶格写,主要是定义变量、常量、程序标签时的名称。

指令区位于标号区之后,以空格或TAB格开。

如果没有标号,也必须在指令前面加上空格或TAB,不能顶格。

注释区在标号区、程序区之后,以分号开始。

注释区前面可以没有标号区或程序区。

另外还有专门的注释行,以*打头,必须顶格开始。

2.一般区分大小写,除非加编译参数忽略大小写。

3.标点符号有时不注意会打成中文全角字符导致错误。

书写格式的要求在很多DSP书里都没有提,初学者往往只把书上的代码输入进去,编译时得到错误的提示,而不知所措。

其中最容易犯的错误指令顶格写,不过一般经提示后不会犯第二次。

有些格式CCS并没有做要求,但注意养成良好的代码书写风格,增加代码的可读性。

以上两个例子的书写风格可作参考,但不是硬性规定:

1.标号区占3个TAB的间隔,即12个字符

2.指令中的指令码占两个TAB间隔,然后是操作数。

3.每一行的尾注能对齐的尽量对齐

4.标明一段程序功能的注释以*号打头顶格写,如果功能说明的注释较多,用分格线框起来。

此外其它编程语言的编程风格也可以借用过来,比如标示符命名规则、程序说明的要求等。

如果项目组有规定,则按规定执行。

本书的代码尽量保持一定的风格,不过读者可以发现前面的代码注释较多,后面随着学习的深入,一般不会对每一条指令加注释,只注明程序段的功能。

另外代码贴到word里后,格式有些错位,无法一一纠正。

2.链接配置文件

一个完整的DSP程序至少包含三个部分:

程序代码、中断向量表、链接配置文件(*.cmd)。

这里介绍一下链接配置文件文件,对本次试验影响不大的中断向量表将在后文介绍。

连接配置文件的确定了程序链接成最终可执行代码时的选项,其中有很多条目,实现不同方面的选项,其中最常用的也是必须的有两条:

1.存贮器的分配 

2.标明程序入口。

以本次实验为例,下面的简单的链接配置文件就够用了:

/* TestXF.cmd */

-e CodeStart /*程序入口,必须在程序中定义相应的标号*/

MEMORY {

page 0:

PRAM:

 org=0100h len=0F00h /*定义程序存贮区,起始0100H,长度0F00H*/

}

SECTIONS{

.text:

>PRAM page 0 /*将.text段映射到page0的param区*/

}

由于每个程序都需要一个链接配置文件,可以编写一个满足通常需要的链接配置文件。

作为本手册通用的链接配置文件如下,可以满足本书大部分程序的需要。

在未特别指明的情况下使用这个通用的链接配置文件:

/* 5402.cmd */

-e CodeStart /*程序入口,必须在程序中定义相应的标号*/

-m map.map /*生成存储器映射报告文件 */

MEMORY {

PAGE 0:

VECT:

 org=0080h len=0080h /*中断向量表*/

PARAM:

 org=100h len=0F00h /*代码区*/

PAGE 1:

DARAM:

 org=1000h len=1000h /*数据区*/

}

SECTIONS {

.text :

> PARAM PAGE 0 /*代码段*/

.vectors :

> VECT PAGE 0 /*中断向量表*/

STACK :

> DARAM PAGE 1 /*堆栈*/

.bss :

> DARAM PAGE 1 /*未命名段*/

.data :

> DARAM PAGE 1 /*数据段*/

}

更多参考:

1.关于代码书写格式:

SPRU102:

 TMS320C54x Assembly Language Tools User's Guide,3.5 

Source Statement Format

2.关于链接配置文件:

SPRU102:

 TMS320C54x Assembly Language Tools User's Guide,7.5 

Linker Command Files,7.7 The MEMORY Directive,7.8 The SECTIONS Directive

练习:

1、试一下不按规定格式书写代码会产生什么样的编译错误。

2、试一下将链接配置文件中的MEMORY,SECTIONS改成小写会出现什么样的编译错误。

3.修改程序1.2中AR1,AR2的值,观察LED闪烁频率

实验二 基本运算

<本节选自为HK-DSP实验箱写的实验指导书,有待整理>

DSP指令数量最多的是:

算术指令、逻辑指令和数据加载与传送指令。

数据加载与传送指令由于处处要用,所以不单独列为实验。

算术与逻辑指令也是数量繁多,无法一一举例,这里简单举一个加法和除法的例子,乘法和乘加指令在FIR用得比较多,稍后一并介绍。

其它指令有兴趣可以对照指令表的说明,试验一下各指令运行的结果。

实验2.1 加减法计算 

************************************************

*计算z=x+y-w。

************************************************

.mmregs

.def CodeStart

Data_DP:

 ;数据段指针

x:

 .word 10 ;初始化变量

y:

 .word 26

w:

 .word 23

z:

 .word 0

.text

CodeStart:

LD #Data_DP,DP ;装载数据指针DP

STM #STACK+10H,SP

SUMB:

 LD x,A ;A=x

ADD y,A ;A=A+y

SUB w,A ;A=A-w

STL A,z ;z=A

END:

 B END

计算结果数据存储器地址存储内容十进制

x1010H000aH10

y1011H001aH26

w1012H0017H23

z1013H000dH13

技巧提示:

试验算术指令由于不需要外部资源,可以不需要仿真器和实验箱。

同学们可以平时自己用软件仿真,多多实验。

但是复杂的算法最好还是在线仿真,因为程序是流水线执行,软件仿真有时与实际硬件执行结果有所不同。

实验2.2 除法计算 

DSP并没有除法指令,回想一下我们用在稿纸上演算除法列的竖式,实际是一种移位减法,DSP中也是通过做多次减法的办法来做除法。

下面例子是把用除以10的办法二进制数转成BCD码例子:

*********************************

*16进制转BCD码

*********************************

.mmregs

.global CodeStart

.data

x:

 .word 1234 ;待转换的数字

y:

 .word 10 ;除数

z:

 .word 0Fh,0Fh,0Fh,0Fh,0Fh;结果区,每位BCD存一个字,

;初始化为F因为实验板的数码管不显示F

.text

 

CodeStart:

LD #x,DP ;设置DP

LD x,A ;被除数

STM #z,AR1 ;结果区指针

loop:

 

RPT #15 ;执行完16次减法后,A的高16位是余数

SUBC y,A ;低16位是商

STH A,*AR1+ ;余数保存到Z

AND #0FFFFH,A ;掩盖掉高16位,保留商值

BC loop,ANEQ ;继续做除法直到商为0 

end:

 B end

练习:

练习其他算术指令

其它参考:

spru172c:

TMS320C54x DSP Reference Set Volume 2:

 Mnemonic Instruction 

Set,2.1 Arithmetic Operations

这个资料对每个指令都有详细说明。

也可以在Help中的TMS320C54x DSP Mnemonic Instruction 

Set中查询或搜索相关指令。

实验三 中断

中断的概念应该不陌生,指的是当某个事件发生时,暂停当前的操作,转向中断服务程序,执行完后再返回继续原来的操作。

这使得DSP能够处理多个任务。

DSP有许多中断源,可以设置中断控制寄存器来确定响应哪些中断而不理会哪些中断。

本实验介绍最常用的定时器中断和外部中断的使用方法,并介绍中断向量表和中断向量指针。

实验3.1 定时器中断:

方波发生器

实验目的:

学习定时器中断的设计方法

回顾一下实验一控制LED的闪烁实际就是一个简单的方波发生器。

但不足的是延时的方法定时不精确,另外还有一个缺点是在执行延时的过程中DSP就无法执行其它指令,这时就可以用定时器来改进。

使用定时器首先要对它初始化,基本步骤如下:

1.关掉中断

2.停止定时器运行。

3.设定时器的定时长度

4.允许定时器中断

5.运行定时器

6.打开中断

现以简单的方波程序为例:

;==============================================

; fangbo1.asm

; 利用定时器Timer0在XF脚产生周期2ms的的方波

;==============================================

.title "fangbo1.asm"

.mmregs

.def codestart ;程序入口

.def TINT0_ISR ;Timer0中断服务程序

STACK .usect "STACK",10H ;分配堆栈空间 

;设定定时器0控制寄存器的内容

K_TCR_SOFT .set 0B<<11 ;TCR第11位soft=0

K_TCR_FREE .set 0B<<10 ;TCR第10位free=0

 

K_TCR_PSC .set 0B<<6 ;TCR第9-6位,可设TDDR一样,也可不设自动加载

K_TCR_TRB .set 1B<<5 ;TCR第5位TRB=1此位置1,PSC会自动加载的

K_TCR_TSS .set 0B<<4 ;TCR第4位TSS=0

K_TCR_TDDR .set 1001B<<0 ;TCR第3-0位TDDR=1001B

K_TCR .set 

K_TCR_SOFT|K_TCR_FREE|K_TCR_PSC|K_TCR_TRB|K_TCR_TSS|K_TCR_TDDR

K_TCR_STOP .set 1B<<4 ;TSS=1时计数器停止

.data

DATA_DP:

 ;数据区指针

XF_Flag:

 .word 1 ;当前XF的电平标志,如果XF_Flag=1,则XF=1

;================================================

;主程序:

;================================================

.text

CodeStart:

STM #STACK+10H,SP ;设堆栈指针SP

LD #DATA_DP,DP ;设数据地址DP

STM #XF_Flag,AR2 ;AR指向XF标志

;改变中断向量表位置

K_IPTR .set 0080h ;指向0080H,默认是FF80

LDM PMST,A

AND #7FH,A ;保留低7位,清掉高位

OR #K_IPTR,A ;

STLM A,PMST

*初始化定时器0

*f=50MHz,定时2ms时:

*根据定时器长度计算公式:

Tt=T*(1+TDDR)*(1+PRD)

*给定TDDR=9,PRD=9999,CLKOUT主频f=40MHz,T=25ns

*Tt=20ns*(1+9)*(1+9999)=2000us=2ms

*f=100Mhz,定时最大是:

10ns*2^4*2^16=10ms,

PERIOD .set 9999 ;定义计数周期

STM K_TCR_STOP,TCR ;停止计数器0

; STM #PERIOD,TIM ;可设成跟PRD一样,也可不设自动加载

STM #PERIOD,PRD ;设定计数周期

STM #K_TCR,TCR ;开始Timer0

stm #0008h,IMR ;允许Timer0中断

STM #0008h,IFR ;清除挂起的中断

rsbx intm ;开中断

end:

 nop

B end 

;================================================

;Timer0中断服务程序:

TIN0_ISR

;================================================

TINT0_ISR:

 

PSHM ST0 ;本中断程序影响TC,位于ST0中

;判断当前XF状态并作电平变化

BITF *AR2,#1 ;IF XF_Flag=1 then TC=1 else TC=0

BC ResetXF,TC ;IF TC=1 then XF=0 else XF=1

setXF:

 

SSBX XF ;置XF为高电平

ST #1,*AR2 ;相应修改标志

B Next

ResetXF:

RSBX XF ;;置XF为高电平

ST #0,*AR2 ;相应修改标志

Next:

POPM ST0

RETE 

.end 

有时定时的长度不能满足需要,比如DSP工作频率50Mhz时,定时最大值是:

20ns*2^4*2^16=20ms。

如果需要更长的定时,就要在定时器中断子程序中再加一个计数器,直到产生一定次数的定时中断后再执行相应的操作。

程序只需要稍作修改,见附盘的fangbo2.asm

技巧提示:

寄存器的不同位通常有不同的含义,初始化时单独设定寄存器的每一位可以增加程序可读性,容易让其它人看懂具体每一位设置的含义,并且易于修改。

如果代码太长可以自己写一个初始化的子程序,需要时修改一下调定时再调用。

当然如果对寄存器各个位的含义相当熟悉,直接整个初始化也行。

可以自行选择这些不同的编程风格。

设计指导:

1.中断向量表

中断向量表是DSP程序的重要组成部分,当有中断发生并且处于允许状态时,程序指针跳转到中断向量表中对应的中断地址。

由于中断服务程序一般较长,通常中断向量表存放的是一个跳转指令,指向实际的中断服务程序。

下面是5402中断向量表的一个范例,可以作为模板,使用时稍作修改就行:

*****************************************************************

*5402Vectors.asm

*完整的5402中断向量表示例

*5402共有30个中断向量,每个向量占4个字的空间。

*使用向量一般用一条跳转指令转到相应中断服务子程序,其余空位用NOP填充

*未使用的向量直接用RETE返回,是为了防止意外进入未用中断。

*****************************************************************

.sect ".vectors" ;开始命名段.vecotrs

.global CodeStart ;引用程序入口的全局符号定义

;。

引用其它中断程序入口的全局符号定义

.align 0x80 ; 中断向量表必须对齐128字的页边界

RESET:

 B CodeStart ; Reset中断向量,跳转到程序入口

NOP ;用NOP填充表中其余空字

NOP ;B指令占了两个字,所以要填两个NOP

NMI:

 RETE ;不可屏蔽中断

NOP

NOP

NOP 

; 软件中断

SINT17 .space 4*16 ;软件中断使用较少,简单起见用0填充

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:

 RETE ;外部中断INT0

NOP

NOP

NOP

INT1:

 RETE ;外部中断INT1

NOP 

NOP

NOP

INT2:

 RETE ;外部中断INT2

NOP

NOP

NOP

TINT:

 RETE ;Timer0中断

NOP

NOP

NOP

BRINT0:

 RETE ;McBSP #0 接收中断

NOP

NOP

NOP

BXINT0:

 RETE ;McBSP #0 发送中断

NOP

NOP

NOP

DMAC0:

 RETE ;无定义(默认)DMA0中断

NOP

NOP

NOP

TINT1:

 RETE ;Timer1中断(默认)或DMA1中断.

NOP

NOP

NOP

INT3:

 RETE ;外部中断3

NOP

NOP

NOP

HPINT:

 RETE ;HPI中断

NOP

NOP

NOP

BRINT1:

 RETE ;McBSP #1接收中断(默认)或DMA2中断

NOP

NOP

NOP

BXINT1:

 RETE ;McBSP #1发送中断(默认)或DMA3中断

NOP

NOP

NOP

DMAC4:

 RETE ;DMA4中断

NOP

NOP

NOP

DMAC5:

 RETE ;DMA5中断

.end

在本实验中只要把在开头加上中断子程序标号的引用,并在中断表的TINT部分换成跳转指令就行了:

*******************************************************

*vectors.asm for 方波发生器

*******************************************************

.sect ".vectors" ;开始命名段.vecotrs

.global CodeStart ;引用程序入口的全局符号定义

.global TINT0_ISR ;引用Timer0中断子程序

<节省篇幅,中间省略>

TINT:

 B TINT0_ISR ;Timer0中断

NOP

NOP

BRINT0:

 RETE ;McBSP #0 receive interrupt

<节省篇幅,下略>

技巧提示:

只有第一个中断(Reset中断)是每个程序都应该有的,在不需要其它中断的情况下,可以只用这一部分,后面可以省略。

如果只需要部分中断也可以按需设置,但必须保证所用中断在中断向量表的位置不变。

不熟悉中断向量表的情况下最好还是用这个完整中断向量表样例。

另外C5400系列中不同型号DSP的中断向量数量和在中断向量表中的位置有所不同,程序移植时需要查相应datasheet确认。

2.中断向量指针

中断向量表的位置并没有强制的位置,可以在内部存贮器,也可以在外部存贮器。

但有一个要求:

中断量表必须放在80H字长存贮块的起始处,即中断向量表的首地址的低7位必须全为0。

DSP 

的寄存器PMST的高9位是中断向量表的指针IPTR。

其上电时默认是在FF80H处,这是为了

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1