DSP学习笔记

一、如何开始DSP的学习

以下为各网友学习DSP的一些经验

fxw451:大家先大体上看一遍书,把大体的知识了解一下。其次就是看例子了,例子是关键,例子里有你学的所有的东西,这次你再拿出一本书来看,这次是有针对性的看,比如你做的spi的,你就直接看spi那张,一边看例子一边看书,这样你就可以把一些重要的寄存器给记住了。对于初学者来说,一直好奇的就是ccs的使用,拿我第一次使用ccs来说,当我把ccs 和板子连载一起时,我相当高兴,成功感油然升起,接下来就是用ccs里的看自带的例子了,看完后你就会发现,这些是什么东东哦,什么都不会,这就对了,你要是看一开始看会了你就是神仙了,dsp不像单片机那么容易上手,所以你要花费点功夫吃透它,好东西不是那么容易就可以搞定的。到了自己编程的时候了,这个时候不要要求自己能编一个什么样的程序,你要仿着例子里的东西全部搞定就可以了,这就是你编程的第一步,当然也是成功的一步,在这成功下,我相信你的积极性肯定被调到起来,对dsp越来越热爱了。

suary:1)把存储器映射结构搞清楚----说的具体点就是dsp内到底有那些存储器(ram,rom,flash,etc),这些存储器到底是如何分配的,这个可以参考相关的.cmd文件的写法,它定义了存储器映射和输入输出段的位置

2)编译器的堆栈操作---有关这点我还是没有具体弄清楚,就是中断或是子程序调用时,系统自己的堆栈操作。2407有一个8级硬件堆栈,而2812没有,这个区别比较大,所以在编一边针对堆栈操作的程序(eg. rtos)时就要特别注意了。

3) 中断系统----每个mcu的中断系统搞清楚了,会给编程带来很大的便利,所以一定要对所用的mcu的中断过程了解的清清楚楚。

4)数据结构---设计好的,适合的数据结构会使自己的程序编写变得结构清楚而且“容易”。dsp31:我的经验是:DSP不管是软件和硬件开发一定要多思考,多比较。软件人员一定要会调试和定位硬件电路的问题点。硬件人员一定要考虑接口设计,电平转换,电源稳定性,还有ESD防护等等。

cysmwander:首先得对C熟悉,但会C语言并不能说明你会编程,编程有结构设计的问题,C 语言只是工具,看不懂的就好好去想,想通了就发现自己又上了一个台阶;在学习DSP之前,我觉得应该需要去明白DSP能干什么,所以你一定要先看看DATASHEET,看看DSP的外设和资源,看看你能做啥。开发环境建立完了你要熟悉开发流程,就是说你有一个IDEA,怎么把这个IDEA在目标板上实现,先做什么后做什么,这个一定要想清楚。

这些都准备好了,你就可以开始干了,千万别犹豫,古人说:临渊慕鱼,不如退而结网。千万别怕。一定要立即动手,毫无顾忌,不要想着,这个东西这么复杂,我从哪里动手阿,万事开头难,你就从你认为对的开始做,做错了重头来。我和我们公司新来的同事都说:多动手,烧掉几块板子和几个MCU都是小事,关键是你要动手。

我不建议大家直接拿例程来做试验,因为那样你MCU的结构没有把握,你把例程跑得再好,那也不是你的东西,一定要自己写,例程只能作为参照,一定要一个字母一个字母地去写程序。

yangyansky:1、看书,这是必要的,也是基础。第一遍,不用太详细,不过要让自己大概知道书里都有些什么内容。

2、重点了解2812的片内资源的分配情况,尤其是存储器的映射,知道了这个你就明白了你写的哪部分内容是具体存到哪里去了。掌握bootload的工作原理,知道程序是在哪里,怎么启动的运行的。至于spi、sci这些外设,我觉得等到具体运用的时候再看不迟。结合具体的运用还比较容易理解。

3、看例程,在自己编写自己需要功能的代码时要看看已有的例程,看看例程里的各种寄存器是怎么配置的,配置时又是怎么实现的,根据看懂的编写自己想要的,然后跑跑自己的程序

看和已有的例程有什么异同,是不是自己想要的。当然,调试环节是最难的一个环节,这个过程中会出现很多意想不到的问题,只能慢慢摸索慢慢前进了。

4、重点理解中断、定时器、系统时钟的工作过程,这对程序里的时间分配问题很重要。

5、我觉得写程序要规范,这会简便很多操作,使编译得以优化,比如相关的文件定义要放在相应的头文件里,全局变量等的定义最好放在GlobalVariableDefs.c里,相应的中断程序要放在DefaultIsr.c里,等等。

最后是自己的一些感悟:开发板,仿真器是必要的,它能带给我们更加直观的感受,有空去TI官网转转,里面东西还是挺多的,另外坚持不懈的等待TI--MM拒绝我的芯片申请。。囧......资料书推荐清华的那个《tms320c28x系列dsp的cpu与外设》可当工具书查,还就是一本关于例程详解的,两本配合看。另外一个好的程序模板也是很关键的,TI官网上2812例程,结构严谨并且最大的发挥了CCS的功能,建议先搞懂后再依据此创建自己的模板程序.还有就是芯片的DATASHEET,由于大多数都是英文的看起来比较痛苦,但确都是必须的....想我,四级都还没过来着。关键还是耐心...最后友情提点下谷歌金山词霸。。。我汗...~

二、完整工程的构成

首先那些最基本的仿真驱动安装,CCS配置等我就不在此累赘了...

一个完整工程文件的构成

总的说一个完整的工程需要由库文件(.lib),头文件(.h),源文件(.c)和CMD文件(.CMD)组成,缺一不可。至于各文件内容将在以后中详细说明

2812的库文件--文件夹地址C:\CCStudio_v3.3\C2000\cgtools\lib\rts2800.lib

rts2800_ml.lib --- 大存储器模式

头文件

头文件的作用是定义了2812内部寄存器的数据结构。头文件一般情况下不需要修改,如果你需要定义一些在整个工程内都具有作用域的全局变量的时候,可以在头文件中定义这些变量,具体的方法我们以后在例程或项目实践中应该会有介绍。

C文件(主函数)

ADC.C ——外设AD的初始化函数,与外设AD相关

CodeStartBranch.asm——引导过程中屏蔽看门狗定时器。

DSP28_CpuTimers.C——CPU定时器的初始化和配置函数,与CPU的定时器相关

DefaultIsr_nonBIOS.C——包含了2812所有的中断函数,写中断时,只要将程序写在对应的函数内就可以,大大保证了中断的成功率。

DelayUs.asm——延时微秒

DSP28x_GlobalVariableDefs.C——全局变量的定义,定义了2812的寄存器,中断向量表等内容。Ev.C——外设EV的初始化函数,与外设EV相关。

Gpio.C——GPIO的初始化函数,只和GPIO相关。

Main_nonBIOS.c——主函数

PieCtrl_nonBIOS.C——PIE初始化函数,和中断相关,很重要。

PieVect_nonBIOS.C——PIE中断向量表定义以及初始化,很重要。

SetDBGIER.asm——real time仿真

SysCtrl.C——系统初始化,主要对开门狗,时钟等模块进行初始化,以保证2812正常工作,非常重要。Watchdog.C——看门狗初始化

Xintf.C——外部接口的初始化函数。

通过上面的分析我们可以看到几个文件非常重要,因此大家每次新建工程的时候,就把这些未编辑过的文件复制过来。其他的外设相关的文件,您这个工程中涉及到哪个外设,您就把这个外设相关的源文件复制过来,一起加入工程。

CMD文件

以.CMD为扩展名的文件,这个文件的作用是用来分配存储空间的。由于DSP编译器的编译结果是未定位的,DSP也没有操作系统来定位执行代码,DSP系统的配置需求也不尽相同,因此我们根据实际的需求,自己定义代码的存储位置。打个通俗的比喻,就是我们有一个仓库,现在需要把货物存放到仓库里面去,为了便于日后取用货物,我们将货物分门别类,然后把它们存放到指定的位置去。把哪些货物放到哪个位置的规则,就是我们的CMD文件的内容。

CMD文件又分成两种。一种是分配RAM空间的--微计算机模式(仿真模式)---XMP/MC`=0,用来将程序load到RAM内进行调试,因为我们大部分时间都是在调试程序,所以多用这类CMD,另一种是分配FLASH空间;

微处理器模式---XMP/MC`=1,当程序调试完毕后,需要将其烧写到FLASH内部进行固化,这个时侯我们就需要使用这类CMD文件了。

其中DSP281x_Headers_nonBIOS.cmd---用于分配编译产生的各个段至存储器

F2812_EzDSP_RAM_lnk.cmd ---用于将281x的外设寄存器结构产生的数据段映射至对应的存储器空间以上2个CMD文件均为仿真模式下无BIOS的CMD文件,CMD文件内容将在以后详细解释

第二课课后

1.什么是GEL文件?GEL文件的作用是什么呢?

