dspdsp 汇编lOad指令指令怎么实现for(i=0;i<4;i++)这个功能

有人说“真正的音响发烧友是不屑于在汽车内听音乐的因为汽车空间环境决定了不管用什么级别的器材也不可能出好声音”。的确大家都知道的常识就是,由于汽车夲身的局限性无论什么器材,如何改装都很难做到同等层次家用音响的效果只是,随着日益加快节奏的生活步伐对真正的音响发烧伖来说,音乐应该是无处不在的享受我们不可能每天在音响室内正襟危坐地聆听音乐,但又渴望音乐的陶冶尤其是在乏味的车里。于昰对爱车进行汽车音响改装把真正的音响发烧器材搬上爱车,打造出媲美于专业家庭音响系统的专业移动音乐厅不再仅仅局限于室内,也是别有一番趣味

摩雷意蕾603套装喇叭
二手美国来福T0低音炮
二手美国K牌1500.1单路功放

车门隔音是整个隔音工程的关键所在,特别是追求音响效果的汽车门板的隔音工程更是马虎不得。车门隔音让车门变成一个结实的音箱体结构从而提高汽车喇叭在车门上的安装环境,让喇叭的音质效果发挥到最佳状态

车门改装摩雷意蕾603套装中低音喇叭

三角位倒模改装摩雷意蕾603套装中音和高音

座椅底改装战神IDSP-i8HD音频处理器和LP200.4㈣路功放推前声场摩雷意蕾603套装中音和高音

座椅底改装战神LP500.2两路功放推前声场摩雷意蕾603套装中低音喇叭

尾箱隐藏式改装美国K牌1500.1单路功放推尾箱美国来福T0低音炮

尾箱隐藏式改装改装魔立方电容

尾箱改装美国来福T0低音炮

战神IDSP-i8HD音频处理器进行电脑调音

战神地址:广州市白云区鹤龙┅路32号御丰广场1A06铺(广花路国际单位转入106国道往嘉和方向100米)

}

开发 TI 公司的 DSP 芯片肯定要编写或鍺修改 CMD 文件,这是在单片机开发中

没有碰到过的新事物也是学习 DSP的难点。面对里面种类繁多、名称各异、来历不明、

作用不清、功能千差万别的存储器、区域和变量、寄存器初学者往往都会一头雾水。甚

至很多人已经把项目成功地完成了对CMD文件仍然是一知半解。 

笔者吔经历了极度困惑的过程曾经大量地看书,下载资料分析所能搜集到的

CMD源文件。可惜的是无论是TI 公司的原始文档,还是网上的资料或者BBS的帖子,

都没有透彻地说明 CMD 文件的原理和使用只说“然” ,要靠自己去体会“所以然” 去

终于有一天,我悟到了也许只是“┅些” 。现在我把自己的“一些”写下来。

我将细致而通俗地说明 CMD 文件的原理给您“鱼” ,更给您“渔” 一步步地引导象我

当初一樣的初学者。我将以 TI 的 2407 为对象展开说明对于 TI 公司其他型号、其他系

列的 DSP,道理是完全相同的 用时下学术界最最最流行的语式, 叫做“基于 2407”

——这个词起源于英文的“based on” 或“something based” ,被我们大量地引用以

至于令人反胃了——我们美妙、绚烂的语言,现在只剩下“基于”叻 

笔者水平有限,但保证会用心去写您会看到很多别处没有的思路和信息,相信会

基本打通初学者的任督二脉本文适用于那些有单爿机的开发基础、刚开始学习 DSP 的

初学者。如果你还不知道程序空间数据空间这些名词,可能就比较困难了 

在DSP系统中,存在大量的、各式各样的存储器CMD文件所描述的,就是开发

工程师对物理存储器的管理、分配和使用情况 

有必要先复习一下存储器的知识。目前的物理存储器种类繁多,原理、功能、参

论多么复杂从断电后保存数据的能力来看,只有两类:断电后仍然能够保存数据的叫做

非易失性存儲器(non-volatile本文称为ROM 类) ,数据丢失的叫做易失性存储器(本文

称为 RAM 类) ; ROM 类的芯片都是非易失性的 而 RAM 类都是易失性的。 即使同为 ROM类或同為 RAM 类存储器仍然存在速度、读写方法、功耗、成本等诸多方面的差别。比

有没有人这样想过:使用存储器的人希望存在这样的区别吗? 

或者说理想的存储器,应当是什么样的 

我们使用存储器时,如果没有人为地改变它就希望里面的数据永远不要变,即使

断了电也偠完好地保存;如果里面的内容是我不需要的或者不能用的我自然就会给它写

入有用的内容,比如初始化理想的存储器就应当永远保存数据,无论掉电与否而且,

希望读写速度为每秒无穷多字节是 0ns,而不是什么 8ns10ns。——不是吗 

然而,人类实现存储器芯片的技术還没有达到理想情况,所以才会有这么多类别

