dsp编程技巧
① 什么叫高级处理器
你这样的问题我有点难得回答呀,范围太大了,
总体来说CPU现在算高级的就是双核的,更高级的就是4核的了,INTEL有赛扬的双核、有奔腾的双核、有酷睿的双核、又有酷睿2的双核、还有4核,E开头的、T开头的、P开头的等等。AMD的4800+以上的都算高级处理器了,更高的有巴塞罗纳等等
再给你加个:
了解高级处理器特点 提高编码效率
Understanding Advanced Processor Features Promotes Efficient Coding
ADI公司 David Katz,Tomasz Lukasiak与Rick Gentile
如今的数字信号处理器(DSP)在性能、外围设备集成、功耗和成本方面都具备很多优势,很多系统设计人员希望在原有系统设计中利用DSP获得比传统处理器更好的效益。但其中一个潜在障碍就是为应用开发的大量遗留C/C++语言代码。显然,工程师们希望能够在DSP平台上最大程度地利用原有高级语言代码,同时充分利用DSP的结构特点,达到原平台无法企及的高性能。此外,设计人员还需要一个熟悉、直观的程序开发环境和一种简单的方法,用于有选择地进行汇编语言的例行程序。本文将介绍在当前的开发环境下为DSP编程的策略与技巧,其中以ADI公司推出的Blackfin 媒体处理器系列作为示例。
高级语言与汇编语言:两者的结合是最佳办法
在进行一项基于DSP的项目开发时,必然要面临的一个问题就是选择使用何种编程方法。选择的结果通常都是在汇编语言与高级语言如C或C++之间选择其中一种。而在选择过程中往往需要考虑许多其它的因素,因此,在选择之前了解这两种语言的长处与不足是十分重要的。
C/C++的好处包括模块化、可移植性以及可复用性。此外,不仅大多数的嵌入式程序设计员使用过这种高级语言,而且已经存在大量的代码基础,可以通过一种相对简单的方法将这些代码从原来的微控制器或DSP移植到新的DSP平台中。而汇编语言是针对特定体系结构的,因此代码重用仅限于同一系列的处理器。此外,一个系统开发项目组通常划分成不同的开发小组,分别负责不同的系统模块,采用高级语言可以使这些功能交叉的开发小组不必知道各自的处理器平台。
传统的汇编语言因为难懂的语法以及奇怪的首字缩写而长期受到贬低。而现在这些因素在采用称作"代数语法"的结构中已不成什么问题。图1中所给出的示例就是将典型的DSP指令分别以传统的格式和代数格式表示时的对比。从图中可以清楚地看出后者的结构要比前者更加直观。
使用汇编语言编程困难的原因之一,就是它专注于DSP寄存器组、运算单元与存储器之间的数据交流。而在C/C++高级语言中,这一过程通常是通过调用变量、函数以及子程序的方法在一个更加抽象的层面来完成的,因此使得编程更为简单。
如今,C/C++编译器所包含的内容十分丰富,其中许多功能可以完成将高级语言代码编译为严密的汇编语言代码。事实上,编译过程中最好的方法就是通过编译器中的优化程序完成任务。但工具开发人员认为最重要的一系列功能,将影响编译器的性能。因此,高级语言代码不可能在所有方面都超过手工的汇编语言代码。
程序开发人员通常只是在需要优化重要的密集型数据处理代码程序块时才会使用汇编语言,以提高程序在DSP上的运行效率。尽管高级语言编译器在程序优化转换方面做的很好,但在对DSP数据流与运算进行直接、仔细的控制时仍然存在不足之处。这也是许多程序设计员经常将C/C++ 等高级语言与汇编语言结合使用的原因。高级语言在程序控制以及基本的数据处理方面有着不错的表现,而汇编语言则在高效的数学运算与速度最为关键的中断服务例程方面体现出明显的优势。
高效编程的结构特点
汇编程序员要使编写的程序高效运行,就必须要了解DSP与未针对超高速数据处理进行优化的普通处理器的区别。这些结构特点包括:
特殊的寻址方式
硬件循环结构
可缓冲的存储器
单循环执行多个操作
互锁流水线
灵活的数据寄存器文件
这些结构特点可以在提高计算效率方面起到十分大的作用。下面逐个讨论这些特点。
特殊的寻址方式
如果要求处理器在一个单循环中访问多个数据字,那么就需要处理器在地址生成方面具有完全的灵活性。除了在16位与 32位范围内的以DSP为主的访问大小之外,需要使用字节编址的方式才能达到最高效率的数据处理。这一点十分重要,因为在一些通常的应用中,包括许多以视频为基础的系统,都是以8位数据方式工作的。当存储器的访问被局限在单一的范围内时,处理器就需要额外的循环用于屏蔽相关的位。
寻址方式的另一个好处就是采用了"循环缓冲"功能。这一功能必须是由DSP在不借助任何专门软件管理而直接支持的。程序设计员可以利用循环缓冲功能在存储器中定义缓冲区,程序执行时会自动跳过这一段。当缓冲区建立后,也无需专门的软件管理这段数据。地址生成器不仅会处理不一致的跳跃,而且更重要的是它能够如图2中所示具备"环绕式处理程序"功能。如果没有这种自动生成地址的功能,程序员将不得不人工跟踪缓冲区,这样就会浪费大量宝贵的处理周期。
一种基本的、用于高效率信号处理操作(如快速傅立叶变换与离散余弦变换)的寻址方式是位反转技术。单从字面上理解,"位反转"就是要按照二进制地址将位反转。即把最不重要的位与最重要的位进行位置交换。基2蝶形运算所需的数据排序是按照"位反转"的顺序,因此在进行快速傅立叶变换阶段需要用到位反转索引。利用软件可以计算出这些位反转索引,但这种做法的效率十分低。图3中给出的是位反转地址流程示例图。
硬件循环构造
在通信处理算法中,循环是十分关键的功能。对于大多数算法而言,有两种与循环相关的功能可以提高算法的性能。第一种被称之?quot;零开销硬件循环"。利用寻址功能,循环构造通过硬件来实现。当然,这一功能也可以通过软件来实现,此时相关的开销则会影响到实时处理的性能。程序设计员通过"零开销循环"对循环进行初始化,其方法就是建立一个计数值并定义循环范围。处理器将不断地执行这一循环直至达到这一计数值。
大多数DSP都支持"零开销循环",但"硬件循环缓存"能够真正提高循环结构的性能。它们用作存放循环中所执行指令的一个高速缓冲存储器。例如,在循环执行了第一次之后,指令可以暂时存放在循环缓冲器中以备下次使用,从而在整个循环过程中就无需每次重取相同的指令。将循环中的指令存放在一个整个循环过程都能访问到的缓存器中,这样就能极大地节省循环次数。虽然这一功能无需程序设计员另外进行设定,但程序员必须了解缓存器的大小,这样才能正确地选择相应的循环大小。
可缓冲的存储器
标准的数字信号处理器通常都有少量片上高速存储器。微控制器通常能够访问较大的外部存储器。分层式存储器结构则汇集了这两种方法的优点,提供了几种具有不同性能层次的存储器。对于最需要决定的应用,片内的SRAM可以在每个核心时钟周期内完成一次访问。而对于那些代码量更大的系统,则可使用容量更大、等待时间稍长、片上或片外的存储器。
就其本身而言,这种分层式结构的作用只是相对的,因为当今的高速处理器只是以较慢的速度有效地运行,因为大型的应用只配备有速度相对较慢的外部存储器。此外,程序设计员也不得不手工地将重要代码从内置式SRAM中移进移出。然而,如果在结构中增加了用于存放数据与指令的高速缓冲存储器,外存储器就变得更加易于管理了。高速缓存可以减少用手工方式移动指令与数据进出处理器内核的次数。这样程序设计员就无需考虑进入处理器内核数据与指令流程的管理,从而极大地简化了编程模式。
图4是一个标准的存储器配置,其中的指令可以根据需要从外存储器中调入。指令高速缓存通常与一些最近最少使用(LRU)算法一起使用,这样就能够确保那些经常使用的指令取代那些较少使用的指令。从图中可以看出:通过配置象高速缓存这样的片上存储器以及SRAM等存储器,还可以优化处理器的性能。DSP控制器能够直接向内核写入内容,而来自表中的数据则可以根据需要被调入数据高速缓存。
每个循环执行多个操作
处理器的衡量标准通常是每秒所能执行的百万条指令数(MIPS)。然而,对于现在的处理器而言,这一标准则会由于组成每条指令含混的内涵而引起误解。例如,过去因用于高端并行处理器而保留的多事件指令现在仍然用于低成本的定点处理器。在每个核心处理器周期内,除了执行多ALU/MAC操作之外,多余数据的载入与存储操作也可以在同一周期内完成。存储器通常被分成几个子存储空间,这样它就能够被内核或DMA控制器进行双重访问了。正如前面所述的基于硬件的寻址计算中进行的分析那样,在一个单周期内完成多项操作是显而易见的。
图5中描述的是多操作指令示例。如图中所示,在同一个处理器时钟周期内,除了进行两个 MAC 操作之外,还完成了一次取数据和存数据的操作。
互锁流水线
随着处理器的速度不断提高,处理器的处理流水线也应该随着整体性能的提高而不断加深。理解这点十分重要,因为在需要使用汇编语言时,流水线可能会使编程更加具有挑战性。而现在一些处理器已经使用了互锁流水线。这就意味着,在使用汇编语言编程中,程序设计员无需人工安排或跟踪数据与指令的流向,因为这些工作将全部由处理器进行自动处理。
灵活的数据寄存器组
最后,数字信号处理器的另一项功能就是通用数据寄存器组。对于传统的数字信号处理器而言,字长通常是固定的。而如果数据寄存器既能被看作是一个32位字(如R0),也能被看作是两个16位字(R0.L 与 R0.H,分别用于高和低的一半),其优点十分明显。在双MAC系统中,这样就允许在一个时钟周期内进行四个16位数据操作。
编程代码对比与分析
上述介绍的结构框架是DSP高效编程的基础。如果程序设计员能够充分利用处理器的所有功能,许多常见的数学算法可以极为快速的完成。下面挑选出一些常用的算法,并介绍它们在DSP中的用法。需要注意的是,当程序员需要在汇编水平上检查代码的高效性时,如今经优化的DSP编译器同样采用了很多汇编程序设计员使用的规则。下面的示例使用的是Blackfin处理器汇编语言。
标量积
标量积是在测定两个矢量正交性时的一种十分有用的操作。大多数的C语言程序设计员都会对下列这个标量积运用十分熟悉:
short dot(short a[], short b[], int size) {
int i;
int output = 0;
for(i=0; i<size; i++) {
output += (a[i] * b[i]);
}
return output;
下面是汇编语言代码的主体部分:
//P0=loop count, I0 & P1 are address registers
A1 =A0 =0; //A0 & A1 are accumulators
LSETUP(loop1,loop1)LC0 =P0;
//Set up hardware loop starting at label loop1:
loop1: A1 += R1.H * R0.H , A0 += R1.L * R0.L || R1 = [ P1++ ] || R0 = [ I0 ++ ] ;
利用下面介绍的几项数字信号处理器结构功能,将有助于编程。
通过使用硬件循环缓冲器与循环计数器,则无需在每次反复操作结尾时执行跳转指令。 由于标量积是一个累加的和,它是通过一个循环来实现的。为了执行循环中的下一次反复操作,许多RISC微控制器都是在每次反复操作结尾使用一条跳转指令。汇编程序中为LSETUP 指令,这是执行一个循环所需的唯一指令。
多事件指令允许在一个时钟周期内执行指令和两次数据访问。在每次反复操作中,值 a[i] 与 b[i] 都一定会被读取,然后相乘,并最后重新写回到变量输出的运行总和中。在大多数的微控制器平台中,这一过程需要使用四条指令。从汇编语言代码中的最后一行可以看出,这些操作可以在一个时钟周期内完成。
并行ALU操作允许两个16位指令可以同时执行。汇编语言代码表明两个累加单元(A0 与 A1)在每次反复操作中都会被用到。这样就能够将反复操作的次数减少50%,从而有效地将执行时间缩短了一半。
FIR
有限脉冲响应滤波器(FIR)是一个与卷积操作一样常用的滤波器程序结构。简单的C 语言命令与标量积十分相似:
// sample the signal into a circular buffer
x[cur] = sampling_function();
cur = (cur+1)%TAPS; // advance the cur pointer in a circular fashion
// perform the multiply-addition
y = 0;
for (k=0; k<TAPS; k++) {
y += h[k] * x[(cur+k)%TAPS];
}
FIR的核心部分用汇编代码表示出来之后与标量积的格式十分相似。事实上,DSP相同的功能也被用于实现执行算法的最高性能。在本例中,信号采样存贮在寄存器R0中,系数则存贮在寄存器R1中。
// P0 holds # of filter taps
R0=[I0++]||R1=[I1++]; // set initial values for R0 and R1
A1=A0=0; // zero the accumulators
LSETUP(loop1,loop1)LC0 =P0; // configure inner loop
loop1: A1+=R0.L*R1.L, A0+=R0.H*R1.H || R0 = [I0++] ||
R1 = [I1++]; // compute
除了具有上述标量积的功能之外,上例中的FIR算法还使用了循环缓存器。
通过循环缓存器则无需使用明显的模运算。在C语言代码片断中, % (模数)运算符提供了一种用于循环缓冲的机制。如汇编核心程序所示,该模运算符在循环内部并没有转换为一条另外的指令。取而代之的是,数据地址生成寄存器I0 与 I1 在循环外进行了设置,并且自动返回系数缓存器边界的开始位置。
FFT(快速傅立叶变换)
快速傅立叶变换是许多信号处理算法的核心部分。它的特点之一就是输入矢量按照时间顺序排序,而输出矢量则是按照"位反转"的顺序。大多数传统的通用型处理器都要求程序设计员执行一个单独的程序,用于将经位反转的输出矢量复原。在数字信号处理器平台中,位反转已经被设计在寻址部分中了。
在执行快速傅立叶变换过程中,通过位反转寻址则无需使用单独的位反转程序。允许硬件对快速傅立叶变换算法中的输出矢量自动进行位反转,这样程序设计员就不用另外编写应用程序,从而提高了处理器的性能。
除了上述介绍的指令结构之外,象 Blackfin这样的处理器 还另外包括一些专用的指令集用于支持大范围的应用。这些指令的作用是将处理器的处理能力进一步扩展到其它一些算法,如Viterbi, Huffman编码以及许多其它的位处理程序。
至此,可以清楚地认识到:在确定一个基于DSP应用的编程方案时,有许多需要考虑的内容。使用C 或C++ 这类带强大编译器与优化程序功能的高级语言可以快速地开发出各种产品,但使用手工编程的汇编语言则是在处理器以外获取额外性能的最佳方法。当然,采用汇编语言的前提是选择一种在结构上基本支持高效编码的处理器。
② 什么是DSP技术
数字信号处理(Digital Signal
Processing——DSP)强调的是通过专用集成电路芯片,利用数字信号处理理论,在芯片上运行目标程序,实现对信号的某种处理.
数位讯号处理(Digital Signal Processing)是二十一世纪形成科学和工程最具威力的技术之一。在各领域内广泛的范围中已经发生革命性的改变:通讯、医疗影像、雷达和声纳、高保真度(fidelity)音乐重制,和原油探勘,只有这些有被命名。每一个领域的DSP技术都已发展到一定的深度,有它们自个儿的算法、数学和特定的技巧。结合广度与深度使得任何人都不能精通所有已被发展的DSP技术。DSP教育包含二项工作:学习一般可套用于整体的概念,以及对你感兴趣的特定领域学习专业的技巧。本章借由描述DSP已在数个不同领域中造成的戏剧般效应来开启我们进入数位讯号处理(Digital Signal Processing)世界的旅程。革命已经开始了。
DSP的起源(The Roots of DSP)
数位讯号处理不同于其它电脑科学中的领域是由于它使用的资料型别的唯一性:讯号(signals)。在大多情况下,这些讯号起源于现实世界中知觉的(sensory)资料:地震的摆动(seismic vibrations)、视觉影像、声波等……。在讯号已经被转换为数位型式后,DSP是数学、算法和用来处理这些讯号的技术。这包含广泛、多变化的目标,例如:强化视觉影像,辨识和产生对话(语音),为了储存和传送的资料压缩,等……。假设我们加一个“对比到数位的转换器”给电脑,并用它来撷取一部份真实世界的资料。DSP回答了问题:下一步是什么?
DSP的起源是在1960和1970年代,当数位电脑首度变成可用时。电脑在这个时代是很昂贵的,而DSP受限于只有一些关键性的应用。先锋们主要努力于四个关键领域:冒着国际的安全性危险的雷达和声纳,可以赚大把钞票的原油探勘,资料有不可取代性的太空探索和可以救命的医学影像。1980和1990时个人电脑的革命使得DSP新的应用突然遽增。动机并非是由于军事和政府的需求,DSP突然被商业市场驱动了。任何认为他们可以在快速扩大的领域中赚钱的人全都突然变成是DSP的厂商。DSP在这样的产品中变成众所皆知的了:行动电话,CD(compact disc players),和电子语音邮件。图1-1列举了这些应用中的一部份。
此技术革命由上而下发生。在1980早期,DSP在电子电机领域中是在研究所课程中教授的课程。十年后,DSP已经变成大学标准课程的一部份。今日,DSP变成在许多领域中被科学家和工程师需要的基本技巧。以此类推,DSP可以被和之前技术革命中的“电子学(electronics)”相比。虽然仍是电子电机领域,几乎每个科学家和工程师都有些基础电路设计的背景。没有的话,他们可能会迷失在技术的世界中。DSP也有相同的未来。
图1-1
DSP已经在科学与工程的许多领域中发动革命。一些多样化的应用列于此。
近来的历史更是超令人好奇的;它对你学习和使用DSP的能力上有极大的影响。假设你遇到了一个DSP问题,并且转向教科书或其它出版品以寻求答案。你通常找到的是一页又一页的方程式,难解的(obscure)数学符号和不熟悉的术语。这真是场恶梦!即使对那些在此领域中有经验的人而言,许多DSP文献仍令人困惑(baffling)。这并不是在文献上有错,它只是预期要给非常特定的读者群。目前发展中之科技的研究者需要这种复杂(详细)的数学以了解工作的理论的意涵(theoretical implications)。
本书基本的假设是大部份实用的DSP技术可以在没有传统复杂的数学和理论的藩篱下被学习和使用。《科学家和工程师的数位讯号处理指引手册》(《The Scientist and Engineer’s Guide to Digital Signal Processing》)是为了那些想要使用DSP作为工具、而非新的职业的人写的。
本章剩余的部份列举了一些DSP已经产生革命性变革的领域。当你看过每个应用,注意到DSP是非常介于各学科间的(interdisciplinary),依赖于许多相邻领域中的技术性工作。如图1-2所建议的,介于DSP和其它技术学科间的边界并不明显也没有完善的定义,而是模糊和重叠的。如果你想要专攻DSP,你也需要去研读一些相关的领域。
图1-2
数位讯号处理在很多科学、工程和数学领域上有模糊和重叠的边界。
电信(Telecommunications)
电信是关于从一个位置传送资讯给另一个。这包含许多资讯的型式:电话交谈、电视讯号、电脑档案和其它类型的资料。要传送资讯,你需要一个介于二个位置间的通道(channel)。这可能是一对导线(wire pair),无线电广播讯号,光纤,等……。电信公司接收传送他们的客户的资讯的付费款项,然而他们必须付费来建立和维护通道(channel)。财务上的帐本盈亏结算线(bottom line)很简单:他们可以经由单一通道来传递愈多的资讯,他们可以赚愈多的钱。DSP已经在许多领域中的电信产业发动革命:声调(tone)讯号的产生及侦测,频带(frequency band)平移,为了移除电力线的嗡嗡声(power line hum)的滤波动作(filtering),等等……。从电话网路中有三个特殊的例子在此会被讨论:多路传输(multiplexing)、压缩和回声控制(echo control)。
多路传输(Multiplexing)
世界上大约有十亿的电话。按下几个键,交换网路允许在任何地方的任何人只要几秒钟就可以被连结起来。此项无限大(immensity)的任务让人犹豫。直到1960时,介于二支电话间的连结需要经由机械的交换器和扩大器(amplifiers)来传送类比声音讯号。一个连结需要一对导线。比较起来,DSP将音讯转换成序列数位资料串流。因为位元可以被轻易地编结(interwinded)并且稍后被分开,许多电话谈话可以被在单一通道(channel)上传送。例如,电话的标准已知为T-carier system,它可以同时传送24个声音讯号。每个声音讯号使用8 bit companded(对数压缩,logarithmic compressed)类比对数位的转换来每秒抽样8000次。每个声音讯号中的结果被表成64,000 bits/sec,且所有的24个channel都包含在1.544 megabits/sec内。使用传统的22 gauge铜制电话线,讯号可被传送约6000英呎,典型的互相连接的距离。数位传输在财务上的优点很多。电线和类比交换器很贵,数位逻辑闸(digital logic gates)很便宜。
压缩(Compression)
当声音讯号以8000 samples/sec被数位化,大部份的数位资讯会是多余的(rendant)。也就是说,由任何一个样本承载的资讯会被邻近的样本大量地复制。数以打计的DSP算法已经被发展来转换数位化的声音讯号成需要较少bits/sec的资料串流。这些被称作资料压缩(data compression)算法。相对应的解压缩(uncompression)算法则被用来回复讯号到它原本的型式。这些算法在进行压缩的数目和结果的声音品质上变化。一般而言,可将资料速率从64 kilobits/sec减少到32 kilobits/sec,而不损失声音的品质。当压缩成资料速率8 kilobits/sec时,声音会明显地被影响,不过仍然对长距离电话网路很有用。最长的可达到的压缩约是2 kilobits/sec,导致高度扭曲的声音,不过可用于一些应用,例如军队和海底通讯。
回声控制(Echo control)
回声在长距离电话连结中是一个严重的问题。当你对电话说话时,一个代表你的声音的讯号传导(travel)到连接的接收器上,其中部份的讯号会回传,即为回声(echo)。如果连结在数百英哩之内,用来接收回声所花费的时间仅有几毫秒(milliseconds)。人耳习惯于听这些小的时间延迟的回声,而连结似乎相当正常。当距离变得较长,回声变得越来越显着且恼人(irritating)。对于州际间的通讯,延迟可以是数百微秒,而且特别令人不愉快(objectionable)。数位讯号处理借由量测传回的讯号并产生适当的反讯号(antisignal)以消除烦扰的回声,来着手处理此类的问题。同样的技术让喇叭扩音器使用者可以同时听和说而没有抗争的(fighting)音讯回馈(长而尖的声音, squealing)。它也可借由数位产生的反噪音(anitnoise)来抵消它,以减少环境噪音。
音讯处理(Audio Processing)
人类的二大主要感官是视觉和听觉。相对应地,许多DSP与影像及音讯处理相关。人们听音乐和语言(语音)。DSP已经在这二大领域上有革命性的变化。
音乐(Music)
从音乐家的麦克风到爱玩高级音响的人的扬声器的路径是相当长的。数位资料表示法很重要,因为它会防止“一般和类比式储存和处理相关”的降级。这对任何比较过卡带和CD的音乐品质的人来讲会很熟悉。在一般的情境(scenario)中音乐片段在录音室(sound studio)中被录起来在数个频道或音轨(track)上。在某些情况下,这甚至包含各别录制单独的乐器和歌手。这麼做是为了给予声音工程师在制作最后的成品时较大的弹性。组合各别的音轨到最后的成品的复杂过程被称作mix down。DSP可以在mix down时,提供数种重要的功能,包括了:滤声(filtering),讯号加和减,讯号编辑,等……。
译注:把 X 声道的 audio 混成 Y 声道,其中 X 是大于 Y 的数字,例如说你的 DVD 上面是 5.1 声道,但是你只有耳机,耳机只有双声道,所以就需要 mix down 成 2 channel,感谢Jedi提供解释。
最有趣的DSP在音乐准备上的应用之一是人工余韵(artificial reverberation)。如果各别的频道被简单地加在一起,结果的片段听起来渺茫无力(frail and diluted),很像是音乐家在户外演奏。这是因为听者被音乐的回音或余韵的内容大大地影响了,而通常在录音室内这些都被最小化了。DSP允许人造回声和余韵在mix down时被加总以模拟各种理想的聆听环境。有数百微秒延迟的回声给予人像教堂般地点的印象。增加10-20微秒延迟的回声让人感觉在更适当大小的聆听空间。
语音的产生(Speech generation)
语音的产生和辨识被用来作为人与机器间的沟通。并不是用你的手和眼,而是用你的嘴和耳。当你的手和眼应该做些别的事,例如:开车,开刀,或(不幸地)用武器对敌人开火时,这非常方便。对于电脑所产生的语音,会使用二个方法:数位录音和声道模拟(vocal tract simulation)。在数位录音中,人声被数位化并储存,通常在一种压缩表格(compressed form)里。在录放时,储存的资料被解压缩并且被转回到类比讯号。整整一小时录下来的语音只需要大约3 megabytes来储存,甚至在小电脑系统里也能。这是今日使用的、最常见的数位语音产生的方法。
声道模拟(vocal tract simulation)更复杂,借由人类建立语音的方法来试着模仿身体的(physical)机制。人类声道模拟是由室内(chamber)的尺寸和形状决定的具共鸣频率(resonant frequency)的声腔(acoustic cavity)。在比较上,摩擦音源于在狭窄的压缩下嘈杂的空气杂讯,就好像牙齿和嘴唇。声道模拟借由产生模仿这二种刺激(excitation)的数位讯号来运作。共鸣室(resonate chamber)的特性是经由具相似共振的数位滤波器来传送刺激讯号来模拟。此方法被用于非常早期的DSP成功故事的其中一个,Speak & Spell是卖得很好的、给儿童的电子辅助学习器。
语音辨识(Speech recognition)
自动地人类语音辨识比产生语音更加地困难。语音辨识是人脑做的好,但数位电脑做的很差的经典范例。数位电脑可以储存并且记得非常大量的资料,以极快的速度执行数学计算,并且做重覆的工作而不会厌烦或没有效率。不幸地,当面对未加工的感知资料(raw sensory data)时,今日的电脑执行地非常差。教导电脑每月寄给你帐单很容易。教导同一台电脑去了解你的声音是件大工程。
数位讯号处理一般在二个步骤中处理语音辨识问题:在特色配对(feature matching)之后做特色撷取(feature extraction)。
进入的音讯讯号中的每个字要先被隔离,然后分析以辨识刺激和共振频率的类型。然后这些参数与之前说话的字的范例做比较以辨识出最接近的配对。常常,这些系统受限于只有几百字,只能接受字与字间有可分辨的中断的语音;且每个说话者需被个别再训练。虽然这对许多商业应用是适当的,当与人类的听力比较时,这些限制是简陋的(humbling)。在此领域有很多工作要被完成,成功的商业性产品的那些人会有巨大的金钱上的奖赏。
回声位置(Echo Location)
获得关于远端物件资讯的常见方法是弹出一个离开它的波(bounce a wave off of it)。例如,雷达借由传送无线电波的脉冲波,并且对每个从飞机回声检查接收到的讯号来运作。在声纳上,声波经由水传送以侦测潜水艇和其它水面下的物体。地球物理学家已经借由设定长期爆破并听取从岩石的深埋层(deeply buried layers of rock)的回声来针测地球。虽然这些应用有共同的思路(thread),它们每个都有自个儿特定的问题和需求。数位讯号处理已经在三个领域中都已产生了革命性的变化。
雷达(Radar)
雷达(Radar)是 RAdio Detection And Ranging的首字缩写。在最简单的雷达系统里,无线电传送器产生一个好几微秒长的无线电频率能量脉冲。此脉冲被餵进高度的指向天线(directional antenna),在那里导致无线电波传播(propagate)并以光速离开。在此波路径上的飞机会反射回来一小部份的能量到位于传送站附近的接收天线。到物体的距离由介于被传送的脉冲和接收的回声间花费的时间来计算。物体的方向更容易发现,当回声被接收时,你知道你在哪里指到指向天线(directional antenna)。
雷达系统的运作范围由二个参数决定:初始脉冲内有多少能量,及无线电接收器的噪音水准。不幸地,要在脉冲波里增加能量通常需要更长的脉冲波。接着,较长的脉冲波减少正确性和消耗时间测度的精度。这导致了二个重要参数间的冲突:侦测远距离物体的能力,和正确地决定物体的距离的能力。
DSP在三个领域有革命性的雷达,它们全都与基本问题相关。第一个,DSP可以在脉冲波被接收后压缩它,提供较佳距离测定而不需减小其作业范围。第二个,DSP可以过滤掉所接收的讯号来减少杂讯。这增加了范围,而不用将距离测定降级。第三,DSP能够快速选取并产生不同脉冲波形和长度。除了其它的(问题)外,这让脉冲波对特定的侦测问题被最佳化。现在是令人印象深刻的部份:这里面很多是由和所使用的无线电频率差不多的抽样率(sampling rate),约是数百megahertz!当它涉及雷达这方面时,DSP与高速硬体设计高度相关就和它与算法的关系一样。
声纳(Sonar)
声纳是SOund NAvigation and Ranging的首字缩写。它被分成二大类,主动式(active)和被动式(passive)。在主动式声纳中,介于2 kHz 和40 kHz 间的声音脉冲波被传送到水里,而结果的回声被侦测和分析。使用主动式声纳包含:侦测和定位水面下的物体、航海、通讯和映射(mapping)到海底(sea floor)。一般最大操作范围是10到100公里。与其相比,被动式声纳只聆听海面下的声音,包含:自然的乱流(turbulence)、海洋生物和从潜艇和表面船舰发出的机械声。因为被动式声纳没有消除能量,它对于转换作业而言很理想。你想要侦测其它人(the other guy),而不要他侦测你。被动式声纳最重要的应用是军事监视(surveillance)系统,它侦测并追踪潜水艇。被动式声纳一般使用比主动式声纳较低的频率,因为它们经由水以较少的吸收作用被传播(propagate)。侦测范围可达到数千公里。
DSP在声纳方面已经与雷达方面有许多相同的领域都有革命性的发展:脉冲波的产生、脉冲波压缩和过滤侦测到的讯号。有个声纳比雷达简单的观点:因为包含了较低的频率。另一个观点是,声纳比雷达更难,因为环境较不一致也较不稳定。声纳系统通常使用昂贵的阵列来传送和接收元素,而不是只有单一个频道。借由适当地控制和混合这许多元素的讯号,声纳系统可以指引被消除的脉冲波到想要的位置并且决定回音被接收的方向。要处理这许多的频道,声纳系统需要与雷达同样大规模的DSP运算能力。
反射地震学(Reflection seismology )
大约是1920年代早期,地球物理学家发现地球外壳的结构可以用声音来探测。探勘者可以引爆并从在表面下超过十公里的边界层(boundary layer)纪录回声。这些回声震动图(seismograms)由肉眼解读来对应到次表面(subsurface)的结构。反射地震法(reflection seismic method)很快地变成主要确定石油和矿藏位置的方法,且直到今日仍是。
在理想的情况下,传送到地面的声音脉冲波从每个脉冲波经过的边界层产生一个回声。不幸地,情况通常不会这麼简单。每一个传回到地表的回声必须经过所有其它上面(它源自的)边界层。这会导致回声在层与层之间跳跃,产生回声的回声在表面被侦测到。这些次要的回声可以使被侦测的讯号非常地复杂和难以解读。自从1960年代,数位讯号处理已经被广泛地运用来从反射震动图(reflection seismograms)中的次要回声隔离主要的回声。早期的地球物理学家如何在没有DSP的情况下处理?答案很简单:他们看简单的地方,在那里多重反射被最小化。DSP允许原油在困难的位置被发现,例如在海的下方。
影像处理(Image Processing)
影像是具有特性的讯号。首先,它们是空间(距离)上参数的测度,虽然大部份讯号是时间参数的测度。第二,它们包含很多资讯。例如,可能需要超过10 megabytes来储存二分之一的电视录影。这比一个相似长度的声音讯号大了超过1000倍。第三,最终品质的判断通当会受限于人类的评估,而非客观存在的评断标准。这些特性已经使得影像处理变成DSP内不同的子群组。
医疗的(Medical)
在1895年,Wilhelm Conrad R?ntgen发现了X光可穿透相当数量的实际物体。医学借由可以看到活生生的人体内而有了革命性的进步。医疗用X光系统只在几年内便散布全球。尽管它明显的成功,直到DSP及相关技术在1970年出现之前,医疗用X光影像一直受限于四个问题。笫一,人体内重叠的结构可以藏在另一个之后。例如,在肋骨后方的部份心藏可能无法被看见第二,并不总是能区分相似的组织(tissue)。例如,可能可以从软组织分开骨头,不过不能从肝藏分辨肿瘤。第三,X光影像显示解剖结构(anatomy),身体的结构,而不是生理学,身体的运作。活人的X光影像看起来就像是死人的X光影像!第四,曝露在X光下会引起癌症,需要谨慎地(sparingly)且只能在有适当的理由时才能使用它。
重叠结构的问题在1971年引入第一台计算式断层摄影法(computed tomography)扫描器被解决了(正式地名称是computed axial tomography或CAT 扫描器)。计算式断层摄影法(CT)是一经典的数位讯号处理的例子。从许多方向的X光会穿透病人被检查时的身体各部份(section)。并非简单地以侦测到的X光形成影像,而是讯号被转成数位资料并储存在电脑中。然后此资讯被用于计算要显示为身体各切片(slice)的影像。这些影像比传统的技术显示更多的细节,允许值得注目地更好的检测和治疗。CT的影响几乎和原本引入X光影像本身一样大。在几年之内,世界上的每家大医院都已经使用CT扫描器了。在1979年时, CT原理的贡献者中其中的二位,Godfrey N. Hounsfield 和 Allan M. Cormack,共享了诺贝尔医学奖(Nobel Prize in Medicine)。那是好DSP!
最后的三个X光问题已经借由使用不是X光的穿透性能源(penetrating energy)被解决了,例如无线电和声波。DSP在所有这些技术中扮演一个关键的角色。例如,核磁共振影像(Magnetic Resonance Imaging,MRI)使用磁场连结无线电波来探测人体的内部。适当地调整磁场强度和频率让在身体区域范围内的原子核可以介于量子能源状态间共振。此共振导致次要的无线电波放射,由放在靠近身体的天线侦测。这个侦测到的讯号的强度和其它特性提供了关于共振局部区域的资讯。磁场的调整让被经此身体扫描的共振区域对应到内部的结构。此资讯通常被表示成影像,就像是计算式断层摄影般。除了提供介于不同类型软组织间杰出的辨识外,MRI可以提供关于生理学(physiology)的资讯,例如经由动脉的血液流。MRI完全依赖数位讯号处理技术,没有它们无法被实作。
外太空(Space)
有时候,你只是必须把一张烂相片弄到最好。这情况屡次都是因为影像从无人管理的卫星和太空探索火箭拍的。没有人会送一个修理工到火星只是去扭转像机的旋钮!DSP可以用数种方法来增进在非常不适宜的情况下所拍的影像的品质,它们是:亮度和对比调整,边界侦测,杂讯减少,焦点调整,动作模糊减少,等……。有空间扭曲的影像,例如拍摄球面星球的平面影像所遇到的,可以被变形(warped)成一种正确的表示法。许多各别的影像可以被结合成单一的资料库,让资讯以唯一的方式被显示。例如,一个电视影像序列模拟飞机在不同星球的表面飞行。
商业化的影像产品(Commercial Imaging Procts)
对于在大量出售给大众的系统而言,在影像内大量的资讯内容是个问题。商业化的系统必须要便宜,且这不是大量记忆体和高度资料传输速率配合的结果。一个对此定理的解答是影像压缩(image compression)。就好像声音讯号,影像包含极大数目的多余资讯,且可经由减少“需要用来表示的bits数目”的算法来回传。电视和其它动作片尤其适合压缩,因为大部份的影像从一个frame到另一个frame仍旧是一样的。商业化的影像处理软体利用此技术,包含了:视讯电话、显示移动中图片的电脑程式和数位电视。
③ DSP的 学习 要那些 基础 知识
信号与系统, 复变函数, 线性代数,数字信号处理。 还有一些编程技巧。如果学会matlab,在dsp的应用仿真中是很有用的!!
加油!!
④ 请问在编写DSP程序时,数学函数如:sprt这种开方的,需要定义什么头文件吗
如何使用STM32F4的DSP库
我们平常所使用的CPU为定点CPU,意思是进行整点数值运算的CPU。当遇到形如1.1+1.1的浮点数运算时,定点CPU就遇到大难题了。对于32位单片机,利用Q化处理能发挥他本身的性能,但是精度和速度仍然不会提高很多。
现在设计出了一个新的CPU,叫做FPU,这个芯片专门处理浮点数的运算,这样处理器就将整点数和浮点数分开来处理,整点数交由定点CPU处理而浮点数交由FPU处理。我们见到过TI的DSP,还有STM32F4系列的带有DSP功能的微控制器。前者笔者没有用过,不作评论,而后者如果需要用到FPU的浮点运算功能,必须要进行一些必要的设置。
首先,由于浮点运算在FPU中进行,所以首先应该使能FPU运行。在system_init()中,定义__FPU_PRESENT和__FPU_USED
/* FPU settings------------------------------------------------------------*/
#if (__FPU_PRESENT == 1)&& (__FPU_USED == 1)
SCB->CPACR |= ((3UL<< 10*2)|(3UL << 11*2)); /*set CP10 and CP11 Full Access */
#endif
这样就使能了FPU。
对于上述改变,当程序中出现这种简单的加减乘除运算FPU就起作用了。但是对于复杂的如三角运算、开方运算等,我们就需要加入math.h头文件。但是如果单纯的加入他,那么Keil会自动调用内部的math.h,该头文件是针对ARM处理器的,专门用于定点CPU和标准算法(IEEE-754)。对于使用了FPU的STM32F4是没有任何作用的。所以,需要将math.h换成ST的库,即arm_math.h。在该头文件中,涉及到另一个文件core_cmx.h(x=0、3、4),当然了,如同STM32F1系列一样,在工程中加入core_cm4.h即可。
到这里,算是全部设置完毕,之差最后一步,调用!但是别小看了这一步,因为如果调用的不正确,全面的设置就白费了。在使用三角函数如sin()、cos()时不要直接写如上形式,因为他们函数的名字来自于math.h,所以你调用的仍旧是Keil库中的标准math.h。要使用arm_math.h中的arm_sin_f32()函数(见Line.5780,原函数见DSP_Lib\Source\FastMathFunctions),可以看到他利用的是三次样条插值法快速求值(见Line.263 /* Cubic interpolation process */)。
注意一下例外函数,sqrt(),在arm_math.h中为arm_sqrt_f32()。使用他的时候需要同时开启#if(__FPU_USED == 1) && defined ( __CC_ARM )才行,切记!还可以发现开方函数还有q15和q31之分,我想他们的区别就是精度的问题,但是他们没有应用FPU来计算,说白了就是利用0x5f3759df这个数进行快速开方
⑤ 如何在VDSP下生成和调用DSP库
有些资料可供你参考:
DSP的特点
对于没有使用过DSP的初学者来说,第一个困惑就是DSP其他的嵌入式处理器究竟有什么不同,它和单片机,ARM有什么区别.事实上,DSP也是一种嵌入式处理器,它完全可以完成单片机的功能.
唯一的重要的区别在于DSP支持单时钟周期的"乘-加"运算.这几乎是所有厂家的DSP芯片的一个共有特征.几乎所有的DSP处理器的指令集中都会有一条MAC指令,这条指令可以把两个操作数从RAM中取出相乘,然后加到一个累加器中,所有这些操作都在一个时钟周期内完成.拥有这样一条指令的处理器就具备了
DSP功能.
具有这条指令就称之为数字信号处理器的原因在于,所有的数字信号处理算法中最为常见的算术操作就是"乘-加".这是因为数字信号处理中大量使用了内积,或称"点积"的运算.无论是FIR滤波,FFT,信号相关,数字混频,下变频.所有这些数字信号处理的运算经常是将输入信号与一个系数表或者与一个本地参考信号相乘然后积分(累加),这就表现为将两个向量(或称序列)进行点积,在编程上就变成将输入的采样放在一个循环buffer里,本地的系数表或参考信号也放在一个buffer里,然后使用两个指针指向这两个buffer.这样就可以在一个loop里面使用一个MAC指令将二者进行点积运算.这样的点积运算对与处理器来说是最快的,因为仅需一个始终周期就可以完成一次乘加.
了解DSP的这一特点后,当我们设计一个嵌入式系统时,首先要考虑处理器所实现的算法中是否有点积运算
,即是否要经常进行两个数组的乘加,(记住数字滤波,相关等都表现为两个数组的点积)如果有的话,每秒要做多少次,这样就能够决定是否采用DSP,采用多高性能的DSP了.
浮点与定点
浮点与定点也是经常是初学者困惑的问题,在选择DSP器件的时候,是采用浮点还是采用定点,如果用定点是16位还是32位?其实这个问题和你的算法所要求的信号的动态范围有关.
定点的计算不过是把一个数据当作整数来处理,通常AD采样来的都是整数,这个数相对于真实的模拟信号有一个刻度因子,大家都知道用一个16位的AD去采样一个0到5V的信号,那么AD输出的整数除以2^16再乘以5V就是对应的电压.在定点DSP中是直接对这个16位的采样进行处理,并不将它转换成以小数表示的电压,因为定点DSP无法以足够的精度表示一个小数,它只能对整数进行计算.
而浮点DSP的优势在于它可以把这个采样得到的整数转换成小数表示的电压,并不损失精度(这个小数用科学记数法来表示),原因在于科学记数法可以表示很大的动态范围的一个信号,以IEEE754浮点数为例,
单精度浮点格式: [31] 1位符号 [30-23]8位指数 [22-00]23位小数
这样的能表示的最小的数是+-2^-149,最大的数是+-(2-2^23)*2^127.动态范围为20*log(最大的数/最小的数)=1667.6dB 这样大的动态范围使得我们在编程的时候几乎不必考虑乘法和累加的溢出,而如果使用定点处理器编程,对计算结果进行舍入和移位则是家常便饭,这在一定程度上会损失是精度.原因在于定点处理处理的信号的动态范围有限,比如16位定点DSP,可以表示整数范围为1-65536,其动态范围为20*log(65536/1)=96dB.对于32定点DSP,动态范围为20*log(2^32/1)=192dB,远小于32位ieee浮点数的1667.6dB,但是,实际上192dB对绝大多数应用所处理的信号已经足够了.
由于AD转换器的位数限制,一般输入信号的动态范围都比较小,但在DSP的信号处理中,由于点积运算会使中间节点信号的动态范围增加,所以主要考虑信号处理流程中中间结果的动态范围,以及算法对中间结果的精度要求,来选择相应的DSP.另外就是浮点的DSP更易于编程,定点DSP编程中程序员要不断调整中间结果的P,Q值,实际就是不断对中间结果进行移位调整和舍入.
DSP与RTOS
TI的CCS提供BIOS,ADI的VDSP提供VDK,都是基于各自DSP的嵌入式多任务内核.DSP编程可以用单用C,也可以用汇编,或者二者结合,一般软件编译工具都提供了很好的支持.我不想在这里多说BIOS,VDK怎么用这在相应的文档里说的很详细.我想给初学者说说DSP的RTOS原理.用短短几段话说这个复杂的东西也是挑战!^_^
其实DSP的RTOS和基于其他处理器的通用RTOS没什么大的区别,现在几乎人人皆知的uCOSii也很容易移植到DSP上来,只要把寄存器保存与恢复部分和堆栈部分改改就可以.一般在用BIOS和VDK之前,先看看操作系统原理的书比较好.uCOS那本书也不错.
BIOS和VDK其实是一个RTOS内核函数集,DSP的应用程序会和这些函数连接成一个可执行文件.其实实现一个简单的多任务内核并不复杂,首先定义好内核的各种数据结构,然后写一个scheler函数,功能是从所有就绪任务中(通过查找就绪任务队列或就绪任务表)找出优先级最高的任务,并恢复其执行.然后在此基础上写几个用于任务间通信的函数就可以了,比如event,message box,等等.
RTOS一般采用抢先式的任务调度方式,举例说当任务A等待的资源available的时候,DSP会执行一个任务调度函数scheler,这个函数会检查当前任务是否比任务A优先级低,如果是的话,就会把它当前挂起,然后把任务A保存在堆栈里寄存器值全部pop到DSP处理器中(这就是所谓的任务现场恢复).接着scheler还会把从堆栈中取出任务A挂起时的程序执行的地址,pop到PC,使任务A继续执行.这样当前任务就被任务A抢先了.
使用RTOS之后,每个任务都会有一个主函数,这个函数的起始地址就是该任务的入口.一般每个任务的主函数里有一个死循环,这个循环使该任务周期地执行,完成一部分算法模块的功能,其实这个函数跟普通函数没任何区别,类似于C语言中的main函数.一个任务创建的时候,RTOS会把这个函数入口地址压入任务的堆栈中,好象这个函数(任务)刚发生过一次中断一样.一旦这个新创建任务的优先级在就绪队列中是最高的,RTOS就会从其堆栈中弹出其入口地址开始执行.
有一个疑问是,不使用RTOS,而是简单使用一个主循环在程序中调用各个函数模块,一样可以实现软件的调度执行.那么,这种常用的方法与使用RTOS相比有什么区别呢?其实,使用主循环的方法不过是一种没有优先级的顺序执行的调度策略而已.这种方法的缺点在于,主循环中调用的各个函数是顺序执行的,那么,即使是一个无关紧要的函数(比如闪烁一个LED),只要他不主动返回,也会一直执行直到结束,这时,如果发生一个重要的事件(比如DMA buffer full 中断),就会得不到及时的响应和处理,只能等到那个闪烁LED的函数执行完毕.这样就使整个DSP处理的优先次序十分不合理.而在使用了RTOS之后,当一个重要的事件发生时,中断处理会进入RTOS,并调用scheler,这时scheler 会让处理这一事件的任务抢占DSP处理器(因为它的优先级高).而哪个闪烁LED任务即使晚执行几毫秒都没任何影响.这样整个DSP的调度策略就十分合理.
RTOS要说的内容太多,我只能讲一下自己的一点体会吧
DSP与正(余)弦波
在DSP的应用中,我们经常要用到三角函数,或者合成一个正(余)弦波.这是因为我们喜欢把信号通过傅立叶变换映射到三角函数空间来理解信号的频率特性.信号处理的一些计算技巧都需要在DSP软件中进行三角函数计算.然而三角函数计算是非线性的计算,DSP并没有专门的指令来求一个数的正弦或余弦.于是我们需要用线性方法来近似求解.
一个直接的想法是用多项式拟合,这也正是大多数DSP C编译器提供正余弦库函数所采用的方法.其原理是把三角函数向函数空间{1,x,x^2,x^3....}上投影,从而获得一系列的系数,用这些系数就可以拟合出三角函数.比如,我们在[0,pi/2]区间上拟合sin,只需在matlab中输入以下命令:
x=0:0.05:pi/2;
p=polyfit(x,sin(x),5)
就得到5阶的多项式系数:
p =
0.00581052047605 0.00580963216172 -0.17193865685360
0.00209002716293 0.99969270087312 0.00000809543448
于是在[0,pi/2]区间上:
sin(x)= 0.00000809543448+0.99969270087312*x+ 0.00209002716293*x^2-0.17193865685360*x^3+
0.00580963216172*x^4+0.00581052047605*x^5
于是在DSP程序中,我们可以通过用乘加(MAC)指令计算这个多项式来近似求得sin(x)
当然如果用定点DSP还要把P这个多项式系数表用一定的Q值来改写成定点数.
这样的三角函数计算一般都需要几十个cycle 的开销.这对于某些场合是不能容忍的
另一种更快的方法是借助于查表,比如,我们将[0,pi/2]分成32个区间,每个区间长度就为pi/64,在每个区间上我们使用直线段拟合sin曲线,每个区间线段起点的正弦值和线段斜率事先算好,存在RAM里,这样就需要在在RAM里存储64个
常数:
32个起点的精确的正弦值(事先算好): s[32]={0,sin(pi/64),sin(pi/32),sin(pi/16)....}
32个线段的斜率: f[32]={0.049,.....}
对于输入的每一个x,先根据其大小找到所在区间i,通常x用定点表示,一般取其高几位就是系数i了,然 后通过下式即可求出sin(x):
sin(x)= s*f
这样一般只需几个CYCLE就可以算出正弦值,如果需要更高的精度,可以将区间分得更细,当然,也就需 要更多的RAM去存储常数表.
事实上,不仅三角函数,其他的各种非线性函数都是这样近似计算的.
1. 接触DSP
在参加过一次社会上多的尽乎到了泛滥地步的"DSPxxx"培训班之后,我"自信"已经具备DSP工师资格,便欣喜若狂跑道书店买了一本名为"DSP xxx应用"的书,作者叫xxx,并且是这个领域的牛人,这本书确实是很出色的书籍.但是当时,对于我这个对DSP一窍不通、刚刚入门的人来说却建立了一个错误的概念--DSP是个很容易的领域,只要培训一下,再稍微看看书,就可以成为专家.所以,现在看来,这些都是误导,我认为学习DSP技术应该分为两个阶段,第一阶段学习DSP技术基础概念;第二阶段学习DSP技术的行业应用.那本"DSP xxx应用"的书,它更适合书名应叫做"DSP中的数学或物理运用"...什么的.
2. 购买DSP学习套件
有了兴趣,就要去学习,于是我撺掇领导批准购买了DSP学习入门套件(DSK),许多公司均有销售,如TI等,大概是需要3000-4000人民币.买后不久,我就发现,这种套件对于我来说一点用处都没有.因为我的基础知识实在是太差了.这些套件对于我来说,只是另一种涵义的PC机及一些外围设备,想要懂的这些东西,我就需要去读更多的相关书籍,这时,很难没有想要放弃的念头,我开始有点畏惧DSP这种技术,门槛太高了.可是,我不能放弃,我已经投入了许多的金钱和时间,我不想丢掉这4000元钱,也不能对领导没有交待.事实上,我没有想到,我将付出更多的钱和时间去学习.
3. 再次参加培训班,再次购买DSP书籍
在我就感到了无助,困惑之际.我又想到了放弃.虽然我的数学还算不错,但其中遇到的一些问题在我思考后,还是无法解决,我越来越畏惧DSP了.于是,我开始在"google"上搜索DSP培训相关的信息,终于发现闻亭公司"DSP培训中心"的教程和内容正是我一直寻找的东西.也许是DSP技术对我的有着巨大的诱惑力,也许是我的之直着,我又一次勇敢的报名参加了培训.32个课时之后,解决了我半年多来积累的很多粗浅的问题.再翻开培训教材刚刚复读了第一章时,我想如果这本教材是我读到的第一本书,并且我没有花4000元买那个可*的学习套件,我会毫不犹豫的投降,放弃学习DSP,但.......那个可*的xxx作者,他的书怎么可以用作教学呀.他的书虽然让我对DSP产生了浓厚的兴趣,却把我引到了一条艰难的路上,而且花了那么多的冤枉钱....既然事已如此,我只有慢慢的去读这些书籍,在我读到教材的后面章节以后,我开始明白前面章节的内容,所以当你读书遇到不明白的时候,千万不要气馁.有时,一个内容,可能需要读上几遍,才能明白,这比一开始的感觉要好的多了.
4. 实验--至关重要的一步
现在,从你的架子上取下那套DSK,去尝试做一些小实验,我的第一个实验是"正弦发生器",这个实验比较简单,但是它也花费了我几周的时间去读大量的关于串口、编码、寄存器等的书并且进行大量的实验.这个执行半小时的"正弦发生器",让我查阅了恨不得够组建一个图书馆的书籍,而且这个东西没有任何用途.我是用汇编语言在54x中执行,这个实验让我很好的理解了什么是DSP,什么是McBSP, DMA, 等.当然问题也同步产生了,我就又不得不做了许多的实验去验证.我建议,在系统未定型之前,使用mathlab/simulink进行仿真,并且可以多实验几种芯片,这样可以让你明白更多的内容.我觉得我就要成为一个真正的DSP工程师了,我度过了最困难的时期.我觉得自己是个英雄,嘿嘿.
5. 去寻找一份与DSP相关的工作,去当个DSP工程师
我希望困难已经过去,但这种愿望为时过早了.在DSP的研究中,我还遇到了很多的困难,由于篇幅有限,我就不在进行描述了.反正,如果想成为真正的DSP专家,就不要期望事情会变得容易.有些DSP开发人员并不知道什么是真正的0和1,他们只会查阅各种参考书籍和参数表,我们并不提倡这种做法.因为这些人选择了一种简单的做法,但是他们并不是真正的DSP开发人员.他们只是编写一些他们不理解的代码,他们似乎在担当着一台"编码器"的角色.
6. 总结
这篇文章只是我的一点感慨,可能并不是很适用现在的DSP开发工程师,因为,市面上已经有了供你学习的DSP教学套件,搭配了多种实验供你参考,轻松入门,如:闻亭公司的"大学实验箱"什么的.这个实验箱提供了一个很好的实验环境,并且为初学的你设计了多种实验、教材,让你由浅入深的学习.不会向我似的,绕一大圈才走到正
⑥ DSP有哪些特点适于进行数字信号处理
DSP的特点
对于没有使用过DSP的初学者来说,第一个困惑就是DSP其他的嵌入式处理器究竟有什么不同,它和单片机,ARM有什么区别。事实上,DSP也是一种嵌入式处理器,它完全可以完成单片机的功能。
唯一的重要的区别在于DSP支持单时钟周期的"乘-加"运算。这几乎是所有厂家的DSP芯片的一个共有特征。几乎所有的DSP处理器的指令集中都会有一条MAC指令,这条指令可以把两个操作数从RAM中取出相乘,然后加到一个累加器中,所有这些操作都在一个时钟周期内完成。拥有这样一条指令的处理器就具备了DSP功能。
具有这条指令就称之为数字信号处理器的原因在于,所有的数字信号处理算法中最为常见的算术操作就是"乘-加"。这是因为数字信号处理中大量使用了内积,或称"点积"的运算。无论是FIR滤波,FFT,信号相关,数字混频,下变频。所有这些数字信号处理的运算经常是将输入信号与一个系数表或者与一个本地参考信号相乘然后积分(累加),这就表现为将两个向量(或称序列)进行点积,在编程上就变成将输入的采样放在一个循环buffer里,本地的系数表或参考信号也放在一个buffer里,然后使用两个指针指向这两个buffer。这样就可以在一个loop里面使用一个MAC指令将二者进行点积运算。这样的点积运算对与处理器来说是最快的,因为仅需一个始终周期就可以完成一次乘加。
了解DSP的这一特点后,当我们设计一个嵌入式系统时,首先要考虑处理器所实现的算法中是否有点积运算,即是否要经常进行两个数组的乘加,(记住数字滤波,相关等都表现为两个数组的点积)如果有的话,每秒要做多少次,这样就能够决定是否采用DSP,采用多高性能的DSP了。
浮点与定点
浮点与定点也是经常是初学者困惑的问题,在选择DSP器件的时候,是采用浮点还是采用定点,如果用定点是16位还是32位?其实这个问题和你的算法所要求的信号的动态范围有关。
定点的计算不过是把一个数据当作整数来处理,通常AD采样来的都是整数,这个数相对于真实的模拟信号有一个刻度因子,大家都知道用一个16位的AD去采样一个0到5V的信号,那么AD输出的整数除以2^16再乘以5V就是对应的电压。在定点DSP中是直接对这个16位的采样进行处理,并不将它转换成以小数表示的电压,因为定点DSP无法以足够的精度表示一个小数,它只能对整数进行计算。
而浮点DSP的优势在于它可以把这个采样得到的整数转换成小数表示的电压,并不损失精度(这个小数用科学记数法来表示),原因在于科学记数法可以表示很大的动态范围的一个信号,以IEEE754浮点数为例,
单精度浮点格式: [31] 1位符号 [30-23]8位指数 [22-00]23位小数
这样的能表示的最小的数是+-2^-149,最大的数是+-(2-2^23)*2^127.动态范围为20*log(最大的数/最小的数)=1667.6dB 这样大的动态范围使得我们在编程的时候几乎不必考虑乘法和累加的溢出,而如果使用定点处理器编程,对计算结果进行舍入和移位则是家常便饭,这在一定程度上会损失是精度。原因在于定点处理处理的信号的动态范围有限,比如16位定点DSP,可以表示整数范围为1-65536,其动态范围为20*log(65536/1)=96dB.对于32定点DSP,动态范围为20*log(2^32/1)=192dB,远小于32位ieee浮点数的1667.6dB,但是,实际上192dB对绝大多数应用所处理的信号已经足够了。
由于AD转换器的位数限制,一般输入信号的动态范围都比较小,但在DSP的信号处理中,由于点积运算会使中间节点信号的动态范围增加,所以主要考虑信号处理流程中中间结果的动态范围,以及算法对中间结果的精度要求,来选择相应的DSP。另外就是浮点的DSP更易于编程,定点DSP编程中程序员要不断调整中间结果的P,Q值,实际就是不断对中间结果进行移位调整和舍入。
DSP与RTOS
TI的CCS提供BIOS,ADI的VDSP提供VDK,都是基于各自DSP的嵌入式多任务内核。DSP编程可以用单用C,也可以用汇编,或者二者结合,一般软件编译工具都提供了很好的支持。我不想在这里多说BIOS,VDK怎么用这在相应的文档里说的很详细。我想给初学者说说DSP的RTOS原理。用短短几段话说这个复杂的东西也是挑战!
其实DSP的RTOS和基于其他处理器的通用RTOS没什么大的区别,现在几乎人人皆知的uCOSii也很容易移植到DSP上来,只要把寄存器保存与恢复部分和堆栈部分改改就可以。一般在用BIOS和VDK之前,先看看操作系统原理的书比较好。uCOS那本书也不错。
BIOS和VDK其实是一个RTOS内核函数集,DSP的应用程序会和这些函数连接成一个可执行文件。其实实现一个简单的多任务内核并不复杂,首先定义好内核的各种数据结构,然后写一个scheler函数,功能是从所有就绪任务中(通过查找就绪任务队列或就绪任务表)找出优先级最高的任务,并恢复其执行。然后在此基础上写几个用于任务间通信的函数就可以了,比如event,message box,等等。
RTOS一般采用抢先式的任务调度方式,举例说当任务A等待的资源available的时候,DSP会执行一个任务调度函数scheler,这个函数会检查当前任务是否比任务A优先级低,如果是的话,就会把它当前挂起,然后把任务A保存在堆栈里寄存器值全部pop到DSP处理器中(这就是所谓的任务现场恢复)。接着scheler还会把从堆栈中取出任务A挂起时的程序执行的地址,pop到PC,使任务A继续执行。这样当前任务就被任务A抢先了。
使用RTOS之后,每个任务都会有一个主函数,这个函数的起始地址就是该任务的入口。一般每个任务的主函数里有一个死循环,这个循环使该任务周期地执行,完成一部分算法模块的功能,其实这个函数跟普通函数没任何区别,类似于C语言中的main函数。一个任务创建的时候,RTOS会把这个函数入口地址压入任务的堆栈中,好象这个函数(任务)刚发生过一次中断一样。一旦这个新创建任务的优先级在就绪队列中是最高的,RTOS就会从其堆栈中弹出其入口地址开始执行。
有一个疑问是,不使用RTOS,而是简单使用一个主循环在程序中调用各个函数模块,一样可以实现软件的调度执行。那么,这种常用的方法与使用RTOS相比有什么区别呢?其实,使用主循环的方法不过是一种没有优先级的顺序执行的调度策略而已。这种方法的缺点在于,主循环中调用的各个函数是顺序执行的,那么,即使是一个无关紧要的函数(比如闪烁一个LED),只要他不主动返回,也会一直执行直到结束,这时,如果发生一个重要的事件(比如DMA buffer full 中断),就会得不到及时的响应和处理,只能等到那个闪烁LED的函数执行完毕。这样就使整个DSP处理的优先次序十分不合理。而在使用了RTOS之后,当一个重要的事件发生时,中断处理会进入RTOS,并调用scheler,这时scheler 会让处理这一事件的任务抢占DSP处理器(因为它的优先级高)。而哪个闪烁LED任务即使晚执行几毫秒都没任何影响。这样整个DSP的调度策略就十分合理。
RTOS要说的内容太多,我只能讲一下自己的一点体会吧
DSP与正(余)弦波
在DSP的应用中,我们经常要用到三角函数,或者合成一个正(余)弦波。这是因为我们喜欢把信号通过傅立叶变换映射到三角函数空间来理解信号的频率特性。信号处理的一些计算技巧都需要在DSP软件中进行三角函数计算。然而三角函数计算是非线性的计算,DSP并没有专门的指令来求一个数的正弦或余弦。于是我们需要用线性方法来近似求解。
一个直接的想法是用多项式拟合,这也正是大多数DSP C编译器提供正余弦库函数所采用的方法。其原理是把三角函数向函数空间{1,x,x^2,x^3....}上投影,从而获得一系列的系数,用这些系数就可以拟合出三角函数。比如,我们在[0,pi/2]区间上拟合sin,只需在matlab中输入以下命令:
x=0:0.05:pi/2;
p=polyfit(x,sin(x),5)
就得到5阶的多项式系数:
p =
0.00581052047605 0.00580963216172 -0.17193865685360
0.00209002716293 0.99969270087312 0.00000809543448
于是在[0,pi/2]区间上:
sin(x)= 0.00000809543448+0.99969270087312*x+ 0.00209002716293*x^2-0.17193865685360*x^3+
0.00580963216172*x^4+0.00581052047605*x^5
于是在DSP程序中,我们可以通过用乘加(MAC)指令计算这个多项式来近似求得sin(x)
当然如果用定点DSP还要把P这个多项式系数表用一定的Q值来改写成定点数。
这样的三角函数计算一般都需要几十个cycle 的开销。这对于某些场合是不能容忍的。
另一种更快的方法是借助于查表,比如,我们将[0,pi/2]分成32个区间,每个区间长度就为pi/64,在每个区间上我们使用直线段拟合sin曲线,每个区间线段起点的正弦值和线段斜率事先算好,存在RAM里,这样就需要在在RAM里存储64个
常数:
32个起点的精确的正弦值(事先算好): s[32]={0,sin(pi/64),sin(pi/32),sin(pi/16)....}
32个线段的斜率: f[32]={0.049,.....}
对于输入的每一个x,先根据其大小找到所在区间i,通常x用定点表示,一般取其高几位就是系数i了,然 后通过下式即可求出sin(x):
sin(x)= s[i]*f[i]
这样一般只需几个CYCLE就可以算出正弦值,如果需要更高的精度,可以将区间分得更细,当然,也就需 要更多的RAM去存储常数表。
事实上,不仅三角函数,其他的各种非线性函数都是这样近似计算的。
⑦ 如何学好DSP及DSP基本知识普及
信号与系统, 复变函数, 线性代数,数字信号处理。 还有一些编程技巧。如果学会matlab,在dsp的应用仿真中是很有用的!!
加油!!
⑧ 学dsp是不是需要一定的数电和模电基础
学DSP最好有单片机基础,是在没做过也无所谓,DSP芯片就相当于一片大的单片机,将部分外设集成到一块芯片上而已,若是想从事芯片开发必须掌握数电模电,如果只是平时的学习,重点学习芯片端口\时序\外设部分即可.编程最好要有C语言基础,所以学习DSP之前熟练掌握单片机原理和C编程技巧的话你会得心应手,无需模电数电。个人意见即供参考