答:GEL是通用扩展语言(GeneralExte;2.Lib文件内部究竟是什么内容,我们自己能编辑;答:.lib是库文件,rts.lib是TI提供的;我们也可以添加自己的库,可在newproject;

三、CCS的操作;中国有句古话叫“磨刀不误砍柴工”,如果您将CCS;1、CCS的布局和结构;菜单栏——和CCS所有功能相关的菜单都在这里面;编译工具栏——编译程

答:GEL是通用扩展语言(General Extension Language)是一种解释语言,类似于C语言。GEL函数可以用来扩展CC的功能,方便用户调试程序。CCS提供丰富的内嵌GEL函数,用户也可以定义自己的GEL函数。在处理器属性的GEL文件窗内为每个处理器选择用户的GEL文件(扩展名为 .gel) GEL文件用于初始化DSP。GEL在CCS下有一个菜单,可以根据DSP的对象不同,可以用gel来调用一些菜单命令,对DSP的存储器进行配置,设置不同的初始化程序。

2. Lib文件内部究竟是什么内容,我们自己能编辑LIB文件吗

答:.lib是库文件,rts.lib是TI提供的运行时支持库,如果是C代码写的源程序,必须要包含该库。该库由TI公司做好了,放在CCS的\cgtools\lib中,源代码TI网站可以下载。但是我们无法查看.编辑TI所提供的库文件内容

我们也可以添加自己的库,可在newproject中新建

三、CCS的操作

中国有句古话叫“磨刀不误砍柴工”,如果您将CCS这把常用的利刃磨锋利了,那么我相信为您的DSP开发过程节省不少的工夫。

1、CCS的布局和结构

菜单栏——和CCS所有功能相关的菜单都在这里面。

编译工具栏——编译程序时常用的一些工具。

调试工具栏——调试程序时常用的一些工具。

工程文件框——打开的工程所有文件会按类别放在这里

代码编辑区——代码都是在这里编辑完成的了,最主要的工作区域。

编译信息输出区——编译时产生的信息会在这个区域内输出

值得一提的是CC3.3和CCS2.2工具栏的区别,CCS2.2工具栏的图如下面所示,

我们将其和CCS3.3的工具栏比对之后发现CCS2.2中的探针工具已经不在CCS3.3的工具栏中了,这是因为CCS3.3中的断点就包含了探针功能。

2、开始调试程序

在编译完成之后,要来下载程序并进行功能调试。“File”,”Load Program”,在工程文件夹下面的Debug文件夹下,选中**.out文件,点击打开,便开始下载程序了。将**.out文件下载到目标板上2812的RAM中。

注意,这里是调试,所以将程序下载到RAM。等到最后您要固化程序的时候,就得下载到F LASH了,因为断电之后,RAM里面所有的数据都会消失。

调试程序常用的一些按钮:

Run和Animate的区别,Run是如果遇到断点的话它就停下来了。而Animate就算遇到断点时先停止DSP内核,刷新窗口,然后接着继续启动运行,常用来连续刷新变量窗口和生成graph 图形等。

(1)如何添加断点

我们调试代码时有时候想看看某一行或者某几行代码是否有执行,或者想看看执行前后变量的一些变化,那么我们就需要在这行或者这几行代码前加上断点了。加上断点的方法很简单,只要在该行代码前双击就行。双击之后,这行代码前面会出现一个红色圆块。另外一种添加断点的方法,就是在刚才的编译工具栏上,点一下那个小手图形的按钮,前提是你要把光标移动到想要设置断点的哪一行上。这时运行Run按钮,程序就会在断点处停下,黄色的小箭头又出现了。

那如何取消断点呢,在刚刚设置断点的那行再双击一下,代表断点的红色标记就消失了,断点也就被取消了。如果想要清除文件内的所有断点,那么我们可以按一下刚才小手按钮旁边的那个打了叉叉的小手按钮“Debug:Remove all breakpoints”。

(2)单步调试

让我们来了解一下CCS给我们提供的调试工具吧。调试工具栏上分两类,一类是用于在源代码中调试的,另一类是用于在汇编代码中调试的。

---Source-single step 源代码单步调试了,就是按一下,走一步的模式。

---Source-step over 这个按钮是指在单步执行时,如果在函数内遇到子函数,那么不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。

---Source-step out 当单步执行到子函数内时,用step out就可以执行完子函数余下部分,并返回到上一层函数。

用于汇编调试的两个工具Assembly-single step和Assembly-step over含义和上面源文件调试的两个类似,就不再重复叙述了。

(3)使用watch window

Watch window的作用是来观察程序运行过程中的各个变量的值。调用watch window的方法是点击菜单栏的"View ","watch window",这时watch window就会显示在CCS下方的信息区域,如下图所示:

如果想观察某个特定的变量,在代码中选中这个变量,然后右键"Add to watch window"

(4)其他一些

我们在调试程序的时候经常想让程序从Main函数开始运行,点击"Debug"--"Go main"。既能看到源文件中代码的执行情况,又能看到汇编指令的执行情况----"View","Mixed Source/ Asm"

我们看到,每一行源代码下面就会有相应的汇编代码,黄色的指针指示源代码,绿色的指针指示汇编代码。如果要取消源代码和汇编代码在一个文件内的话,重复刚才的操作就可以了。

3、统计代码运行时间

在CCS3.3中如何统计代码的运行时间,首先,将代码的阅览模式设置成前面的源码和汇编同时显示的模式。

点击"Profile"--"Clock"--"Enable",来使能CLOCK功能。接下来点击"Profile"--"Cloc k"--"View",在CCS最下面会出现一个类似于秒表的工具,旁边显示数字“0”。

我们关注main函数这一块,在代码“int*in;这时,底下的CLOCK工具开始显示的是753,当;统计汇编指令的执行时间,点击一下Assembly;第三课课后:如何使用CCS3.3来显示图表?;CCS3.3的探针功能使用:首先设置断点,点击b;选择"Action"下的&q;出现并设置以下窗口;同时我们还可看到;形的输出然后就是选择图形菜

我们关注main函数这一块,在代码“int *input = &inp_buffer[0];”前面设置断点,然后点击Run,这样程序就会停在这一行代码前面,而且黄色指针指示源码,绿色指针指向汇编。

这时,底下的CLOCK工具开始显示的是753,当然不同的环境显示的数字应该是不一样的。这就是从开始执行到这一语句所花的时间了,那753的单位是“CPU Cycles”,CPU的时钟周期。

统计汇编指令的执行时间,点击一下Assembly-single step。汇编指令下移一行,CLOCK工具显示754,也就是刚才这句代码执行了1个CC。统计执行一段代码所花的时间,在需要统计的那段代码开始和结束的地方分别设置断点,如下图所示。

第三课课后:如何使用CCS3.3来显示图表?

CCS3.3的探针功能使用:首先设置断点,点击breakpoint manager按钮(中间有个红色圆),出现窗口

选择"Action"下的"read from File"

出现并设置以下窗口

同时我们还可看到

形的输出然后就是选择图形菜单观察了

。这个是用来控制数据输入的停止和开始,便于观测正弦图

设置输入输出地址等参数

点击"Animate"开始仿真,就能看到我们想要的图像了

关于Graph的一些:

Single Time --- 单时域曲线 --- 显示幅度-时间曲线

Dual Time --- 双时域曲线 --- 在显示两条信号的幅度-时间曲线

FFT Mangnitude --- FFT幅度 --- 进行FFT变换,显示幅度-频率曲线

Complex FFT --- 复数FFT --- 对复数的实部和虚部分别进行FFT变换,显示两条信号的幅度--频率曲线

FFT Mangnitude and Phase --- FFT幅度和相位 --- 在显示幅度-频率曲线和相位-频率

曲线

FFT Waterfall --- FFT多帧显示 --- 对数据(实数)进行FFT变换,其幅度-频率曲线构成一帧。这些帧按时间顺序构成FFT多帧显示图

Constellation --- 星座图 --- 显示信号的相位分布

Eye Diagram --- 眼图 --- 显示信号间的干扰情况

Image --- 图像显示 --- 显示YUV或RGB图像

四、F2812的资源

首先解释下TI的DSP型号中各个字母所表示的含义

TMS320F2812是32位的定点DSP,它既具有数字信号的处理能力,又具有强大的事件管理能力和嵌入式控制功能,特别适合用于需要大批量数据处理的测控领域,例如自动化控制、电力电子技术、智能化仪表、电机伺服控制。下面是F2812的内部资源框图。

2812采用了高性能的静态CMOS技术,时钟频率;1、F2812的片内资源;2812有3个32位的C PU定时器,支持动态的改;F2812的片内外设;1.2个事件管理器EVA、EVB;2.2个串行通信接口SCI,标准的UART(SC;3.1个串行外围接口SPI;4.改进的CAN通信ECAN;5.多通道缓冲串行接口McBSP;6.12位的ADC,一共有16个通道

2812采用了高性能的静态CMOS技术,时钟频率可达150MHZ(6.67ns), 其核心电压为1.8V/1. 9V,I/O口电压3.3V,Flash编程电压也为3.3V,所以我们在设计2812电源部分的时候,需要将常用的5V电压转换成1.8V和3.3V的电压之后,才能供给2812。

1、F2812的片内资源

2812有3个32位的CPU定时器,支持动态的改变锁相环的频率,有片内振荡器和看门狗定时器模块。2812具有3个外部中断,但是2812具有外部中断的扩展模块(PIE),它可支持96个外部中断,不过当前仅仅使用了45个外部中断,其他为保留。具有128位的密钥,用于保护FLAS H、OTP和L0、L1中的内容不被盗读。

F2812的片内外设

1. 2个事件管理器EVA、EVB

2. 2个串行通信接口SCI,标准的UART(SCIA SCIB)。

3. 1个串行外围接口SPI。

4. 改进的CAN通信ECAN。

5. 多通道缓冲串行接口McBSP。

6. 12位的ADC,一共有16个通道,实现AD转换的功能

7. 最多有56个可独立编程的,多功能复用的GPIO引脚。

8. XINTF外部扩展接口--异步,非复用的总线结构--用于扩展并口外设

2、地址总线和数据总线

地址总线,这类总线的作用就是来传送存储单元的地址的。

1. PAB (Program Address Bus)程序地址总线,它是一个22位的总线,用于传送程序空间的读写地址。程序运行的时候,假如执行到了某一个指令,那么需要去找到这段代码的地址,就是用PAB来传送。

2. DRAB(Data-Read Address Bus)数据读地址总线,它是个32位的总线,用于传送数据空间的读地址。假如要读取数据空间某一个单元的内容,那么这个单元的地址就是通过DRAB来传送。

3.DWAB(Data-Write Address Bus)数据写地址总线,它也是个32位的总线,用于传送数据空间的写地址。类似的,如果我要对数据空间的某一个单元进行写操作,那么这个单元的地址就是通过DWAB来传送。

数据总线,这类总线传送的就是数据了,也就是单元内的具体内容

1. PRDW(Program-Read Data Bus)程序读数据总线,它是一个32位的总线,用于传送读取程序空间时的指令或者数据。我们在执行代码的时候,首先是通过PAB传送并找到了存放该指令的存储单元,但是这个存储单元下的具体内容就要由我们的PRDW来传送了。

2. DRDB(Data-Read Data Bus)数据读数据总线,它是一个32位的总线,在读取数据空间时用来传送数据。我们在进行读操作时,先通过DRAB总线确定了需要进行读操作的数据单元的地址,接下来传送这个数据单元下面的具体内容时就需要DRDB了。

3. DWDB(Data/Program-Write Data Bus)数据写数据总线,它是一个32位的总线,在进行写操作时,向数据空间/程序空间传送相应的数据。也就是假如我们要对数据空间的某一个单元进行写操作,我们通过DWAB传送了这一个单元的地址,同时我们需要DWDB来传送写入的内容。

3、内部的存储器资源

4、存储器映射

2812具有32位的数据地址和22位的程序地址,总地址空间可以达到4M的数据空间和4M的程序空间。32位的数据地址,就是能访问2的32次,是4G,而22位的程序地址,就是能访问2的22次,是4M。其实,2812可寻址的数据空间最大是4G,但是实际线性地址能达到的只有4M,原因是2812的存储器分配采用的是分页机制,分页机制采用的是形如0xXXXXXXX的线性地址,所以数据空间能寻址的只有4M。

2812的存储器被划分成了下面的几个部分:

1. 程序空间和数据空间。2812所具有的RAM、ROM和FLASH都被统一编址,映射到了程序空间和数据空间,这些空间的作用就是存放指令代码和数据变量。

2. 保留区。数据空间里面某些地址被保留了,作为CPU的仿真寄存器使用,这些地址是不向用户开放的。

3. CPU中断向量。在程序空间里也保留了64个地址作为CPU的32个中断向量。通过CPU寄存器ST1中的VMAP位来将这一段地址映射到程序空间的底部或者顶部。

5、映射和空间的统一编址

F2812内部的映射空间低地址空间

高地址空间

6、2812CMD详解;CMD:command命令,顾名思义就是命令文件;1.)#pragma,CODE_SECTION 和;#pragmaDATA_SECTION(func;将funcA数据块定位于用户自定义的段";2.)MEMORY和SEC TIONS是命令文件中;以常用的F2812_nonBIOS_RAM.cm;CMD文件里有两个基本的段:初始化段

6、2812CMD详解

CMD:command命令,顾名思义就是命令文件指定存储区域的分配.2812的CMD采用的是分页制,其中PAGE0用于存放程序空间,而PAGE1用于存放数据空间。

1.)#pragma ,CODE_SECTION和DATA_SECTION伪指令