“非易失”和“速度”就是一对典型的矛盾。非易失的 ROM 类存储器可以“永远”地

保存数據,但读写速度却很低比如30ns;RAM 的速度(8ns)一般都比 ROM(30ns)

快得多,但却不能掉电保存这是很无奈的现实。假如有那么一天ROM 类的读写速喥

和 RAM 一样快,或者RAM 也可以掉电保存数据就不存在易失和非易失的区别了,那将

是革命性的进步那时,智能芯片和智能系统的设计将会囿很大的变化编写 CMD 文件

就会很简单,甚至不需要了 

已经有芯片厂家做了一些这方面的工作,比如把电池和 RAM 结合起来就是一个

能掉电保存的 RAM。它既可以作为传统的ROM 使用又可以当 RAM 使用。但这显然只

是一个暂时、折中的方法其原理、成本、体积、容量还不如人意,不能算是“革命性”

我们平时在用到存储器的时候要考虑哪些因素呢? 

首先必须确认在你的使用场合,是要永久保存数据还是暂时保存?这关系到选

择非易失性还是易失性存储器的大问题,是首要的问题在某些场合,如果必须永远地

保存数据即使希望速度快一些,吔只能选择非易失的 ROM 类存储器而把速度问题放

在其次,或者另外想办法解决;另外一些场合却要把速度放在第一位,只要在通电期间

能够始终保存数据就够了,当然就要选择 RAM 类的存储器了 

这两种情况我们都会遇到:程序代码一般都要存储在ROM 类存储器中,否则从

设備生产开始,储存、运输一直到用户手里,要必备不间断电源还要保证不发生断电

的意外;程序运行的时候,为了提高速度就必须茬RAM 中运行,试想想如果你的 MP4

放电影一停一顿的,谁还会用它看电影呢所以 ROM 和 RAM 都是必不可少的,各有各的用途而且,出于功能、参数、速度、读写方法、功耗、工艺、成本等方面的考虑往

往要同时使用不止一种存储器。 

事实上TI 在设计 DSP芯片时,也遇到同样的问题TI 考慮的情况要比我们更多,

更复杂要知道,设计芯片的人是最牛 X的开发工程师只是跟在人家后面,在人家规定

的框框里亦步亦趋翻开DSP嘚 PDF文档,找到 memory map就会看到芯片上集成了

FIFO 等。就 2407和 2812而言如果是做个流水灯之类的小东东,DSP芯片加晶体加电

源就可以了片上集成的ROM 和RAM,在汸真状态下已经足够用了烧写并脱离仿真器

运行也足够。所以它们的最小系统不需要外扩任何存储器。但也只能做简单的东东往

往還需要外扩一些 ROM 和/或 RAM 存储器,才能委以大用 (顺便说一句,DSP的最小

系统要比 8951芯片的最小系统大得多。 ) 

千万不要被这些存储器的名称所迷惑!翻来覆去其实就是两大类:非易失和易失。

初学者往往忽略了这一点 

两大类!记住这一点,CMD文件就是以这两类存储器为主轴然后展开的。 

DSP芯片的片内存储器 只要没有被TI占用, 用户都可以全权支配 TI设计了 “CMD

文件”这种与用户的接口形式,用户通过编写 CMD 文件来管理、分配系统中的所有物

理存储器和地址空间。CMD文件其实就是用户的“声明” 包括两方面的内容: 

1、用户声明的整个系统里的存儲器资源。无论是 DSP 芯片自带的还是用户外扩

的,凡是可以使用的、需要用到的存储器和空间用户都要一一声明出来:有哪些存储器,

咜们的位置和大小如果有些资源根本用不到,可以视为不存在不必列出来;列出来也

2、用户如何分配这些存储器资源,即关于资源分配情况的声明用户根据自己的

需要,结合芯片的要求把各种数据分配到适当种类、适当特点、适当长度的存储器区域,

用户编写完自巳的程序以后要经过开发环境(编译器)的安排和解释(即编译) ,

转换为芯片可以识别的机器码最后下载到芯片中运行。CMD 文件就是茬编译源程序、

生成机器码的过程中发挥作用的,它作为用户的命令或要求交给开发环境(编译器)

去执行:就这么分配! 

下面将从這两个方面入手,详细说明如何编写 CMD文件 

三、编写CMD文件之——资源清单 如上文所述,CMD 文件包含两大内容首先就是存储器的资源清单,戓者说系

统中(电路板上)可用的存储器资源。 

TI 规定CMD文件的资源清单用关键字“MEMORY”作为标识,具体内容写在后

面的大括号 { } 里面如下媔的形式: 

其中,MEMORYPAGE n,orglength,包括冒号、等于号、花括号都是关键

字符,必不可少 

PAGE n表示把可用的资源空间再划分成几个大块,最多允许汾 256块从PAGE 

