dsp 学习心得

如果说前几年DSP作为一个器件,一个处理器或一个事物是相对比较新的东西,那么现在DSP已经在我们电子设计开发中非常常见了。首先我们从定义上简单理解一下DSP。我们涉及到的DSP主要是只这里特指数字信号处理器芯片,这里我把我的一些学习经验和大家分享。希望对大家有帮助

了解DSP

我个人认为学习一个东西首先是了解它,比如DSP到底是什么?用在什么地方?怎么用?和这里我们传统的单片机特点有那些相同与不同?开发需要注意什么?怎么样完成一个最小系统等。我想了解清楚这些问题我们自然就清楚比较清楚的认识DSP了。下面我们就来对上面的问题我们在很多地方都可以找到答案,我把其中比较重要的简单的回答一下。

DSP大家注意和传统的概念区分一下,传统我们经常说的DSP(Digital Signal Processing(数字信号处理))的缩写也就是说是一些功能算法,这里的DSP是指(Digital Signal Process(数字信号处理器))的缩写,也就是说他是一个集成一些外设的一个芯片,类似我们的单片机。我们通过程序实现一些特定的功能。

和传统单片机比较的区别?

DSP功能比普通单片机高出很多,当然价格也比较高。所以直接用DSP和单片机比较是不合适的。我们这里比较不是从他的应用领域来比较,我们是从开发的角度来比较,为了是使那些熟练使用单片机的朋友可以很快上手。当然我的主要目的的大家可以比较学习,达到

熟悉一种CPU其他就可以很快上手。下面从几个方面比较一下

1,硬件上比较

从硬件上比较DSP和传统的单片机主要有几个方面不一样,很多DSP电源系统比传统的复杂,但是这个并不影响我们因为如TI的DSP都提供相关的测试电路。开始的时候大家可以完全按照他来设计。调试方式上有很大不同,DSP一般通过JTAG来进行仿真和烧写的,而单片机是通过直接仿真器来仿真的(这里讲的单片机是比较早的,现在的单片机也有很多采用JTAG调试方式)。其他设计比如重要的时序设计所以CPU系统是一样的只要满足时序就可以达到目标。

2,软件上比较

相比硬件软件应该是DSP差别比较大的DSP的软件需要CMD文件,一般的单片机编译器 编译以后就可以了不需要。并且CMD也是DSP学习过程中比较困难的一个方面。后面我们简单说明一下。

构建DSP最小系统

小系统的是任何DSP系统开发前必须要完成的,你可以从一下几个方面获得小系统。一、购买一个市场上比较成熟的小系统产品;二、自己动手设计一个小系统。我们这里主要告诉大家怎么自己设计一个最小系统。

首先我给最小系统一个定义,我按照我个人的习惯把最小系统分成2个方面

1,狭义的最小系统

所谓狭义最小系统是指就是能够完成一个独立功能,并且方便观察的一个系统。比如我们常见的通过DSP控制一个LCD灯让它闪起来。完成这个功能我们可以认为狭义的最小系统完成。

独立完成功能,我们很容易想到要一个系统能够独立完成功能必须需要的部分应该有电源电路、时钟电路、复位电路。这个和我们单片机基本一样只是在电路设计上注意看手册这个会少出错。其实对于一些DSP来说光是这样是不够的,我们必须要有存储器系统,如果是采用2000系统可以不需要扩展因为他内部自己有FLASH,但是对于5000系统来说就必须扩展非易失性的FLASH等存储器保证系统在掉电重新上电后可以正常工作,所以除了考虑通用单片机的3个方面我们还需要在存储器,BOOTLOADER方面了解DSP,这个也正是大家学习DSP比较困难的地方。

方便观察这个是我自己增加的一个方面,主要是让大家养成良好的习惯,比如我们在设计系统时加一个LED或者蜂鸣器这样在调试的时候会给我们带来很多好处。比如我们设计一个IO操作的程序通过IO输出一个方波,我们可以通过很多方法来观察我们的结果是对好是错。我们可以通过示波器,但是由于很多初学者不一定具备这个条件。如果我们有LED就可以通过他的状态来观察程序运行的结果.

2, 广义的最小系统