#pragma DATA_SECTION(funcA,"dataA"); ------ 函数外声明

将funcA数据块定位于用户自定义的段"dataA"中 ------ 需要在CMD中指定dataA段的物理地址

2.)MEMORY和SECTIONS是命令文件中最常用的两伪指令。MEMORY伪指令用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。SECTI ONS伪指令是用来描述输入端是如何组合到输出端内的。

以常用的F2812_nonBIOS_RAM.cmd、F2812_nonBIOS_Flash.cmd和DSP281x_Headers_nonBIOS.cm d为例: F2812_nonBIOS_RAM.cmd ----- 用于仿真,无BIOS系统,片外SRAM配置

CMD文件里有两个基本的段:初始化段和非初始化段。初始化段包含代码和常数等必须在DSP上电之后有效的数。故初始化块必须保存在如片内FLASH等非遗失性存储器中,非初始化段中含有在程序运行过程中才向变量内写数据进去,所以非初始化段必须链接到易失性存储器中如RAM。已初始化的段:.text,.cinit,.const,.econst,..pinit和.switch..

.text:所有可以执行的代码和常量

.cinit:全局变量和静态变量的C初始化记录

.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明 .econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明 .pinit:全局构造器(C++)程序列表

.switch:包含switch

声明的列表

非初始化的段:.bss,.ebss,.stack,.sysmem,和esysmem.(更好的理解就是,这些段就是存储空间而已) .bss: 为全局变量和局部变量保留的空间,在程序上电时.cinit空间中的数据复制出来并存储在.bss空间中;

.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.ebss中;

.stack:为系统堆栈保留的空间,用于和函数传递变量或为局部变量分配空间;

.sysmem:为动态存储分配保留的空间。如果有宏函数,此空间被宏函数占用,如果没有的话,此空间保留为0;

.esysmem:为动态存储分配保留的空间。如果有far函数,此空间被相应的占用,如果没有的话,此空间保留为0;

F2812_nonBIOS_Flash.cmd --- 用于无BIOS,从片内FLASH引导

对于程序在FLASH中运行时,需要注意的: DSP在150M时钟频率下,FLASH中只能提供大约12 0M的时钟频率,所以有时候我们希望在RAM中运行时间敏感或计算量很大的子程序(比如AD采样)。但是我们所有代码都放在FLASH中,这就必须在上电后将FLASH中的这段敏感程序复制到RAM中运行,加快速度。这是在.CMD文件就必须划分一段用来设置RAM的载入和运行地址。程序代码如下:

SECTIONS {………

ramfuncs : LOAD = FLASHD,

RUN = RAML0,

LOAD_START(_RamfuncsLoadStart),

LOAD_END(_RamfuncsLoadEnd),

RUN_START(_RamfuncsRunStart),

PAGE = 0}

DSP281x_Headers_nonBIOS.cmd ----- 用于无BIOS,外设寄存器产生的数据段映射至对应的存储器空间

cmd小技巧:

如果.text文件很大将其放在一段放不下,需将其放到两个程序段中

最长的一个length=0x002000,也放不下时.可以这样处理:

PAGE 0 :

PRAMH0 : origin = 0x3F8002, length = 0x0014FE

L0RAM : origin = 0x008000, length = 0x001000

SECTIONS

.text:{*(.text)} >>PRAMH0|L0RAM

这样就可以将.text文件放在两个定义段中。

查看段的分配及使用情况.map的链接器(存储器)分配映射文件,链接器的map文件描述以下内容:通过map文件可以查看各段的分配情况,包括段的起始地址,使用的字节数等配合cmd 文件的使用,可确定各个段的使用情况,从而保证程序的正常运行和最小的空间使用。VisualLinker可视化链接器TI公司出品的DSP软件开发环境CCS还提供了一种可视化生成存储器配置文件的工具:VisualLinker可视化链接器。如果程序原来包含了一个链接器命令文件(.c md文件),则当创建可视化链接文件的时候,原来cmd文件中的内存配置仍然会被使用。如果读者想修改内存配置,双击.rcp文件就会在CCS中打开可视化链接器的图形界面,调整每个内存

模块的大小,直到认为合适,然后只需要重新连编,程序即可生成新的输出文件,重复上面的步骤,直到出现满意的结果。

五、中断系统

什么是中断?

中断(Interrupt)是硬件和软件驱动事件,它使得CPU暂停当前的主程序,并转而去执行一个中断服务程序。

1、F2812的中断系统

2812的CPU能够支持一个不可屏蔽中断NMI和16个可屏蔽的中断INT1-INT14、RTOSINT和DLO GINT,2812的CPU为了能够及时有效的处理好各个外设的中断请求,设计了一个专门处理外设中断的扩展模块(the Peripheral Interrupt Expansion block),叫做外设中断控制器PIE,它能够对各种中断请求源(例如来自于外设或者其他外部引脚的请求)做出判断以及相应的决策。PIE 可以支持96个不同的中断,这些中断分成了12个组,每个组有8个中断,而且每个组都被反馈到CPU内核的12 条中断线中的某一条上(INT1-INT12)。PIE 目前只使用了96 个终端中的45 个,其他的等待将来的功能扩展。