“外文类”等。大家都习惯于把PAGE 0作为程序空间把 PAGE 1作为数据空间。如果

你很好奇也可以试试别的数字。凡智能芯片都离不开這两种“空间” ,大名鼎鼎的冯·诺

依曼结构和哈佛结构都是建立在程序空间和数据空间两种结构的基础上,我们面对的

DSP也是如此只偠学习过单片机,就很容易理解如果你构思出第三种结构,恭喜您

您将与这二位齐名了。 

CMD文件中还可以写上注释用“”包围起来,泹不允许用“//” 这一

上面的例子,仅仅就是个“例子” 不针对任何特定的芯片。带注释的语句有两行

每一行都是一项声明,表示在程序空间或数据空间下再细分更小的块,好比是“社科类”

又分了几个书架比如 

表示在程序空间 PAGE 0里面,划分出一个命名为 xxx的小块空间起始地址从存储单元

0x1234 开始, 总长度为 0x5678 个存储单元 地址和长度通常都以十六进制数表示。 所以

地址加长度再减一) ,这一段连续的存儲区域就属于xxx小块了。上面的例子中PAGE 

0和 PGAE 1各包含了只有一个“小块” ,用户可以根据自己的情况按照同样的格式任意

增加。在支持多個CMD文件的开发环境里某个或某几个 CMD文件中, “小块”的数量

可以为 0也就是说,关键字 PAGE 0或 PAGE 1下面可以是空白的。但不允许所有的

CMD 文件的哃一空间都是空白另外,没有资料提到过“小块”数量上限的限制需要去查阅文档或咨询TI 公司。 

很多关键字还允许有别的写法,比洳“org”可以写为“o” “length”可以写为

这个文档不适合初学者。 

实践证明至少对于 C2000 系列的 2407 和 2812 而言,存储单元的单位是“字

要特别注意以下幾点: 

1、必须在DSP芯片的空间分配的架构体系以内分配所有的存储器。这里举两个

a、对于 2407程序空间和数据空间都是从地址 0x0000 到 0xFFFF,最大数

值昰四个 F共 64K 字范围。所以2407 的 CMD文件中不能出现五位数的地址,也不允

许任何一个小块空间的地址范围覆盖到 64K 以外的区域因为2407根本就无法控制这些

区域,或者说不能访问、无法寻址要注意,起始地址和长度不要算错了2812也有同样

b、2407的数据空间里,0xFF 和其他几块区域是 TI 声明嘚保留

空间(Reserved 或 illegal) ,也是芯片无法访问的分配资源的时候不能涉及到这些区域。

同样地2812的程序空间和数据空间,都有大片的保留区域不能使用。 

2、每个小块的空间必须是一片连续的区域。因为编译器在使用这块区域的时

候,默认它是连续的而且每个存储单元都昰可用的。 

3、同一空间下面任何两个小块之间,不能有任何的相互覆盖和重叠 

在外扩存储器时, 要保证片外的存储空间之间 特别是爿外与片内的存储空间之间,

不要发生冲突有些空间,已经被 DSP 芯片的内部存储器占用了用户是不可更改的,

或只能通过模式配置在┅定范围内改动,用户自行扩展存储器时要避开这些地方。 

4、用户所声明的空间划分情况必须与用户电路板的实际情况相符合! 

对于鼡户自制的电路板,这是很容易出错的地方通常会出现两种错误: 

a、在设计硬件电路的时候,通常用 CPLD 作为片外存储器的选通信号用

verilog 或鍺 VHDL 进行编程;也有用 74 或 4000 系列芯片来搭建的,已经很少了如果

CPLD 逻辑出错,或者逻辑并没有真正写入 CPLD 芯片里面即使 CMD 文件是正确的,

即使编譯已经通过在仿真下载或者烧写的时候,PC机都会报错而无法继续操作 

b、 电路板有虚焊的地方, 主要发生在DSP 芯片的管脚、 电平转换芯片嘚管脚及片外存储器的管脚上。这种情况效果等同于上面所说的CPLD 逻辑错误。更要命的是

补焊一次、两次甚至几次,虚焊仍然存在這最容易把人搞糊涂了。笔者就经常遇到这样

出现这些硬件错误时初学者往往不能正确地对故障作出定位,一会儿认为 CMD

文件有问题一會儿觉得硬件电路有问题,反复地折腾最后陷入迷茫。这时一定要保

持清醒的头脑:先检查原理设计;再检查硬件电路板,保证逻辑囸确焊接可靠;最后再

5、一般地,初学者会找一些现成的 CMD 文件来用一点改动都不敢。其实胆

子可以大一些,改一改试一试,没什麼大不了的想学会游泳,必须要下水DSP芯片

上的存储器,只要没有被TI 用作专门的用途用户都可以全权支配。空间的划分是由用

户决萣的,可以根据需要甚至个人的喜好来划分,名称也可以随意起和C语言的变量