广义的最小系统除了具有上面狭义最小系统的功能外还必须具有一个功能可开展性。这个在系统设计中是非常重要的。如果说我们可以设计并完成一个狭义的最小系统就代表我们对DSP已经入门了。那么完成可扩展性功能就代表你可以使用DSP进行系统设计了。

可扩展性在这里我要主要讲的是时序,也就是我们设计的时候必须满足他的时序功能。经常在论坛里面看到大家问我的系统怎么扩展一个存储器或者其他外设。即使有一些参考电路我们怎么判断他的正确与否。这一点正好和我们的单片机系统重合。所以我常常说知道一个CPU怎么用要用一个新的就非常简单了。下面我们就谈谈时序设计需要注意的地方。

一、 首先要熟悉主CPU的时序,也就是说你需要向外设写或者读取一个数据你是采用什么方法的。比如我们的DSP系统的数据手册就专门有一大段内容对外部程序空间、数据空间、IO空间访问的图和说明。

二、 熟悉我们外设对时序的要求,这个很容易理解,你打算读写我总应该知道按照什么样的方法怎么读写吧。一般在手册上也是很清楚的。

三、 当我们清楚DSP和外设的时序后我们来判断他们是不是匹配(简单点说就是可不可以实现数据的读

写功能)如匹配电路设计就是正常的否则我们要想办法让他们匹配。其实这个过程就是电路设计和判断的过程。

关于时序的设计的详细说明几句话说不清楚我们可以在论坛上来一起讨论他是我们数字系统设计的核心。

四、软件最小系统,很多朋友在论坛上说没有一个具体的思路来写DSP程序或者直接是看不懂人家的。其实这些多少没有系统概念造成的。如果我们知道软件最小系统有那几个文件组成。他们主要完成什么功能我们在一个一个的理解和消化他这样不就可以很好的写出程序。比如我们DSP的一个软件系统主要有头文件、库函数、中断向量表、存储器分配文件(CMD)

复杂的CMD文件

CMD文件是DSP学习中初学者遇到的最大的问题,这里我简单说明一下CMD下面是一个2407程序的CMD文件

MEMORY

{

PAGE 0: /* Program Memory */

VECS: org=0000h, len=00040h /* internal FLASH */

FLASH: org=0100h, len=7fffh /* internal FLASH */

PAGE 1: /* Data Memory */

B2: org=00060h, len=00020h /* internal DARAM */

B0: org=00200h, len=00100h /* internal DARAM */

B1: org=00300h, len=00100h /* internal DARAM */

SARAMDATA: org=00800h, len=00800h /* internal SARAM */

EXTDATA: org=08000h, len=08000h /* external SRAM */

}

SECTIONS

{

/* Sections generated by the C-compiler */

.text: > FLASH PAGE 0 /* initialized */

.cinit: > FLASH PAGE 0 /* initialized */

.const: > B0 PAGE 1 /* initialized */

.switch: > FLASH PAGE 0 /* initialized */

.bss: > EXTDATA PAGE 1

.stack: > SARAMDATA PAGE 1 /* uninitialized */

.sysmem: > B0 PAGE 1 /* uninitialized */

/* Sections declared by the user */

.vector: >VECS PAGE 0 /* initialized */

}

CMD文件应该首先清楚他的作用,它是用来把DSP的段进行管理的文件。简单的说就是把一段放在什么地方。

CMD的结构主要分成2个大的方面,1、MEMORY他的主要作用是系统存储器声明也就是说用来描述硬件系统存储器有多少分别在什么地址范围,这样就告诉我们在写MEMORY的时候必须和硬件结合起来。我归纳的原则的对于硬件系统有的存储器在声明的时候不全声明,但是对于物理硬件上没有的存储器一定不能在里面声名。因为这个声明的存储器是为了存放数据准备的,你不存在当然不能声名。

SECTION指令是把相关的段放在存储器的一个位置。大家可以看DSP怎么按照段管理的就很清楚了。特别注意一下中断向量段。

学习应该学会总结和比较

回顾自己使用多种CPU和DSP到现在我觉得最重要的是在学习过程中总结一下自己的得与失。这样才有比较好的进步。

比如我们前面讲到是DSP和单片机的相同与不同点我们只要熟悉单片机并且清楚相同与不同点,我们就知道从那些方面下手这样学习的效率就会提高。