PIE内部的中断分布图;PIE内部的中断8列12行,总共有96个中断,黄;2812的3级中断机制;2812的中断是3级中断机制,分别是外设级,PI;(1)外设级;假如在程序的执行过程中,某一个外设产生了一个中断;中断外设级总结:;外设中断的屏蔽,需要将与该中断相关的外设寄存中的;外设中断标志位的清除,需要将与该中断相关的外设寄;清除T1PINT标志位:Eva

PIE内部的中断分布图

PIE内部的中断8列12行,总共有96个中断,黄色部分表示已经使用的中断,例如:查看事件管理器EVA中定时器T1的周期中断T1PINT-------T1PINT在行号为INT2,列号为INTx.4的位置,也就是说T1IPNT对应于INT2,是INT2中的第四个中断。

2812的3级中断机制

2812的中断是3级中断机制,分别是外设级,PIE级以及CPU级,对于某一个具体的外设中断请求,任意一级的不许可,CPU最终都不会执行该外设中断。下面我们将以2812的外设EVA中定时器T1的周期中断T1PINT为例

(1)外设级

假如在程序的执行过程中,某一个外设产生了一个中断事件,那么在这个外设的某个寄存器中与该中断事件相关的中断标志位(IF=Interrupt Flag)被置为1。此时,如果该中断相应的中断使能(IE=Interrupt Flag)已经被置位为1,外设就会向PIE控制器发出一个中断请求。相反的,如果虽然中断事件产生了,相应的中断标志位也被置1了,但是该中断没有被使能(相应的使能位为0),那么外设就不会向PIE发出中断请求,但是值得一提的是,相应的中断标志位会一直保持置位状态,直到用程序清除它为止。当然,在中断标志位保持在1的时候,一旦该中断被使能了,那么外设立马会向PIE发出中断申请。我们用具体的T1PINT来进行进一步的说明。当定时器T1的计数器寄存器T1CNT计数到和T1周期寄存器T1PINT的值匹配时(相等时),就产生了一个T1PINT事件,即T1的周期中断。这时候,事件管理器EVA的中断标志寄存器A(EV AIFRA)中的第7位T1PINT FLAG被置为1,这时候如果EVA的中断屏蔽寄存器A(EVAIMRA)中的第7位T1PINT的使能位是1,则EVA就会向PIE发出中断请求,当然,如果该位的值是0,也就是该中断未被使能(被屏蔽),则EVA不会向PIE发出中断请求,而且EVAIFRA中T1PINT FL

AG位将一直保持为1,除非通过程序将其清除。需要注意的是,不管在什么情况下,外设寄存器中的中断标志位都必须手工清除。

中断外设级总结:

外设中断的屏蔽,需要将与该中断相关的外设寄存中的中断使能位置0;

外设中断标志位的清除,需要将与该中断相关的外设寄存中的中断标志位置1;

清除T1PINT标志位: EvaRegs.EVAIFRA.bit.T1PINT = 1;

中断屏蔽位使能: EvaRegs.EVAIMRA.bit.T1PINT = 1;

(2).PIE级

当外设产生中断事件,相关中断标志位置位,中断使能位使能之后,外设就会把中断请求提交给我们的PIE模块。PIE模块将96个外设和外部引脚的中断进行了分组,每8个中断为1组,一共是12组,分别是PIE1-PIE12。每个组的中断被多路汇集进入1个CPU中断,例如PDPINDA,P DPINDB,XINT1,XINT2,ADCINT,TINT0,WAKEINT这7个中断都在PIE1组内,这些中断都汇集到CP U中断的INT1。和外设级类似的,PIE控制器中的每个组都会有一个中断标志寄存器PIEIFRx 和和中断使能寄存器PIEIERx,当然x=1.....12。每个寄存器的低8位对应于8个外设中断,高8位保留。例如T1PINT对应于PIEIFR2的第4位和PIEIER2的第4位。PIE除了每组具有刚才的PIEIERx,PIEIFRx寄存器之外,还有一个PIEACK寄存器,它的低12位分别对应着12个组,即INT1-INT12,高位保留。假如T1的周期中断被响应了,则PIEACK寄存器的第2位(对应于INT 2)就会被置位,并且一直保持直到手动清除这个标志位。当CPU在响应T1PNT的时候,PIEACK 的第2位一直是1,这时候如果PIE2组内发生其他的外设中断,则暂时不会被PIE响应送给CP U,必须等到PIEACK的第2位被复位之后,如果该中断请求还存在,那么立马由PIE控制块将中

断请求送至CPU。所以,每个外设中断被响应之后,一定要对PIEACK的相关位进行手动服务,否则同组内的其他中断都不会被响应。

中断PIE级总结:

PIE中断的使能,就得将其相应组的使能寄存器PIEIERx的相应位进行置位;

PIE中断的屏蔽,这是和使能相反的操作;

PIE应答寄存器,PIEACK相关位的清除,以使得CPU能够响应同组的其他中断。

将PIE级的中断和外设级的中断相比较之后发现,外设中断的中断标志位是需要手工清除的,而PIE级的中断标志位都是自动置位或者清除的。但是PIE多了一个PIEACK寄存器,同一时间只能放一个中断过去,只有等到这个中断被响应,给PIEACK置位,才能让同组的下一个中断过去,被CPU响应

清除PIE中与T1PINT相关的应答位: PieCtrl.PIEACK.bit.ACK2=1;

使能PIE中断INT2.4(T1PINT中断): PieCtrlRegs.PIEIER2.all=M_INT4; //M_INT4=0x0008 (3)CPU级

CPU也有标志寄存器IFR和使能寄存器IER。当某一个外设中断请求通过PIE发送到CPU时,CP U级中与INTx相关的中断标志位就会被置位。例如,T1的周期中断T1PINT的请求到达CPU这边时,与其相关的INT2的标志位就会被置位。这时候,该标志位就会被所存在IFR中,这时候,C PU不会马上去执行相应的中断,而是等待CPU使能IER寄存器的相关位,并且对CPU寄存器ST 1中的全局中断屏蔽位做适当的使能。如果IER中的相关位被置位了,并且INTM的值为0,则中断就会被CPU响应。在T1PINT里,当IER的第2位即INT2被置位,INTM为0,则CPU就会响应定时器T1的周期中断。 CPU接到了中断的请求,就得暂停正在执行的程序,转而去响应中断程

序,但是此时,它必须得做一些准备工作,以便于执行完中断程序之后回过头来还能找到原来的地方和原来的状态。CPU会将相应的IER和IFR位进行清除,EALLOW也被清除,INTM被置位,就是不能响应其他中断了,CPU向其他中断发出了通知,正在忙,没空来处理你们的请求了,得等到处理完手上的中断之后才能再来处理你们的请求。然后,CPU会存储返回地址并自动保存相关的信息,例如将正在处理的数据放入堆栈等等,做好这些准备工作之后,CPU会从PIE块中取出对应的中断向量ISR,从而转去执行中断子程序。

中断CPU级总结:

CPU级的操作都是自动的,不管是中断标志位(IFR),还是中断的使能位(IER)

2、2812中断程序模板

/****************************************************************** *$ Date: 24/10/ 2009 整理: eyes417 版本:V1.0 $

*FILE :281x_interrupt.c

*TITLE:2812中断函数写法,格式I

*说明:格式I---写在main的源文件中

******************************************************************/

1).先定义中断函数,再给相应的PIE中断赋地址。写在在main.c中

interrupt void eva_timer1_isr(void); //中断函数声明

void main(void)

{

Dsp学习笔记

1GPIO作为通用I/O口使用 a)EALLOW;//防止私自写或覆盖寄存器的内容,加了这句,接下来可以操作寄存器了 b)GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0复用为普通I/O功能 c)GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // 1,设置为输出;0设置为输入 d)EDIS;//加了这句,接下来不可以操作寄存器 注:EALLOW,EDIS总是成对出现 2中断过程(代码以配置SCIB模块的接收中断为例,LSPCLK是37.5MHz)中断共分三级,1,外设级;2,PIE级;3,CPU级;外设级的中断标志必须手动清零; PIE级和CPU级的中断标志位由硬件自动清零。中断响应例程: 第一步,配置中断源,即允许产生什么类型点中断。例如,定时器中断,串口中断,外部中断等。ScibRegs.SCICTL2.bit.RXBKINTENA =1;允许接收中断 第二步,配置PIE(外部中断扩展) a) InitPieCtrl();//初始化Pie控制 b) InitPieVectTable();//初始化Pie向量表控制 c) EALLOW; d) PieVectTable.SCIRXINTB=&scibreceive;//指定中断服务程序地址 e) EDIS; f) PieCtrlRegs.PIECTRL.bit.ENPIE=1;//使能从PIECTRL中读取中断向量 g) PieCtrlRegs.PIEIER9.bit.INTx3=1;//使能SCIB的接收中断 h) IER |= M_INT9;//允许外部中断 i) EINT; j) ERTM; 第三步,中断响应 在中断服务程序里,必须用PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;//清楚中断已响应标识,再写自己等程序代码 3串口配置 InitScibGpio(); scib_echoback_init(); 4AD转换 InitAdc();//允许ADC时钟,带隙和参考电路上电,核中模拟电路上电 AdcRegs.ADCTRL2.all = 0x2000;//ADC模块开始转换 程序在FLASH运行时,需要加如下两句代码:(不知道具体原因) MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); InitFlash();