这里应当举一个 CMD 文件资源声明的例子,但为时过早资源声明常常与资源分

配是密切相关的,笔者把例子放在下一节与资源分配一起详细说明,效果会好一些 

四、编写CMD文件之——资源分配 

系统资源已经声明完了,现在就要说明用户是如何分配这些存储器资源的,即向

编译器声明资源的分配情况 

要合理地分配存储器资源,首先要搞清一个问题:资源要分配给谁有哪些东东需

要占用存储器? 

我们来看下面这段不严格的C程序: 

这“段”程序只是笔者建立的┅个模型用它来代表几乎所有的程序:哪怕变量(包

括数组)有一千个、一万个,都用一个“i”来代表;哪怕程序主体包含了各种搬移、运算、

逻辑等动作哪怕有一万行那么长,都用一句“i++”来表示 

让我们站在 TI 公司和编译器的角度,来考虑下面的问题:程序经过编译鉯后会

产生哪些对存储器资源有要求的“状况”? 

有单片机开发经验的人都知道至少要产生两种情况: 

1、指令码,即二进制形式的指囹需要占用芯片的“程序空间” 。这些数据完全等价于或等同于用户编写的程序,只是转换成了另一种形式而已这种“数据”有两個特

点:a、只要用户程序编写完成,这些“数据”就已经是可知的、可预期的是由用户编

写的程序代码和编译器共同决定的。b、在系统運行过程中这些数据的内容不会发生任

何变化,只会被读取不会被修改。 

2、在运行过程中动态变化的“量” ,需要占用“数据空间” 上面例子程序中的

变量 i,就属于这种情况这些数据,在设计师编写程序的时候有时会预先写入具体的

数值,即初始化有时甚至根本不需要进行初始化。在运行过程中既要被读取,又会被

改写经常在变化。设计师自己也很难确切知道在某一时刻,这些数据的具体的数值是

什么最多只知道它们的位数、最大和最小值的范围。 

那么什么样的物理存储器适合于数据空间使用,什么样的存储器适匼于程序空间

对于数据空间其最基本、最首要的要求是速度快,并不要求掉电保存数据的能力

显然应当由RAM 类存储器来承担,所以RAM 一般都必不可少。但是并不是说数据空

间只能连接 RAM 芯片,只要你能够接受比较慢的速度并且安排好芯片的控制时序,你

完全可以在数据涳间扩展 ROM 类存储器 

程序空间的代码数据,一般都要求掉电保存只能由 ROM 来承担,所以 ROM 必

不可少那么,ROM 的读取速度慢的问题怎么解决呢?对于有些低速的智能芯片ROM

的速度慢一点,是完全可以接受的可以直接从ROM 中读取代码指令,然后译码、执行;

我们熟悉的 MCS51、PIC 系列单爿机都是这么做的(以下信息笔者不能保证正确性:

2407 脱离仿真器运行时,似乎也是直接从 ROM 中读取程序代码) 另外有一些低端的智

能芯爿,生产商通过特殊的技术手段在一定范围内等效地提高内部程序 ROM 的读取速

LPC213x 的片内 FLASH程序存储器, 与内核之间的接口居然是 128位宽度 通过所谓 “加

速器”相连接。对于高速的智能芯片从 ROM 直接读取代码并执行,已经不能满足速度

的要求了通常的解决方法是,把程序代码储存在 ROM 中在每次上电运行时,通过“引

导程序”把用户代码读出并保存在RAM 中然后从 RAM 中运行,这样做既解决了ROM

速度慢的问题又解决了 RAM 掉電丢失数据的问题。 

实际操作中并不是只有指令码和变量 i 这么简单,除这两项以外还会出现很多

小“状况” ;而且,当芯片型号不同甚至用户源程序不同时,出现的细节也是变化的恰

恰就是这些变化,导致CMD文件变得复杂 

但是,任何大“状况” 、小“状况” 都归屬于对程序空间和数据空间的操作,不存在第三种空间 (有些 DSP 的所谓“IO 空间” ,实质上是数据空间的一个变种但又脱离

了数据空间,鈈属于CMD文件考虑的范围 ) 

编写CMD文件,就是要搞清楚以下情况并对编译器做出声明: 

1、你的系统都有哪些存储器资源? 

2、哪些存储器安排在程序空间哪些在数据空间? 

3、你的系统会产生哪些大“状况”和小“状况” 

4、哪些状况属于程序空间,哪些属于数据空间 

5、程序空间的“状况”如何安排在程序空间的资源里,数据空间的“状况”如何

安排在数据空间的资源里 

笔者想从事情的起源入手,逐步引導初学者自己去发现“资源要分配给谁有哪些

东东需要占用存储器?”这个问题的答案所以使用了一些不正规的术语,比如“状况”

讓我们从一个实际使用过的 2407 芯片的 CMD文件来展开说明 其他 DSP芯片的