由于我在这方面知识结构的欠缺希望错误和不足的地方大家多多指正。

 

第二篇:dsp学习心得

也是二年级时才开始学DSP的,当时比较着急,因为也感觉什么都不会,不知道从哪里下手。还好的是我们一个同年级的也有同学在做2812,所以向他请教请教,有个人指点一下,比一个人琢磨效率会高很多。

我一开始也是看书,我觉得不错的有两本,一本是《DSP原理与开发》,除了有详细的理论说明之外,还会在每个章节之后配上一个例程,缺点就是错误也不少,估计时间太仓促,校对没做好。另一本书是清华大学出版社的《TMS320C28X系列DSP的CPU与外设》,是从TI的英文的技术手册翻译过来的,分上、下两册,可以作为工具书,很实用,缺点是没有例子。

书看了一两遍,觉得还是一头雾水,就索性开始练习自己写写程序,刚开始都不知道怎么建PROJECT,后来问了同学,然后再看TI的例程,仿照它的程序框架,我还是比较喜欢这种框架的。边看例程,边对着书,看得主要是如何初始化,需要对每个外设进行哪些寄存器的初始化,寄存器为什么这样设置,程序如何进中断,如何出中断等等。边看书边做实验,效率会高很多,也就能慢慢理解了。开始的时候,建议看最简单的例程,对外设一个一个的进行消化。

如果你都不知道看波形的时候该看哪个脚的话,说明两个问题,一是你可能程序还没看明白,都不知道是在EV中的哪些定时器或比较器产生波形,另一个可能就是你对板子不够熟悉,不知道对应的是哪个引脚。前者需要你再看看程序,把它搞清楚了,是用到了哪个定时器,定时器的哪个比较单元,以什么样的方式产生PWM波,周期是多少,占空比是多少等等。。。。如果是后者的话,建议你把板子的原理图拿过来,仔细找一下对应引脚的位置。做实验的时候,不用怕出错,一开始大家都是从不断的出错中走过来的。

有个人指导的话就会轻松很多,但是也不能依赖别人,遇到问题不经思考就去问,要先自己找原因,实在不行了再去请教别人。所以,在学习的过程中需要和大家多交流交流。

其实我学的也不精,但上面是我自己的一些心得和体会,希望能够帮到正在刚刚开始学习DSP的朋友,呵呵。

第一步:获得合适的开发工具

1) 目标板和仿真器

2) 仿真器驱动及FLASH烧写插件(包括相应的flash应用文档)

3) 开发环境CCS

第二步:获得开发的初级软件

1) 下载TI提供的C/C++ Header Files and Examples(因为该文件包含所有的外

设例程和相应的CMD文件)

2) 认真阅读该库中提供的doc文档来调试和弄清楚这些例程

第三步:下载高级的软件及库应用

/mcu/docs/mcuproductcontentnp.tsp?sectionId=95&familyId=916&tabId=2656&DCMP=DSP_C2000&HQS=Tools+OT+c2000getstarted

这里面包含了开始开发的文档以及如MATH 和 DMC 库

第四步:注册MY.TI账号

/mcu/docs/mcuproductcontentnp.tsp?sectionId=95&familyId=916&tabId=2656&DCMP=DSP_C2000&HQS=Tools+OT+c2000getstarted

提供的便利如下:

1) 可以快速的参考你所选择器件的信息

2) TI将最新的产品、技术文档和勘误表发送到注册的EMAIL

3) TI提供最新的创新信息和产品升级

第五步:获得数据手册(这个非常重要,很多设计的参数和设计参考都在这里指出)

每个器件都有各自的数据手册,当然同一个系列的也可以共用一个数据手册。只要详细的阅读数据手册,可以达到中级开发甚至高级开发已经可以了。下面只给出28335的数据手册链接。

/lit/ds/sprs230l/sprs230l.pdf

第五步:自己设计板卡或者购买第三方开发板和仿真器

第三方:和众达,瑞泰,闻停,61IC , HELLODSP 上海三意等

第六步:下载开发的头文件和外设例程(第一步和第二步的细化)

下面给出28335的示例链接:C2833x/C2823x C/C++ Header Files and Peripheral Examples

/docs/toolsw/folders/print/sprc530.html