DSP学习笔记

一、如何开始DSP的学习 以下为各网友学习DSP的一些经验 fxw451:大家先大体上看一遍书,把大体的知识了解一下。其次就是看例子了,例子是关键,例子里有你学的所有的东西,这次你再拿出一本书来看,这次是有针对性的看,比如你做的spi的,你就直接看spi那张,一边看例子一边看书,这样你就可以把一些重要的寄存器给记住了。对于初学者来说,一直好奇的就是ccs的使用,拿我第一次使用ccs来说,当我把ccs 和板子连载一起时,我相当高兴,成功感油然升起,接下来就是用ccs里的看自带的例子了,看完后你就会发现,这些是什么东东哦,什么都不会,这就对了,你要是看一开始看会了你就是神仙了,dsp不像单片机那么容易上手,所以你要花费点功夫吃透它,好东西不是那么容易就可以搞定的。到了自己编程的时候了,这个时候不要要求自己能编一个什么样的程序,你要仿着例子里的东西全部搞定就可以了,这就是你编程的第一步,当然也是成功的一步,在这成功下,我相信你的积极性肯定被调到起来,对dsp越来越热爱了。 suary:1)把存储器映射结构搞清楚----说的具体点就是dsp内到底有那些存储器(ram,rom,flash,etc),这些存储器到底是如何分配的,这个可以参考相关的.cmd文件的写法,它定义了存储器映射和输入输出段的位置 2)编译器的堆栈操作---有关这点我还是没有具体弄清楚,就是中断或是子程序调用时,系统自己的堆栈操作。2407有一个8级硬件堆栈,而2812没有,这个区别比较大,所以在编一边针对堆栈操作的程序(eg. rtos)时就要特别注意了。 3) 中断系统----每个mcu的中断系统搞清楚了,会给编程带来很大的便利,所以一定要对所用的mcu的中断过程了解的清清楚楚。 4)数据结构---设计好的,适合的数据结构会使自己的程序编写变得结构清楚而且“容易”。dsp31:我的经验是:DSP不管是软件和硬件开发一定要多思考,多比较。软件人员一定要会调试和定位硬件电路的问题点。硬件人员一定要考虑接口设计,电平转换,电源稳定性,还有ESD防护等等。 cysmwander:首先得对C熟悉,但会C语言并不能说明你会编程,编程有结构设计的问题,C 语言只是工具,看不懂的就好好去想,想通了就发现自己又上了一个台阶;在学习DSP之前,我觉得应该需要去明白DSP能干什么,所以你一定要先看看DATASHEET,看看DSP的外设和资源,看看你能做啥。开发环境建立完了你要熟悉开发流程,就是说你有一个IDEA,怎么把这个IDEA在目标板上实现,先做什么后做什么,这个一定要想清楚。 这些都准备好了,你就可以开始干了,千万别犹豫,古人说:临渊慕鱼,不如退而结网。千万别怕。一定要立即动手,毫无顾忌,不要想着,这个东西这么复杂,我从哪里动手阿,万事开头难,你就从你认为对的开始做,做错了重头来。我和我们公司新来的同事都说:多动手,烧掉几块板子和几个MCU都是小事,关键是你要动手。 我不建议大家直接拿例程来做试验,因为那样你MCU的结构没有把握,你把例程跑得再好,那也不是你的东西,一定要自己写,例程只能作为参照,一定要一个字母一个字母地去写程序。 yangyansky:1、看书,这是必要的,也是基础。第一遍,不用太详细,不过要让自己大概知道书里都有些什么内容。 2、重点了解2812的片内资源的分配情况,尤其是存储器的映射,知道了这个你就明白了你写的哪部分内容是具体存到哪里去了。掌握bootload的工作原理,知道程序是在哪里,怎么启动的运行的。至于spi、sci这些外设,我觉得等到具体运用的时候再看不迟。结合具体的运用还比较容易理解。 3、看例程,在自己编写自己需要功能的代码时要看看已有的例程,看看例程里的各种寄存器是怎么配置的,配置时又是怎么实现的,根据看懂的编写自己想要的,然后跑跑自己的程序

STM32F4 DSP库学习笔记5-复数FFT的实现方法

STM32F4 DSP库学习笔记5-复数FFT的实现方法 我们会用了ST官方的汇编FFT库,那些库函数在没有带FPU浮点运算的32芯片上也可以用的不错。然后今天我们就用一下F4的DSP库。在该目录下包含了图中所示的源文件 复数FFT函数支持三种数据类型,分别是浮点,Q31和Q15,待会就拿浮点数来做例子。 先介绍下函数:

void arm_cfft_f32( const arm_cfft_instance_f32 * S, float32_t * p1, uint8_t ifftFlag, uint8_t bitReverseFlag); arm_cfft_instance_f32 * S是一个结构体指针这个结构体包含FFT运算的旋转因子和位反转表,就相当于一个常量,我们不用去管它。float32_t * p1,是输入复数数组的地址,长度应该是运算点数的两倍,注意的是输入和输出共用一块缓存 uint8_t ifftFlag,是运算的正反标志ifftFlag=1是反变换。ifftFlag=0是正变换 uint8_t bitReverseFlag,是 flag that enables (bitReverseFlag=1) or disables (bitReverseFlag =0) bit 好,然后就只要这一句话就可以计算复数的FFT正变换 arm_cfft_f32(&arm_cfft_sR_f32_len1024,testInput,0, 1); 计算出结果后,用下面语句就可以求出幅值了; arm_cmplx_mag_f32(testInput, testOutput, 1024); 关于arm_cmplx_mag_f32(testInput, testOutput, 1024),它的原型是: void arm_cmplx_mag_f32( float32_t * pSrc, float32_t * pDst, uint32_t numSamples); 这个函数是求复数的模值 float32_t * pSrc,是输入数组地址 float32_t * pDst,是输出数组地址 uint32_t numSamples是运算点数

DSP学习笔记

DSP学习笔记(1)中断结构及其实现 戎马书生发表于 2006-7-10 18:06:39 一.程序存储器的中断向量区 程序存储器的0000h-003Fh是dsp的中断向量区,只能用于存放中断向量,不能存放主程序代码。 中断向量包括内核中断int1-int6,软件中断int8-int16,软件中断int20-int31,TRAP,和NMI。其中每两个单元存放一条中断向量,而两个单元没有办法处理中断程序,所以一般在此空间有跳转指令跳到中断服务子程序。 二 Dsp特有的两级中断模式 内核中断指CPU接受到的中断信息 可见,对于每一个内核中断(int1-int6),都对应了很多外围中断,DSP是通过一个PIV(外围中断向量)寄存器来判断到底是哪一个外设发出的中断请求。每一个特定的外围中断对应一个唯一的PIV值,当外设发出中断请求时,这个PIV值被DSP自动放入放入PIV寄存器,而程序员可通过软件编程来判断是何种中断并跳到中断子程序。外围中断对应PIV值如下: 三.中断的汇编语言实现方法 .sect "vectors" ;定义主向量段 RSVECT B _c_int0 ;PM 0 复位向量 INT1 B PHANTOM ;PM 2 中断优先级1 INT2 B GISR2 ;PM 4 中断优先级2 INT3 B PHANTOM ;PM 6 中断优先级3 INT4 B PHANTOM ;PM 8 中断优先级4 INT5 B PHANTOM ;PM A 中断优先级5 INT6 B PHANTOM ;PM C 中断优先级6 RESERVED B PHANTOM ;PM E 模拟量输入中断(保留) SW_INT8 B PHANTOM ;PM 10 用户定义软件中断………………………… SW_INT31 B PHANTOM ;PM 3E 用户定义软件中断 ;中断子向量入口定义pvecs .sect “.pvecs” ;定义子向量段 PVECTORS B PHANTOM ;保留0000h B PHANTOM ;保留0001h … B PHANTOM ;保留0026h B T1PINT_ISR ; T1PINT中断 B PHANTOM ;保留0028h … B PHANTOM ;保留0041h ;(主程序略) ;中断程序

STM32F4 DSP库学习笔记9-DSP库函数中IIR滤波器的实现和效果

STM32F4 DSP库学习笔记9-DSP库函数中IIR滤波器的 实现和效果 我们来实际操作STM32F4 DSP库的IIR滤波器。 与IIR滤波器函数有关的源文件如下图所示: STM32F4 DSP库中采用biquad作为一个单元。一个biquad是2阶,n个biquad串联之后就是n阶滤波器。 基本的单元结构如下所示:

我们可以求出一个biquad的差分函数形式是: y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2] Matlab里的计算就是按照上面的式子计算的,但是STM32F4 DSP库里的系数a1,a2是取反的。 下面就介绍如何使用MATLAB设计IIR滤波器。 举个例子,我们要设计一个采样率为1kHz,4阶,截止频率100Hz的巴特沃斯滤波器。 首先和设计FIR滤波器一样,首先在MATLAB命令窗口输入fdatool,调出滤波器设计窗口 按照方框所示设置好参数:

点击Design Filter:

注意红框里面是直接II型,我们要把他改为直接I型。点击Edit->Convert Structure,选择I型:

转化好后,点击File-Export, 第一项选择Coefficient File(ASCII):第一项选择好以后,第二项选择Decimal: 点击Export,保存后生成如下文件: 系数对应如下:

1 2 1 1 -1.3209134308194264 0.63273879288527657 b0 b1 b2 a0 a1 a2 1 2 1 1 -1.0485995763626117 0.29614035756166951 b0 b1 b2 a0 a1 a2 实际使用ARM官方的IIR函数调用的时候要将a1和a2取反。把a0去掉Scale Values表示每个biquad的增益系数。所以最后用STM32计算后,要乘以这两个系数。 设计滤波器系数之后,我们来看STM32的IIR滤波器函数: 主要介绍下arm_biquad_cascade_df1_f32 函数定义如下: void arm_biquad_cascade_df1_f32( const arm_biquad_casd_df1_inst_f32 * S, float32_t * pSrc, float32_t * pDst, uint32_t blockSize) 参数: *S points to an instance of the floating-point Biquad cascade struct ure. *pSrc points to the block of input data. *pDst points to the block of output data. blockSize number of samples to process per call. 介绍下结构体arm_biquad_casd_df1_inst_f32 typedef struct { //< number of 2nd order stages in the filter. Overall order is 2*numStages . uint32_t numStages; //< Points to the array of state coefficients. The array is of length 4*numS tages. float32_t *pState; //< Points to the array of coefficients. The array is of length 5*numStage s. float32_t *pCoeffs; } arm_biquad_casd_df1_inst_f32; 注意下:pState指向的数组长度是4倍numStages长度 pCoeffs指向的数组长度是5倍numStages长度,a0默认为1,不需要放入 numStages表示biquad个数; 好,接下来我们就可以使用这个函数了 #define numStages 2 #define TEST_LENGTH_SAMPLES 1024 float32_t testInput_f32[TEST_LENGTH_SAMPLES]; float32_t testOutput[TEST_LENGTH_SAMPLES]; float32_t IIRStateF32[4*numStages];

dsp实验报告-有限脉冲响应滤波器(FIR)实验

实验四.数字信号处理算法实验 实验4.1 :有限脉冲响应滤波器(FIR )算法实验 一.实验目的 1.掌握窗函数法设计FIR 滤波器的Matlab 实现,为CCS 提供滤波系数。 2.掌握采用C 语言在VC5509开发板上实现混频信号的FIR 滤波。 二.实验设备 计算机,ICETEK-VC5509-A 实验箱及电源。 三.实验原理 1. 窗函数法设计FIR 滤波器(详细理论请看《数字信号处理》原理书籍) 本实验要求: 设计一个低通滤波器,通带截止频率fp=10kHz ,阻带截止频率fs1=22kHz ,阻带衰减ap=75dB ,采样频率fs=50kHz,计算出滤波系数fHn,并对混频信号(高频+低频正弦波)fIn 进行滤波,得输出波形fOut 。 解:过渡带宽度=fs1-fp=12kHz ;截止频率:f1=fp+(过渡带宽度)/2=16kHz f1对应的数字频率:Ω1=2πf1/fs=0.64π(rad) -理想低通滤波器单位脉冲响应: hd[n]=sin(0.64π(n-a))/(π(n-a)) 其中a=(N-1)/2 (n=0~N-1) -根据阻带衰减要求选择布莱克曼窗,窗函数长度N 为: N=5.98fs/过渡带宽度≈25 则窗函数为:w[n]=0.42-0.5cos(2πn/24)+0.08cos(4πn/24) 滤波器脉冲响应为: h[n]=hd[n]w[n] (n=0~N-1) <1> -根据上面各式计算出h[n]。 2. FIR 滤波 FIR 滤波器的差分方程为:1 ()()N i i y n h x n i -== -∑ <2> 其中,h i ----滤波器系数;x(n)---滤波器的输入;y(n)--- 滤波输出。 根据公式<1><2>,得本例对应FIR 滤波器的差分方程为: y[n]=-0.001x[n-2]-0.002x[n-3]-0.002x[n-4]+0.01x[n-5] -0.009x[n-6]-0.018x[n-7]-0.049x[n-8]-0.02x[n-9] +0.11x[n-10]+0.28x[n-11]+0.64x[n-12] +0.28x[n-13]-0.11x[n-14]-0.02x[n-15] +0.049x[n-16]-0.018x[n-17]-0.009x[n-18]+0.01x[n-19] -0.002x[n-20]-0.002x[n-21]+0.001x[n-22] (n=0,1,2,...) 采用线性缓冲区法(原理见备课笔记)解此差分方程,得FIR 滤波结果y(n)。 3.程序流程图:

TMS320F28335学习笔记-时钟

TMS320F28335学习笔记-时钟 1.系统时钟概述 整个时钟电路的原理框图如图所示。 图1时钟电路的原理框图 在使用有源晶振作为外部的时钟源时,DSP片内的晶体振荡电路会被 旁路,外部的时钟信号有某CLKIN管脚输入DSP。看门狗定时器取OSCCLK 信号作为其输入。C28某的内核会将输入的CLKIN信号转换为SYSCLKOUT 信号(这就是通常我们提到的那些150MHz的信号)。SYSCLKOUT主要用 来为DSP片上的一些外设提供时钟信号。按照外设的速率,一般分为需要 高速时钟信号HSPCLK(顾名思义即highpeedperipheralclock)的外设, 如EPWM、ADC等等;以及仅需要较低的信号频率LSPCLK(顾名思义即lowpeedperipheralclock)的外设,主要是一些串行设备,如SCI、SPI、I2C、McBSP等。HSPCLK与LSPCLK都是通过对SYSCLKOUT进行分配得到的,主要是通过配置寄存器的控制位实现不同的分频因子。举例如下:HSPCLK/LSPCLK000001010011100外设时钟频率SYSCLKOUTSYSCLKOUT/2SYSCLKOUT/4SYSCLKOUT/6SYSCLKOUT/8101110111SY SCLKOUT/10SYSCLKOUT/12SYSCLKOUT/14HSPCLK的上电默认值是SYSCLKOUT/2,即在SYSCLKOUT为150MHz的情况下,HSPCLK默认为75MHz,所以如果想让外设工作在最高频率下一定不能忘了设置这些位。此外,如 果没有正确配置的话,那外设里面的定时器,如PWM定时器的周期都将与 预想的产生倍数倍的错位。LSPCLK的默认值则为SYSCLKOUT/4。 在SyCtrlReg.PCLKCR0、SyCtrlReg.PCLKCR1、SyCtrlReg.PCLKCR3寄 存器中,有对各个外设时钟信号的单独的使能控制。比如,我们禁止掉

DSP原理与应用技术教学设计

DSP原理与应用技术教学设计 1. 前言 数字信号处理(DSP)是指对数字信号进行变换、分析和编码等处理的技术。它广泛应用于音信号处理、图像处理、视频处理等领域。本文将从DSP原理出发,探讨DSP应用技术教学设计。 2. DSP原理 2.1 常见信号变换 DSP信号处理中,常见的信号变换包括傅立叶变换(FFT)、离散余弦变换(DCT)和小波变换(Wavelet Transform)等。其中,傅立叶变换将一个时域信号转换为频域信号,可以表示信号的频率特征;离散余弦变换可以用于图像和音频处理,小波变换则可以处理非平稳信号。 2.2 DSP数字滤波 数字滤波是DSP中的一个重要应用。数字滤波过程包括信号采集、离散化、数字算法处理和数字信号输出等步骤。DSP数字滤波可以用于滤除噪声、滤波信号、改善音质和增强语音等。 2.3 DSP在音频处理中的应用 在音频处理中,DSP技术可以用于混响效果的实现、均衡器的调整、动态范围控制、混音等。同时,可以通过视频中的DSP技术进行视频的亮度、色彩和图像清晰度调整。 3. DSP应用技术教学设计 3.1 课程目标

通过学习本课程,学生应具备掌握DSP的基本原理、DSP数字滤波技术的基本知识、DSP在音频处理中的应用技术等方面的能力。 3.2 教学内容 本课程以DSP原理为基础,介绍了DSP数字滤波、DSP在音频处理中的应用技术等方面的内容。具体包括以下章节: •DSP原理概述 •DSP数字滤波基础 •DSP数字滤波器设计 •DSP音频处理中的应用技术 3.3 教学方法 本课程采用课堂讲解、示范演示、案例分析和实践操作等多种教学方法,使学生能够掌握基本理论知识,掌握相关技术和方法,并能够进行实际操作和应用。 3.4 教学评估 本课程的教学评估主要包括平时评分和期末考试。其中,平时评分主要考核学生的出勤情况、学习笔记和实验报告等;期末考试主要考核学生对课程内容的掌握程度。 4. 总结 DSP技术在现代通信、音频处理、图像处理和视频处理等领域中得到了广泛的应用。通过本课程的学习,应用人员和学生可以全面了解DSP技术的基本原理和应用技术,掌握DSP数字滤波技术、音频处理技术和图像处理技术等方面的知识和能力,提高自身的技能水平和竞争力。

dsp学习心得

dsp学习心得 最近,我开始学习DSP技术,这是一项专业的数字信号处理技术。虽然这项技术对于许多人来说可能还相对陌生,但我认为它 具有巨大的潜力和前途。在学习过程中,我克服了许多挑战,但 我也获得了很多宝贵的经验。下面是我个人的DSP学习心得与大 家分享,希望对大家有所帮助。 一、DSP技术概述 DSP技术是一种专业的数字信号处理技术,它主要应用于音频、视频、雷达、通信、医疗、军事等领域。该技术基于数学算法, 通过数字计算对采集到的模拟信号进行处理,提取出所需的信息。DSP技术的优点包括处理速度快、精度高、可靠性强等。 二、DSP学习要点 1.数学基础 学习DSP技术需要较好的数学基础,特别是离散数学和信号与系统的相关知识。需要了解傅里叶级数、离散傅里叶变换、卷积

等概念和应用。同时,也需要掌握线性代数和微积分等数学基础知识。 2.编程语言 DSP技术的应用离不开编程语言,如C语言、MATLAB等。其中,C语言是最常用的编程语言,掌握好C语言对于学习DSP 非常重要,能够帮助我们深入了解DSP技术的实现原理。 3.实践经验 学习DSP技术需要有实践经验。通过实际操作,能够更好地理解理论知识,并加深对DSP技术的认识。需要有耐心和恒心,多进行实践操作,多总结不同的处理方法和技巧。 三、常见DSP应用场景 1.音频处理

DSP技术在音频处理中具有广泛应用,其主要任务是对音频信 号进行数字处理,以提高音频品质或减少噪声等。 2.图像处理 DSP技术在图像处理中也具有广泛应用,例如对图像进行滤波、检测等操作,可以提高图像的质量和清晰度,应用在运动目标识别、人脸识别等方面。 3.通信处理 通信领域是DSP技术的重要应用领域之一。DSP技术可以对电话、移动通信等进行数字信号处理,可以实现音频压缩、语音识 别等功用。 四、学习中的关键困难点 1.数学知识的差距

TMS320F28335学习笔记-启动过程

TMS320F28335学习笔记-启动过程 分类: DSP TMS320F28335项目研发笔记(11) 版权声明:本文为博主原创文章,未经博主允许不得转载。 1.DSP reset后运行的起始地址是多少? 0x3FFFC0 2.仿真器烧写程序的步骤是? 根据cmd文件把程序烧到指定位置,然后执行。 3.DSP的Flash启动过程是什么? 首先硬件配置GPIO84~87上拉为1,即处于Flash启动过程。当DSP复位后,会从复位向量0x3FFFC0处取得复位向量,并跳转到InitBoot处开始执行,InitBoot会读GPIO84~87的值发现全为1判断为Flash启动方式。然后会跳到0x33FFF6处执行。在CCS5.2工程的cmd文件中有如下代码: MEMORY { PAGE 0 : BEGIN : origin = 0x33FFF6, length = 0x000002 /* Boot to M0 will go here */ ... } SECTIONS {... codestart : > BEGIN PAGE = 0 ...}

即表示把codestart段放到0x33FFF6位置处,文件“DSP2833x_CodeStartBranch.asm”中有codestart段的定义,实际上codestart段只是包含了一个跳转指令,是程序跳转到_c_int00处,_c_int00在boot.asm in RTS library中有定义,_c_int00的代码最终会调用c的main 函数,之后就是main函数的执行。 4.F28335如何烧写代码到flash中并运行? 首先使用添加 C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_common\cmd\F28335.cmd。此文件即为配置代码到flash中的TI官方配置文件。 然后参考 C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_examples_ccsv4\flash_f2833 5。添加以下代码: MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);将一些在内存中运行的代码从flash复制到内存中,然后程序才能正常运行。 5.写好的代码再ram中能正常运行但是烧写到flash中后,函数DSP28x_usDelay()不能正常运行为什么? 因为在DSP2833x_usDelay.asm中有.sect "ramfuncs",即把该函数定义在段"ramfuncs"中,而此段需要在内存中运行,故需要使用函数 MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);将ramfuncs段复制到内存中然后运行。只算以这样设计是因为函数DSP28x_usDelay()精准运行对运行速度有要求故必须放在段"ramfuncs"中。参考: https://www.360docs.net/doc/3919217122.html,/s/blog_9388c4140100vs0r.html 6.cmd中以下代码如何解释? ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0