下图是 2407芯片的空间分配情况(Memory Map) ,是从 2407的数据手册直接复

#2行至 #8行MEMORY  {……} 部汾,就是上一节我们已经说明的系统可用

#4行所声明的PROG区域,是为用户指令码分配的存储空间这部分空间一般都很大(比如 0x7E00h) 。 

相当于PROG 鼡户指令码区域#3行声明的 VECS 区域是一个特殊的“小状况” ,

TI 在设计 2407 的硬件电路时用这块区域来保存各种中断服务程序的入口地址,即中斷

向量与硬件电路挂钩,不能与一般的程序代码相混杂所以要单独声明。按照芯片手册

元是保留位置在上面的例子中,由于0x0040 ~ 0x0043四个单え暂时无用(reserved)

计也没有问题,因为存放中断服务程序入口地址是编译器根据用户的声明填充的,它会

把有用的地址数据安排到对应嘚单元里至于没用的空间,无论保存了什么样的地址对

于用户都无所谓。另外按手册的说法,用户代码似乎应当从0x0044单元开始(User code 

begins at 0044h) 實际上可以这么做,也可以不这么做只要在芯片的程序空间里,与其他

空间不发生冲突从哪个单元开始都可以,编译器自然会安排仩面的例子就是从0x0100

单元开始存储程序代码。长度也是用户确定的不一定要象例子那样,在 0x7FFF 单元结

笔者自行扩展了一块 SRAM 存储芯片型号为 IS61LV6416,是 ISSI 公司的产品

总容量 64K 字(word) ,通过 CPLD 逻辑电路把一半的容量安排在程序空间的 0x0000

至0x7FFF,覆盖了 PROG和VECS两块区域所谓“安排” ,就是常说的“映射” 仔细

存储器“占用” ,怎么能分配给其他芯片呢再说,程序代码保存到 SRAM 里面掉电岂

不丢失?…… TI 在设计 2407硬件电路的时候给鼡户提供了一个 MP/MC管脚,该管脚

对片内的 FLASH 存储器进行寻址程序空间全部被 FLASH 占用;该管脚接 1 电平时,

片内 FLASH 被隔离只对外接的存储器进行访問。在开发阶段程序代码写入 SRAM,

断电当然就丢失了但这只麻烦开发人员一个人,每次都要重新往SRAM 里写一遍开发

的时候,程序本来就茬变就必须重写;开发成功了,再写入 FLASH 里交付用户。那

么TI 这么做,是否多此一举直接在 FLASH 里开发,不行吗笔者不好妄下结论,估

計是出于以下考虑:a、烧写 FLASH需要特殊的算法即时序,在仿真状态下进行烧写可

能有困难或存在其他问题;b、在FLASH 中运行程序时,难以同時进行仿真;c、FLASH

存储器的烧写寿命有限各位可以结合自己的经验,考虑一下这个问题……总之,TI 设

计了这种方式 在仿真开发阶段, 使用外扩的SRAM存储器 工程师把VECS数据和PROG

数据,通过仿真器和CCS环境的“load program”指令下载到 SRAM 芯片里运行;开发成功以后,再通过TI 提供的专用烧写插件把代码烧到FLASH 存储器的对应空间里,

交付用户使用所以,开发成功以后程序空间外扩的SRAM 芯片也就不需要了,完全可

以删除说不定還能节省一些产品成本呢。 

顺便说一下对于 2407,无论是仿真开发还是脱离仿真最好不要使用0x8000 ~ 

0xFFFF 的高 32K 程序空间,原因有三:a、仿真阶段和脱離仿真器运行时无法使用同

一个 CMD 文件;b、会出现中断不正常的问题,在网上的论坛里经常有人提问;c、最

重要的原因,是笔者的经历曾经搞一个项目,代码量超出了32K需要在高32K空间扩

展程序存储器,咨询 TI 公司后得知必须由 TI 提供特殊的 CCS 文件,而且 TI 不能保证

结果的正确性! 后来笔者只好缩减代码在CMD文件中,有意把片内 FLASH的地址和

片外的 SRAM 地址相重合只需要用跳线改变 MP/MC 管脚的电平, 就能同时避开 a和

b 两个问題何乐而不为呢 ?!在仿真阶段和脱离仿真阶段完全可以使用同一个 CMD

IS61LV6416 的另一半,安排在数据空间下文会进一步说明。至于把IS61LV6416

的低 32K 安排在程序空间、高 32K 安排在数据空间还是正好相反,都无所谓也都是

可以实现的,仅仅CPLD的逻辑不同而已很多人会在这里糊涂半天。 

是 2407芯片内部集成的存储器彼此的地址都不连续,所以要分别声明B0B1块,是由

B0块和B1块合并组成 但二者是有区别的: B1块地址始终固定在数据涳间的 0x0300h ~ 

0x03FF区域,B0块在芯片复位后的默认地址是数据空间的0x0200h ~ 0x02FF区域但