下载好了,安装之后再下载,相应的文档(安装后也会有文档说明)

第七步:下载相应的FLASH烧写工具及烧写应用文档

/c2000flashtools

在上面的网站上提供每个器件相对应的flash API及烧写工具

/lit/ml/sprb169/sprb169.pdf

这个提供了F28XX FLASH烧写的解决方案

/lit/an/spra958h/spra958h.pdf

提供了从内部FLASH进行编程的应用报告

第八步:运行你的第一个例程

1) 首先从网站上下载相应片子对用的例程,如28335:

/docs/toolsw/folders/print/sprc530.html

2) 下载后默认安装路径就可以了

3) 安装DSP对应的仿真器驱动(若购买第三方仿真器,则会附带提供)

如果没有的可以在此下载/

4) 板子上电并连接仿真器,安装USB驱动

5) 安装好后,大家CCS setup进行DSP片子选择配置,然后保存就行了(第三

方都会提供详细的安装指导教程,在此只做简单引导)

6) 只要第一个程序会了就可以了

注:本指导只给出以下常用的链接,目的在于引导一个新学DSP的人怎么寻找到

自己想要的资料,关于更多详细的设计文档和软件开发库,可以上

上尽心查询。写得很粗糙,望对每个初学者起到一个抛砖引玉的作用,谢谢!!!

手把手教你找寄存器定义

一直就很纳闷,没有一个 向 c8051f410.h的头文件定义特殊功能寄存器,找不见定义,使

用起来就无从下手 ,心里总是不舒坦 ;

从网上看了一些帖子,都说就是在头文件里(我也是这么认为的,肯定要有定义的,不

然无法调用)

StartUp{

………..

……….

GEL_MapAdd(0x3400u,2,0x0400u,1,1); /* GPIO 1KW */

………..

}

这段映射 0x3400u 为 GPIO空间,其实只是表示这段 i/o空间可读可写;

下面是我一步一步地追踪,这些都是要用到的宏定义;

#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) 从一个 ioport Uint16*类型的 地址中

取出 地址内容,就是IODIR寄存器的值了

#define _GPIO_IODIR_ADDR (0x3400u) //定义了IO地址常量 #define _GPIO_IODIR PREG16(_GPIO_IODIR_ADDR) //得到寄存

器的地址

#define _IODIR _GPIO_IODIR 定义了 _IODIR 常量

#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并 #define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)Val

#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)

从这个宏定义开始

1:GPIO_RSET(IODIR,1)

这句很明显了,把IODIR寄存器的值置 1

2:_PREG_SET(GPIO_ADDR(##IODIR),1)

利用这两个宏

#define GPIO_RSET(Reg,Val) _PREG_SET(GPIO_ADDR(##Reg),Val)

#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR

分解的到

a:GPIO_ADDR(IODIR) _GPIO_##Reg##_ADDR

_GPIO_ IODIR _ADDR

b:_PREG_SET(_GPIO_ IODIR _ADDR,1)

3:接下来

#define _PREG_SET(PregAddr, Val) PREG16(PregAddr) = (Uint16)Val

PREG16(_GPIO_ IODIR _ADDR) =1;

4::#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) *

*(_GPIO_ IODIR _ADDR) = 1;

5: 这句就简单了 *(0x3400u) = 1;

一步一步顺藤摸瓜,总算摸到;但我们的问题,还是没讲清楚;

究竟 IODIR 是在哪里定义的呢?

开始我也很迷惑,仔细想想后,惶然大悟,快乐!!

问题出在,这些都是宏语句,执行编译前,就已经把 GPIO_RSET(IODIR,1) 翻译成

*(0x3400u) = 1;

编译器不认识IODIR ,而 IODIR在直到

#define GPIO_ADDR(Reg) _GPIO_##Reg##_ADDR 两个变量合并

前就是个字符串,连个常量都算不上(不知道这么说确切不,完全是因为它在语句的位置,

赋予了它意义)

跟单片机 类比 SFR IODIR = 0X3400;

编译器绕了这么一大圈,其实做得工作太简单了,究竟为什么这么做,我还没来得及想。

总之这个问题已经 很明白了;

我的第二篇了,大家多多支持,给个技术分吗!!呵呵