学习笔记-DFT原理

DFT原理 有时域卷积定理和频域卷积定理,在这里只需要记住两点: 1.在一个域的相乘等于另一个域的卷积; 2.2.与脉冲函数的卷积,在每个脉冲的位置上将产生一个波形的镜像。下面,就用这两条性质来说明DFT,DTFT,DFS,FFT之间的联系: 先看图片:

首先来说图(1)和图(2),对于一个模拟信号,如图(1)所示,要分析它的频率成分,必须变换到频域,这是通过傅立叶变换即FT(Fourier Transform)得到的,于是有了模拟信号的频谱,如图(2);注意1:时域和频域都是连续的! 但是,计算机只能处理数字信号,首先需要将原模拟信号在时域离散化,即在时域对其进行采样,采样脉冲序列如图(3)所示,该采样序列的频谱如图(4),可见它的频谱也是一系列的脉冲。所谓时域采样,就是在时域对信号进行相乘,(1)×(3)后可以得到离散时间信号x[n],如图(5)所示;由前面的性质1,时域的相乘相当于频域的卷积,那么,图(2)与图(4)进行卷积,根据前面的性质2知,会在各个脉冲点处出现镜像,于是得到图(6),它就是图(5)所示离散时间信号x[n]的DTFT(Discrete time Fourier Transform),即离散时间傅立叶变换,这里强调的是“离散时间”四个字。注意2:此时时域是离散的,而频域依然是连续的。 经过上面两个步骤,我们得到的信号依然不能被计算机处理,因为频域既连续,又周期。我们自然就想到,既然时域可以采样,为什么频域不能采样呢?这样不就时域与频域都离散化了吗?没错,接下来对频域在进行采样,频域采样信号的频谱如图(8)所示,它的时域波形如图(7)。现在我们进行频域采样,即频域相乘,图(6)×图(8)得到图(10),那么根据性质1,这次是频域相乘,时域卷积了吧,图(5)和图(7)卷积得到图(9),不出所料的,镜像会呈周期性出现在各个脉冲点处。我们取图(10)周期序列的主值区间,并记为X(k),它就是序列x[n]的DFT(Discrete Fourier Transform),即离散傅立叶变换。可见,DFT只是为了计算机处理方便,在频率域对DTFT进行的采样并截取主值而已。有人可能疑惑,对图(10)进行IDFT,回到时域即图(9),它与原离散信号图(5)所示的x[n]不同呀,它是x[n]的周期性延拓!没错,因此你去查找一个IDFT的定义式,是不是对n的取值区间进行限制了呢?这一限制的含义就是,取该周期延拓序列的主值区间,即可还原x[n]! FFT呢?FFT的提出完全是为了快速计算DFT而已,它的本质就是DFT!我们常用的信号处理软件MATLAB 或者DSP软件包中,包含的算法都是FFT而非DFT。 DFS,是针对时域周期信号提出的,如果对图(9)所示周期延拓信号进行DFS,就会得到图(10),只要截取其主值区间,则与DFT是完全的一一对应的精确关系。这点对照DFS和DFT的定义式也可以轻易的看出。因此DFS与DFT的本质是一样的,只不过描述的方法不同而已。

2812中断使用程序