用户可以通过软件设置CNF位,把 B0块转移到程序空间里如果用户需要这样的轉移,

就不能把 B0、B1 合并起来;如果用户不做这样的转移就可以象这个例子一样,B0B1

#8行所声明的区域就是上文所说的 IS61LV6416 芯片的“另一半” 。の所以安排

在数据空间的0x8000 至 0xFFFF 区域原因很简单,因为这里是TI 指定的外扩数据存储

器的位置数据空间的其他位置,基本上都被片内集成的存储器所占用或者被禁用。起

始位置和长度是由用户自己决定的你可以把这片区域分成几个小块来使用,只要相互不

重叠不超出 0x8000 至 0xFFFF 區域,并且修改和增加对应的声明就可以。声明语句

的格式都是一样的另一方面,如果片内的 2K 多的存储器已经够用就不必外扩了,吔

就不再需要#8这一行的声明所以,如果只是用 2407 做个流水灯之类的小东东就不需

要外扩任何存储器,片上的 ROM 和 RAM 资源在仿真状态下已经足够用了,脱离仿真

器运行也足够 #4~#8 五行所声明的空间,都可以进一步拆分如我在前面所说的,是由用户决定

的可以根据需要,甚至個人的喜好来划分但#3 行的 VECS 区域,因为与硬件挂钩的

ExtSRAM这些名称 都允许用户自己来起名, 和C语言的变量名一样; 但在后面 #10 ~ #15

的几行里引用的時候必须使用同样的名称。 

册的说明它能够在同一个“循环”内(in the same cycle) ,同时完成读出和写入;另一

其他材料上 没有进一步的介绍。 峩们可以推断 DARAM 的速度要比 SARAM 快, SARAM

比 SRAM 快但是电路结构的复杂性、实现的成本也与速度成正比关系,所以2407 的

片内DARAM只有544个字,SARAM 却有2K字之大恏了,我们不必知道它们的细节

总线接口、读取方式、写入方式、刷新方式、指标参数,这些是TI 更关心的事我们只要

记住它们的特点:它们都是 RAM 类存储器,掉电要丢失数据的; DARAM 的读写速度最

快SARAM 次之。我们分配资源的时候要考虑这些特点量才适用。 

首先SECTIONS,PAGE包括花括号、冒号,都是关键字符注意:SECTIONS

字符是复数形式。在花括号内每一行最左侧的“.vectors” 、 “.text” 、 “.cinit” 、 “.bss” 、

“.stack”这些名称,包括小数點都是 TI 默认的关键字符,只有“.extdata”是用户自

在 MEMORY 里声明过的资源名称除此以外,有些字符也允许有别的写法参见

这些东西,就是前文所说对存储器资源有要求的“状况” !前面声明的存储器资

源,就是要分配给这些“状况”使用的! 

初次接触这些名称一定会一头雾沝:这些都是什么东西?从哪里冒出来的 

在 TI 的《dsp 汇编lOad指令语言工具指南》里,这些名词统称为“directives” “指令”的意思,

实际上是针对编譯器的“伪指令” 在芯片的指令集里是找不到这些指令的,不要把二者相

规定的关键字(这些定义应当隐含在TI 提供的某个文件中国比洳 .lib 库文件) ,在用户

自己的源程序中一般不能也不需要对这些关键字做定义或声明,只是去引用它们;但

“.extdata”与这些关键字不同是由鼡户自己定义的,下文会进一步说明每条伪指令,

要求编译器在程序空间或数据空间里保留指定数量的存储单元,这些存储单元叫做“sections” 一般翻译为“段” ,与笔者所说的“状况”相对应大家在提到这些伪指令

名词的时候,有时来代表这些指令更多的时候是代表咜们所对应的段。如果使用dsp 汇编lOad指令语

言开发 DSP一定要用到这些伪指令,也会对它们有较深刻的理解 

Sections) 。所谓“已初始化” 具有两个特点:a、只要用户程序编写完成,这些“数据”

就已经是可知的、可预期的是由用户编写的程序代码和编译器共同决定的;b、在系统

运荇过程中,这些数据的内容不会发生任何变化只会被读取,不会被修改下次再通电,

这些数据依然存在显然,指令码就属于“已初始化的” 但“已初始化”并非只包含指令

码,指令码只是“段”的一种而已一般还会有其他的“段” 。所谓“未初始化” 就是上

文所说的, “设计师自己也很难确切知道在某一时刻,这些数据的具体的数值是什么”的

意思上面提到的变量  i 就属于“未初始化的” ,哃样地 “未初始化”还包括其他段。这

里的“初始化” 是从编译器的角度来考虑的,是“可预知、可预期”的意思并不是我们

通常說的,给某个变量赋予初始值的那个“初始化”  

当芯片型号不同,甚至用户源程序不同时编译产生的“段”也是不同的;反之,

产生哪些段是由芯片型号和用户的源程序共同决定的。 

那么我们怎么知道,我的工程项目会产生哪些“段”呢工程项目在编译之后,

会茬项目文件夹内产生一个 .map 文件用随便一个文本编辑器就可以打开,内容也很容

易理解初学者可以先找一个现成的 CMD 文件,稍作修改或者鈈修改加入项目中进行

编译,如果编译失败(failure或error) 则根据提示进行修改,如果只是告警(warning)

(length)非 0 的段就是你的项目真正会产生的段;那些长度为 0 的段,基本都可以从

CMD 文件中删除有时也存在这样的情况:某些长度为 0 的段,即使开发人员并没有在

CMD文件中作出声明仍嘫会在 .map 文件里出现,这对我们的开发并没有影响 

我们仍然通过前面的 CMD 例子,来看这些段都是什么意思为了方便读者理解,

我把说明的順序调整了一下另外,开发过 MCS51 或其他单片机的人应当边看边想,

想想单片机的程序去体会与这些段相对应的东西。 

“.text” 就是编译後生成的二进制指令代码段。我们甚至可以用手工把 C 程序或

dsp 汇编lOad指令程序翻译成二进制指令代码,所以它显然属于“已初始化的”段。我们编写的

main 主函数 “子”函数或子程序,中断服务函数或程序它们都会产生指令代码,也都

属于这个段通过#11 行的声明 

围内。每个函数的代码块的首地址长度等信息,都记录在 .map 文件中至于这些代码

最终写入哪个物理存储器,是片内的FLASH还是片外扩展的程序 SRAM,是由MP/MC

管脚决定的(对于2407芯片) 已经不是CMD文件的责任了。 

 “.vectors” 表示“中断向量段”,也就是中断服务程序的入口地址段很显然,

这个段要求物理存储器必须能够掉电保存数据我们在编写用户程序的时候,普通的函数

件其中的一句声明,把中断服务函数  abc ( ) 与具体的硬件中断對应起来: 

有了这些声明编译器就会把函数abc ( ) 的代码块的首地址,编排到与 int1中断对应的

向量中写入#3行定义的0x0000h ~ 0x0040处,中断向量的地址空间里这个首地址,

编译器当然是知道的所以“.vectors”也属于“已初始化的”段。用户如果想知道中断

服务程序的入口地址只能去查看 .map 文件。對于 2812情况基本相同,不同之处是

“.cinit” 段定义比较模糊,有文章解释为“对全局变量和静态变量初始化的常

数” 按笔者理解,我们经瑺用到的数表比如七段显示器的代码表、液晶的显示字符代码

表、正弦数表等,都属于这个段那么,还包括哪些内容呢笔者也不是佷确定。但有一

点是肯定的:它属于“已初始化的”段必须作为代码,存储在程序空间里而且必须能

“.stack” ,就是我们常说的堆栈我們根本不可能知道堆栈内部数据的变化情况,

所以它属于“未初始化的”段,定位在数据空间在调用函数、保存现场时,一定要用

到這个段但笔者怀疑,还会有其他的用途比如用堆栈来批量交换数据。显然堆栈内

部的数据,没有掉电保存的必要在上面作为例子嘚 CMD文件中,#1行是用户对堆栈空

间的大小所作的声明是按照TI 公司规定的语法,200h表示 512 个单元;如果用户没有

作出#1行的声明编译器将按照默認的数量来分配空间。一般来说如果你无法确定程序

运行究竟需要多大的堆栈,就尽量设置大一点例子中把整个 B0B1 存储器块,都作为堆

棧使用  “.bss” ,定义同样比较模糊但很容易意会。有文章介绍为“保存全局变量和静

态变量” 很显然,它属于“未初始化的”段要萣位在数据空间。前面 C 程序例子中

变量 i 就定位在这里。这个段同样不要求掉电保存数据。 

 “.extdata” 是笔者自行定义的段, 属于 “未初始囮的” 专门用来保存一个 20000

用户设计的,把某些内容从 bss 段里分出来进行特殊定位的方法。具体作法是: 

b、在源程序中包含如下的语句: 

這样用户的声明就完整了,编译器将把数组 xyz[20000] 从 bss 段里分出来单

独定位。所以这个指令的优先级要高于bss。 

我们再来看几个未初始化段的粅理定位: 

这三个段的数据都不需要掉电保存。例子中三个段都定位在数据空间的 RAM 类存储

器中,但分别属于三个不同的物理存储器實际上,你完全可以按照自己的意愿甚至个人

喜好随意地定位,比如把任意一个段定位在任意一个物理存储器里或者把某两个段定

位茬同一个物理存储器里,或者三个段都挤在一个物理存储器里都可以,实际运行起来

都没有任何问题!反正三个存储器都属于数据空间反正谁都可以闲着谁都可以忙起来,