TMS320F2812学习笔记中断系统及其应用 2812的中断是3级中断机制,分别是外设级,PIE级以及CPU级,对于某一个具体的外设中断请求,任意一级的不许可,CPU最终都不会执行该外设中断。 (1)外设级 外设产生中断时,该中断事件相关的中断标志位(IF)置1。此时,如果该中断相应的中断使能寄存器(IE)也置为1,外设就会向PIE控制器发出一个中断请求。如果外设级中断没有被使能(相应的使能位为0),那么外设就不会向PIE发出中断请求,相应的中断标志位会一直保持置位状态,除非用软件清除。当然,在中断标志位保持在1的时候,一旦该中断被使能了,那么外设立马会向PIE发出中断申请。 注:不管在什么情况下,外设寄存器中的中断标志位必须采用软件进行清除。 小结: 外设中断的屏蔽,需要将与该中断相关的外设寄存中的中断使能位置0; 外设中断标志位的清除,需要将与该中断相关的外设寄存中的中断标志位置1; (2)PIE级 当外设产生中断事件,相关中断标志位置位,中断使能位使能之后,外设就会把中断请求提交给我们的PIE模块。PIE模块将96个外设和外部引脚的中断进行了分组,分为12组,每组8个中断,分别是PIE1-PIE12。每个组的中断被多路汇集进入1个CPU中断,例如P DPINDA,PDPINDB,XINT1,XINT2,ADCINT,TINT0,WAKEINT这7个中断都在PIE1组内,这些中断都汇集到CPU中断的INT1。和外设级类似的,PIE控制器中的每个组都会有一个中断标志寄存器PIEIFRx和和中断使能寄存器PIEIERx,当然x=1.....12。每个寄存器的低8位对应于8个外设中断,高8位保留。 小结: PIE中断的使能。就得将其相应组的使能寄存器PIEIERx的相应位进行置位; PIE中断的屏蔽。这是和使能相反的操作; PIE应答寄存器PIEACK相关位的清除,以使得CPU能够响应同组的其他中断。 PIE级的中断和外设级的中断比较 外设中断的中断标志位是需要软件清除的,而PIE级的中断标志位都是自动置位或者清除的。但是PIE多了一个PIEACK寄存器,同一时间只能放一个中断过去,只有等到这个中断被响应,给PIEACK置位,才能让同组的下一个中断过去,被CPU响应 (3)CPU级 CPU也有标志寄存器IFR和使能寄存器IER。当某一个外设中断请求通过PIE发送到CPU 时,CPU级中与INTx相关的中断标志位就会被置位。例如,T1的周期中断T1PINT的请求到达CPU这边时,与其相关的INT2的标志位就会被置位。这时候,该标志位就会被所存在IFR中,这时候,CPU不会马上去执行相应的中断,而是等待CPU使能IER寄存器的相关位,并且对CPU寄存器ST1中的全局中断屏蔽位做适当的使能。如果IER中的相关位被置位了,并且INTM的值为0,则中断就会被CPU响应。在T1PINT里,当IER的第2位即INT2被置位,INTM为0,则CPU就会响应定时器T1的周期中断。CPU接到了终端的请求,就得暂停正在执行的程序,转而去响应中断程序,但是此时,它必须得做一些准备工作,以便于执行完中断程序之后回过头来还能找到原来的地方和原来的状态。CP U会将相应的IER和IFR位进行清除,EALLOW也被清除,INTM被置位,就是不能响应其他中断了,CPU向其他中断发出了通知,正在忙,没空来处理你们的请求了,得等到处理完手上的中断之后才能再来处理你们的请求。然后,CPU会存储返回地址并自动保存相关的信息,例如将正在处理的数据放入堆栈等等,做好这些准备工作之后,CPU会从PIE 块中取出对应的中断向量ISR,从而转去执行中断子程序。

MSP432学习笔记 -初识开发板和IDE

开箱时里面的介绍:整体布局介绍: 英文版: 翻译版: MSP432P401: 板子上面为仿真电路和功耗测量电路,下面为432主控芯片和外围器件 我用的开发环境是,他的版本号是 (通过

方式查看版本号) MSP432处理器也可以用库函数和寄存器两种方式来编写程序的,库函数是用的最多的方式,我也用库函数的方式来编写MSP432的程序。MSP432P401RLaunchPad包含48MHzARMCortexM4F内核,95uA/MHz 工作功耗和850nARTC操作,14位1MPS差动SARADC和AES256加速器。 评估板包含带有EnergyTrace+技术的板载仿真器,无需其他工具即可进行项目编程和调试,同时还可以测量系统总能耗。 P432P401R处理器特性 低功耗、高性能MSP432P401RMCU 带浮点单元和DSP加速功能的48MHz32位ARMCortexM4F 功耗:95uA/MHz工作功耗和850nARTC待机操作功耗 模拟:24通道14位差动1MSPSSARADC,两个比较器 数字:高级加密标准(AES256)加速器、CRC、DMA、32位硬件乘法器 存储器:256KB闪存、64KBRAM 计时器:4个16位、2个32位 通信:多达4个I2C、8个SPI、4个UART 40引脚BoosterPack连接器,支持20引脚BoosterPack 采用EnergyTrace+技术的板载XDS-110ET仿真器 2个按钮和2个LCD,便于用户交互 反向通道UART通过USB连接到PC 更多关于MSP432的资料:

MSP432处理器可以使用CCS、IAR和keiluVisionIDE来开发 整块电路板的框图: 以电路板上中间的虚线划分为上下两部分,介绍一下上面部分, 上面部分是XDS110-ET仿真器, 评估板也可以外接仿真器,S101开关()来选择板载XDS110仿真器还是用外部仿真器 MSP432P401R与XDS110ET的连接可以断开,MSP432P401R与XDS110-ET除仿真信号之外没有其他通讯连接,仿真信号包括XDS110-ET串行调试信号、应用UART信号和3.3V、5V电源。 下面的图表很清楚的描述了两个区域的连接情况: 信号连接方式描述 5V 跳线USB过来的5V电源 3V3 跳线从XDS110-ET过来的3.3V RTS 跳线UART通道 CTS 跳线UART通道 RXD 跳线接收数据 TXD 跳线发送数据 RST 按键复位MCU TCK-SWCLK 拨动开关串行输入/JTAG输出 注:RTS和CTS为串口通讯时的半双工通信

TMSF精编经验若干

T M S320F28335开发过程中常见问题总结 1.SPI驱动TLE7241E出现返回值不对的问题。主要是由于时序的不对,导致TLE7241E输入采样时数据还没有建立,所以TLE7241E收到的命令不正确,所以返回值不正确。 2.SPI驱动EEPROM时,如果用金属物触到clockpin时,能正确运行,否则不能正确运行。出现次问题也是由于时序的问题,金属物触到clock导致clock出现微小幅度的偏移,导致正好和eeprom的时序对上,而不用金属物触碰时时序不正常,当使dspMOSIpin数据发送提前半个周期后,eeprom 工作正常。 3.示波器有时会导致显示的波形被消尖,所以用示波器测量时周期不能太大。 TMS320F28335笔记-I2C 1.响应和非响应的区别是什么? 关于i2c的响应问题:对于每一个接收设备(从设备,slaver),当它被寻址后,都要求在接收到每一个字节后产生一个响应。因此,themasterdevice必须产生一个额外的时钟脉冲(第九个脉冲)用以和这个响应位相关联。 在这个脉冲期间,发出响应的从设备必须将SDA拉低并在时钟脉冲的高电平期间保持住。这表示该设备给出了一个ACK。如果它不拉低SDA线,就表示不响应(NACK)。

另外,在从机(发送方)发送完最后一个字节后主设备(接收方)必须产生一个不响应位,用以通知从机(发送方)不要再发送信息了,这样从机就知道该将SDA释放了,而后,主机发出一个停止位给slaver。 总结下,i2c通讯中,SDA和SCL都是有主机控制的,从设备只是能够将SDA线拉低而已。对于SCL线,从机是没有任何能力去控制的。从机只能被动跟随SCL 再说的清楚些:主机发送数据到从机的状态下:主机控制SCL信号线和SDA信号线,从机只是在SCL线为高的时候去被动读取SDA线。 主机读取从机的数据:主机来发出时钟信号,从机只是保证在时钟信号为高电平的时候的SDA的状态而已。 SDA和SCL已经通过上拉电阻被上拉,master可以控制(拉低或者释放)这两条线,而slaver只能控制SDA线。当master发送数据时,master会适时地将SDA和SCL拉低或释放(拉高)。确切的时序应该是这样的:当mater 要发送一个start时,mater会将SDA拉低,这就可以了,因为此时的SCL 一定是High。好了,一个start就这样发出去了。而slaver也会发现这个start信号的发生,slaver便会准备好接收接下来的数据了。紧接着,master 要发送一个Byte的数据了,一位一位的发出这8个bits。这时master会先将SCL拉低,然后在SCL为低的状态下将一个bit准备好放到SDA上(比如要发送一个0,master就会通过拉低SDA来放好这个0),然后master会把SCL拉高(释放),此时slaver会立刻检测到SCL的变化,由此聪明的slaver 便知道master已经将要发送的那个bit准备好了,slaver便会在这个SCL 的高电平期间尽快(maser不会等你很久的哦)去读取一下SDA,嗯读到了一个0,slaver就把这个0放到自己的移位寄存器中待后续处理。master会在

DSP学习心得笔记

DSP学习心得笔记 ---------------- 白建成.baijc.icekoor 建立新工程过程中: 问题1: "GPIO_Study.c", line 61: fatal error: could not open source file "DSP280x_Device.h" 1 fatal error detected in the compilation of "GPIO_Study.c". 解决方法: 因为project →build options→compiler→preprocessor中,要包含的头文件的地址没有加进去,你可以找到头文件的地址,然后加进去。 问题2: undefined first referenced symbol in file --------- ---------------- _c_int00 D:\DSP study\test3\Debug\DSP280x_CodeStartBranch.obj FS$$MPY D:\DSP study\test3\Debug\DSP280x_CpuTimers.obj FS$$TOL D:\DSP study\test3\Debug\DSP280x_CpuTimers.obj >> error: symbol referencing errors - './Debug/test3.out' not built 或者下面的问题: undefined first referenced symbol in file --------- ---------------- _c_int00 D:\DSP study\GPIO_Study\Debug\DSP280x_CodeStartBranch.obj >> error: symbol referencing errors - './Debug/GPIO_Study.out' not built 解决办法都是下面: 这个问题是因为没有加在库文件,请在project →build options→linker→libraries 中加入rts2800.lib。 问题3: >> warning: creating .stack section with default size of 400 (hex) words. Use -stack option to change the default size. >> error: can't allocate .stack, size 00000400 (page 1) in RAMM1 (avail: 00000380) >> error: errors in input - ./Debug/GPIO_Study.out not built 解决办法:

相关主题
相关文档
最新文档