反正爱谁闲着就闲着爱谁忙就忙不需要顾及它们的情绪。当然前提是物理空间够用。

但是想紦 stack 分成几块,分别定位在几个存储器可能是行不通的。bss 也无法分成

两块因为无论你怎么分,剩下的还叫做 bss除非你用前面介绍的方法,把所有的变量

都人工定位然后是什么情况,笔者也不知道了那么,分来配去总要追求点什么意义

才好吧?!前面说过这些存储器的区别主要是速度,能够最大程度提高系统运行速度

才是应当追求的目标。具体该怎么分配就靠读者自己去体味吧。笔者讲一个例孓供读

者参考:前面的数组 xyz[ 20000] ,如果没有对它单独定位它就会被编译器并入bss 段,

bss 段的长度将超过 20000了由于片内存储器的容量都没有这么夶,只能把bss 定位在外扩的 SRAM 中 但是, 笔者又不愿意浪费片内的 SARAM 它的访问速度毕竟要比 SRAM

要快一些,闲着实在可惜所以才把数组从 bss 中分出來,以便给 SARAM 和 SRAM 分

别派上适当的用场 

以上介绍的都是 2407 芯片常见的段,还有几个段比如 “.switch” , “.const”

稍微复杂一些,这里不再详述相信讀者掌握了本文介绍的思想以后,能够很快地理解和

五、DSP系统硬件电路板的故障排查 

自己焊接装配的电路板刚装配完成的时候,一般都會存在各种故障查找故障的

部位,是电子工程师的基本功 

第一步,一个 DSP电路板刚装配完必须先排除电路板的硬故障,比如电流异常

芯片发热,DSP始终处于复位状态振荡器没有起振等。这些故障没有“放之四海而皆准”

的方法每个人遇到的情况都会不一样。一般来說把所有的引脚重新焊一遍,可以解决

第二步看仿真器能否与目标板连接。把PC机与仿真器连接(要保证仿真器已经

正确驱动) 仿真器与目标电路板正确连接,目标板通电这些硬件操作完成后,再启动

CCS(要保证CCS已经按照目标板的芯片型号进行了设置) 几秒种后,如果已经正确连

接在 CCS界面的左下角会出现“目标板已经连接”的提示。当然还有其他的提示方式

比如弹出dsp 汇编lOad指令语言窗口等。如果仿嫃器无法成功与目标板连接就说明目标板上有故障。

据笔者的经验一般是 JTAG 接口的几条线上有短路或断路,数据线、地址线上有短路或

苐三步这时就可以调试我们的程序了。当我们把程序编译完成通过 CCS 开发

平台的“load  program”命令,把代码调入外扩 SRAM的时候经常会遇到错误告警,

说在某地址处出现“校验错误” 这大多是因为地址总线、数据总线,或者控制线的虚焊、

短路引起的主要发生在 DSP 芯片的总线管脚、电平转换芯片的管脚,及片外存储器的

管脚上;或者片选逻辑电路有错误CCS 把代码写入 SRAM 之后,会逐个单元读出与

原始数据进行比较,洳果二者不相同就会提示这样的错误。 

遇到这个问题怎么办呢这里介绍一个用软件去查找硬件故障的方法,非常有效

前面说过,DSP的朂小系统不需要外扩任何存储器其自身的存储器足够运行在仿真器状

态,或脱离仿真器的状态我们可以利用这个特点,把外扩的SRAM或其怹外设都作为

外设来操作,用软件生成一些有规律的波形帮助我们定位故障的部位。具体操作如下: a、编写一段程序向外扩 SRAM的存储單元里,按地址顺序依次写入连续变化

的数据,象下面这段程序: 

这里的0x8000 ~ 0xFFFF是外扩的数据存储器的地址无条件地、反复地运行这

段程序,就会在地址线、数据线上产生连续的方波最低位的 A0 和 D0 的周期最短、频

率最高,A1和D1的周期分别是 A0、D0 的两倍A2、D2是 A1、D1的两倍,依次类推  

b、在 CMD文件中,把这段程序定位在片内程序空间的 RAM 类存储器中而不是

外扩的存储器, 就是前面说的思路: 利用 DSP的最小系统 把外扩 RAM 作为外設来操作。  

c、在仿真状态下全速运行,用示波器检查所有数据总线、地址总线、控制总线

和片选信号的波形顺藤摸瓜,就能查到故障位置 

CMD 文件是开发 DSP 芯片的一个难点。如果站在 TI 公司或者编译器的角度去

考虑问题,对于理解 CMD 文件会有很大的帮助从而更快地掌握 CMD 文件嘚编写。本

文正是按这个思路展开的如果能够对初学者有一些帮助,将是笔者莫大的荣幸 

本文完全是笔者原创的,版权为笔者所有錯误和不足之处,欢迎批评指正:

加载中请稍候......

}

我要回帖

更多关于 dsp汇编指令 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信