最新日志

发表于:2008-5-20 13:14:46
标签:无标签

0

FIR 滤波器

FIR 滤波器FAQ

Part 1: Basics

1.1 什么是FIR滤波器?

  FIR 滤波器是在数字信号处理(DSP)中经常使用的两种基本的滤波器之一,另一个为IIR滤波器.

1.2 FIR代表什么?

  FIR是有限冲激响应(Finite Impulse Response)的简称.

1.3 FIR(有限冲激响应)中的有限该如何理解?

  冲激响应是有限的意味着在滤波器中没有发反馈.

1.4 FIR 怎么发音?

  有些人直接读字母音 F-I-R; 也有人发做fir的音[:], fir是冷杉树.

1.5 FIR 滤波器外有什么其他选择?

  DSP滤波器还有一类: IIR(无限冲激响应,Infinite Impulse Response).IIR滤波器使用反馈,因此当信号输入后,输出是根据算法循环的.

1.6 FIR滤波器与IIR滤波器比较?

   每一种都有优缺点.但总得来说, FIR滤波器的优点远大于缺点,因此在实际运用中,FIR滤波器比IIR滤波器使用的比较多.

1.6.1 相对于IIR滤波器, FIR滤波器有什么优点?

  相较于IIR滤波器, FIR滤波器有以下的优点:

  * 可以很容易地设计线性相位的滤波器. 线性相位滤波器延时输入信号,却并不扭曲其相位.

  * 实现简单. 在大多数DSP处理器, 只需要对一个指令积习循环就可以完成FIR计算.

  * 适合于多采样率转换,它包括抽取(降低采样率), 插值(增加采样率)操作. 无论是抽取或者插值, 运用FIR滤波器可以省去一些计算, 提高计算效率. 相反,如果使用IIR滤波器,每个输出都要逐一计算,不能省略,即使输出要丢弃.

  * 具有理想的数字特性. 在实际中,所有的DSP滤波器必须用有限精度(有限bit数目)实现,而在IIR滤波器中使用有限精度会产生很大的问题,由于采用的是反馈电路,因此IIR通常用非常少的bit实现,设计者就能解决更少的与非理想算术有关的问题。

  * 可以用小数实现. 不像IIR滤波器,FIR滤波器通常可能用小于1的系数来实现。(如果需要,FIR滤波器的总的增益可以在输出调整)。当使用定点DSP的时候,这也是一个考虑因素,它能使得实现更加地简单。

1.6.2 相较于IIR滤波器, FIR滤波器的缺点是什么?

  相比较于IIR滤波器, 有时FIR滤波器为了得到一个给定的滤波响应特性,需要花费更多的存储器或者计算. 当然,用FIR滤波器去实现某些响应也是不实际的.

1.7 在描述FIR滤波器的时候,都要提到什么术语?

  * 冲激响应 - FIR滤波器的冲激响应实际上是FIR的系数.

  * 抽头(Tap) - FIR的抽头是系数或者延时对.FIR抽头的个数(通常用N来表示)意味着:1)实现滤波器所需要的存储空间, 2) 需要计算的数目, 3) 滤波器能滤掉的数量, 实际上,越多的抽头意味着有更多的阻带衰减, 更少的波纹,更窄的滤波等等.

  * 乘累加 (MAC) - 在FIR方面考虑,MAC是指把延时的数据采样与相应的系数相乘,然后累加结果。通常,FIR每一个抽头都需要一个MAC。大多数DSP微处理器实现MAC操作都是单指令周期。

  * 跃迁带(Transition Band) -在通带和阻带边沿之间的频带。跃迁带越窄,需要更多的抽头去实现滤波器。也有说,小的跃迁带就是一个sharp滤波器。

  * 延时线- 一组存储器单元,实现在FIR计算中的Z^-1延时。

  * 环形缓存 - 一个特殊的缓存,是首尾相连的。通常由DSP微处理器实现。


Part 2: Properties

2.1 线性相位

2.1.1 FIR滤波器和线性相位之间有什么关系?

  大多数的FIR滤波器是线性相位滤波器. 当需要设计线性相位滤波器时, 通常使用FIR滤波器.

2.1.2 什么是线性相位滤波器?

  线性相位是指滤波器的相位响应是频率的线性函数(在+/-180度)。因此滤波器的延时后,所有的频率相位相同。因而滤波器不会产生相位和延迟扭曲。在某些领域,比如数字解调器,没有相位或者延迟扭曲是FIR滤波器相对于其他IIR和模拟滤波器的一个关键优点

2.1.3 线性滤波器的条件是什么?

  FIR滤波器经常被设计成为线性相位的,当然不是必须要这么做。如果滤波器的系数是关于中心系数对称的,也就是说第一个系数和最后一个系数相同,第二个系数和倒数第二个相同,那么FIR滤波器就是线性的。有奇数个系数的FIR滤波器,中心单独的系数没有对应的。

2.1.4 什么是线性相位FIR滤波器的延时?

  非常简单的公式: 给定FIR滤波器有N个抽头,那么延时是(N - 1) / (2 * Fs), 这里Fs是采样频率. 比如, 21抽头的线性相位滤波器运行在1kHz, 那么延时就是(21 - 1) / (2 * 1 kHz)=10 微秒.

2.1.4 除了线性相位,还可以选择什么?

  当然是非线性的了。实际上,最流行的选择是最小相位滤波器。小相位滤波器,也叫最小延时滤波器,比线性相位滤波器具有更少的延时,当两者的幅度响应相同时以非线性相位特性。低通滤波器在它的冲击响应中心有最大的系数。而最小相位滤波器的最大系数在开始部分。

2.2 频率响应

2.2.1 什么是FIR滤波器的Z变换r?

  对于N抽头的滤波器, 系数为h(k), 那么输出由:        

  y(n)=h(0)x(n) + h(1)x(n-1) + h(2)x(n-2) + ... h(N-1)x(n-N-1),

滤波器的z变换就是:       

  H(z)=h(0)z-0 + h(1)z-1 + h(2)z-2 + ... h(N-1)z-(N-1) , or

        http://blog

2.2.2 FIR滤波器的频率响应公式是什么?

  H(z)中的变量z为连续的复数变量,可以描述为 z="r"·ejw,这里r是幅度,w是z的角度。如果令r=1,H(z)就变成了滤波器频率响应H(jw)。这也就意味着替代z为ejw,得到了滤波器频率响应H(w)。       

  H(jw)=h(0)e-j0w + h(1)e-j1w + h(2)e-j2w + ... h(N-1)e-j(N-1)w , or

使用欧拉公式, e-ja=cos(a) - jsin(a), 我们可以把H(jw)写成矩形表示:      

  H(jw)=h(0)[cos(0w) - jsin(0w)] + h(1)[cos(1w) - jsin(1w)] + ... h(N-1)[cos((N-1)w) - jsin((N-1)w)] , or

   http://blog

2.2.3 能用离散傅立叶变换(DFT)来计算FIR的频率响应么?

  可以。对于N抽头的FIR,可以得到N  evenly-spaced points of the frequency response by doing a DFT on the filter coefficients.但是,为了得到任意频率的频率响应,需要使用上边的公式。

2.2.4 FIR滤波器的DC增益指的是什么?

  DC(0 Hz)输入信号包含每个采样都为1.0。通过延时线后,输出是所有系数的和。因而,在DC处滤波器的增益就是所有系数之和。  

  可以通过上边的公式进行验证。问我们设w为0, cos项就一直为1,而sin项则一直为0。因此频率响应就变成了:

       http://blog

2.2.5 如何调整FIR滤波器的增益?

  简单地在系数上乘上因子.

2.3 数字性质

2.3.1 FIR滤波器是固有稳定的?

  是的,因为没有反馈,任何有限的输入产生有限的输出。

2.3.2 什么使FIR滤波器的数字性质变好?

  缺少反馈是关键。在计算机中实现FIR滤波器时,每个计算都产生数字错误。由于FIR滤波器没有反馈,因此不能够记住以前的错误。相反,IIR滤波器的反馈可能导致错误的积累。这个实际的影响就是,可以用更少的bit去实现与IIR滤波器相同精度的滤波器。比如,FIR滤波器通常用16位来实现的话,IIR滤波器就通常需要32位,或者更多。

2.4 为什么通常在多采样率系统中采用FIR滤波器而不采用IIR滤波器?

  因为只有一小部分的计算需要用减采样或者插值滤波器来实现。

  由于FIR滤波器不使用反馈,因而只有那些实际需要使用的输出才需要计算。比如,在减采样的时候(N个输出中只有一个有效),那么其他的N-1输出就不会进行计算。类似的,对于插值滤波器(在采样点中插入0来提高采样率),你不必实际地用FIR滤波器乘以系数,求和得到,你只需要忽略和这些值有关的乘加(因为它们不会改变结果)。

  相反,因为IIR滤波器使用反馈,每个输入都必须使用,每个输入必须计算,因为所有的输入和输出对滤波器的反馈都有影响。

2.5 有哪些特殊的FIR滤波器?

  Aside from "regular" and "extra crispy" there are:

  *  矩形 -矩形 FIR 滤波器是每个系数都是1.0的简单的滤波器。因而对于N个抽头的矩形滤波器,它的输出仅仅是过去N个采样之和。由于矩形FIR只能实现加法,因此当乘法器实现比较昂贵时,在硬件实现中会考虑。         

  * 希尔伯特变换(Hilbert Transformer) - 希尔伯特变换是把信号相移90度。它们经常被用在给定实数部分,产生虚数部分。  

   * 差分(Differentiator) -差分器的幅度响应是频率的线性函数。现在已经不流行了,但是以前曾经在FM解调器上使用过。 

  *  Lth-Band - 也叫做“Nyquist"滤波器,这些滤波器是在多速率应用中特殊的一类滤波器。主要的卖点是,每L个系数有一个为0,那么就将减少乘累加操作的实现(著名的半带滤波器就是这一种)。 

   * Raised-Cosine - 这是一种特殊类型的滤波器,有时会用在数字数据应用方面。(通带上的频率响应是被上移一个常数的cos形状)。


Part 3: Design

3.1 有哪些设计FIR滤波器的方法?

三种最流行的设计方法:

  • Parks-McClellan: Parks-McClellan 方法( MATLAB里用Remez)是设计FIR滤波器中可能是使用最光的.method (inaccurately called "Remez" by Matlab) is probably the most widely used FIR filter design method. It is an iteration algorithm that accepts filter specifications in terms of passband and stopband frequencies, passband ripple, and stopband attenuation. The fact that you can directly specify all the important filter parameters is what makes this method so popular. The PM method can design not only FIR  "filters" but also FIR "differentiators" and FIR "Hilbert transformers".
  •  Windowing:. In the windowing method, an initial impulse response is derived by taking the Inverse Discrete Fourier Transform (IDFT) of the desired frequency response. Then, the impulse response is refined by applying a data window to it.
  •  Direct Calculation: The impulse responses of certain types of FIR filters (e.g. Raised Cosine and Windowed Sinc) can be calculated directly from formulas.

3.2 如何实际地设计FIR滤波器?

  当然是用FIR设计程序呀. 虽然可以使用手工亲自的方法进行设计滤波器,但是使用FIR滤波器程序比较简单.


Part 4: Implementation

4.1 实现FIR滤波器基本的方法是什么?

  FIR滤波器的结构上包含两个东西:一个是采样点延迟线,一个是系数. 可以由以下方法实现FIR滤波器:

  1. 把输入的采样点放入到延迟线中.

  2. 把延迟线中的数与相应的系数相乘并累加.

  3. 移位, 使下一个输入采样能进入延迟线.

4.2 用C语言如何实现FIR滤波器?

  为了展示众多的方法和技巧,这里提供用C语言实现的FIR滤波器算法。

http://blog fir_algs_1-0.c C 源码

http://blog fir_algs_1-0.zip C 源码( MS Visual C++ 6.0 工程文件)


包括以下功能模块:

  1. fir_basic: 实现基本的FIR滤波器

  2. fir_circular: 说明环行buffer是如何实现FIR的。

  3. fir_shuffle: 一些TI的处理器上使用的shuffle down技巧

  4. fir_split: 把FIR滤波器展开为两块,避免使用环行缓存。

  5. fir_double_z: 使用双精度的延迟线,使可以使用一个flat buffer。

  6. fir_double_h: 使用双精度的系数,使可以使用一个flat buffer。

4.3 用汇编如何实现FIR滤波器?

  FIR滤波器的汇编算法是跟处理器对应的,但是大多数普通的系统会使用一个DSP处理器提供的环行缓存。

  1. 配置环行缓存。加载系数和延迟线指针。然后对每个采样点执行以下操作:

  2. Store the incoming data in the delay line; increment the delay-line pointer.Digital

  3. Clear the multiplier-accumulator.

  4. Loop over all coefficients/delays; accumulate the values obtained by multiplying the coefficients by the delayed samples.

  5. Round or truncate the result as the FIR output.   

  Alternatively, a "shuffle down" method is used in Texas Instruments' older fixed-point processors to implement circular buffers. The processor literally moves each sample delay values by one slot during each multiply-accumulate (via the "MACD" instruction).    

  Each DSP microprocessor manufacturer provides example FIR assembly code in its data books or its application handbooks, so be sure to look at those before you "reinvent the circular buffer".

4.4 如何测试以及实现的FIR滤波器? 

  Here are a few methods:

  •  Impulse Test: A very simple and effective test is to put an impulse into it (which is just a "1" sample followed by at lest N - 1 zeroes.) You can also put in an "impulse train", with the "1" samples spaced at least N samples apart. If all the coefficients of the filter come out in the proper order, there is a good chance your filter is working correctly. (You might want to test with non-linear phase coefficients so you can see the order they come out.) We recommend you do this test whenever you write a new FIR filter routine.
  •  Step Test: Input N or more "1" samples. The output after N samples, should be the sum (DC gain) of the FIR filter.
  •  Sine Test: Input a sine wave at one or more frequencies and see if the output sine has the expected amplitude.
  •  Swept FM Test: From Eric Jacobsen: "My favorite test after an impulse train is to take two identical instances of the filter under test, use them as I and Q filters and put a complex FM linear sweep through them from DC to Fs/2. You can do an FFT on the result and see the complete frequency response of the filter, make sure the phase is nice and continuous everywhere, and match the response to what you'd expect from the coefficient set, the precision, etc."

4.5 在实现FIR滤波器的过程中有什么有用的技巧?   

  FIR tricks center on two things 1) not calculating things that don't need to be calculated, and 2) "faking" circular buffers in software.

4.5.1 如何跳过不必要的计算?   

  First, if your filter has zero-valued coefficients, you don't actually have to calculate those taps; you can leave them out. A common case of this is "half-band" filter, which have the property that every-other coefficient is zero.   

  Second, if your filter is "symmetric" (linear phase), you can "pre-add" the samples which will be multiplied by the same coefficient value, prior to doing the multiply. Since this technique essentially trades an add for a multiply, it isn't really useful in DSP microprocessors which can do a multiply in a single instruction cycle. However, it is useful in ASIC implementations (in which addition is usually much less expensive than multiplication); also, some newer DSP processors now offer special hardware and instructions to make use of this trick.

4.5.2 How do I fake circular buffers in software?   

  When hardware support for circular buffers isn't available, you have to "fake" them. Also, since ANSI C has no construct to describe circular buffers, most C compilers can't generate code to use them, even if the target processor has them.   

  You can always implement a circular buffer by duplicating the logic of a circular buffer in software (and many have), but the overhead can be prohibitive; the circular-fake might take several instructions to implement, compared to just a single instruction to do the multiply-accumulate operation. Therefore you need to fake it.   

  Here are several basic techniques to fake circular buffers:      

  1. Split the calculation: You can split any FIR calculation into its "pre-wrap" and "post-wrap" parts. By splitting the calculation into these two parts, you essentially can do the circular logic only once, rather than once per tap. (See fir_double_z in FirAlgs.c above.)      

  2. Duplicate the delay line: For a FIR with N taps, use a delay line of size 2N. Copy each sample to its proper location, as well as at location-plus-N. Therefore, the FIR calculation's MAC loop can be done on a flat buffer of N points, starting anywhere within the first set of N points. The second set of N delayed samples provides the "wrap around" comparable to a true circular buffer. (See fir_double_z in FirAlgs.c above.)      

  3. Duplicate the coefficients: This is similar to the above, except that the duplication occurs in terms of the coefficients, not the delay line. Compared to the previous method, this has a calculation advantage of not having to store each incoming sample twice, and it also has a memory advantage when the same coefficient set will be used on multiple delay lines. (See fir_double_h in FirAlgs.c above.)      

  4. Use block processing: In block processing, you use a delay line which is a multiple of the number of taps. You therefore only have to move the data once per block to implement the delay-line mechanism. When the block size becomes "large", the overhead of a moving the delay line once per block becomes negligible.

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(197)
发表于:2008-4-26 10:49:24
标签:无标签

1

十个习惯让你精通新的开发技术(转自CSDN)

这篇文章,是从我的《高效开发人员的五个特征》一文中抽出的一个观点。从我自身的事业和习惯中,我考虑了很多方式怎么样才能有效地学习。

1. 要看书。在成千上万的编程图书中,可能很大一部分根本毫无用处。但是仍然有很多图书对你的(编程)能力有很大的提升。我一直坚持,相比在网络上查找很多有用信息,在同类图书中查找要来得更容易更快捷。阅读设计等方面来说,图书也一样很有帮助。只不过要找到高质量的、权威的信息,就不如网络上可供查找的范围广。

2. 读代码。这也是我很喜欢的一种方式。如果我并没有几年的专业编程工作经验,在学习之初我并不会去读很多复杂的代码。如果我要是早些开始学习,我将是一个比现在更好的程序员。但是,开始时我会从一些开源项目里,去学习那些源代码(当然,这些代码不能与我的工作有关,也不是我自己写的)。要从自己会使用到的,或者自己感兴趣的程序开始这项工作。我是从 Paint.net 这个网站里开始学习的,而且已经积累了很多关于 .NET 的编程技术。

读别人的代码可以为你提供更多不同的工作思路,这比你完全凭自己思考得到的工作方式要多。

3. 写代码。谨记,要写大量的代码。从根本上来讲,最好的学习方法就是实践。如果不写代码,你根本不能把(某种语言中)内在的东西学习透彻。学习之初,可以从一些技术指南和图书中照搬一些尽量简单的程序。当然,这种照搬是要自己完全手工输入,而不是复制和粘贴,这两种之间的效果差别是很大的。这种方法的主旨就在于,使知识内在化,并思考其用法,而不是盲目照抄。学习过程中,要时常查找新的 API 调用方法,这其实是简单的事情。

最重要的是,要写一个你自己的程序,不管它是一个简单的游戏,或者是一个参与开源项目的程序,还是一个公为你自己使用的简单插件。用不同的方式来写程序,尽量尝试使用新的技术,新的技巧,新的设计方式。一定要让现在的项目比以往的项目更好。想要成一个优秀的开发者,这一点是核心。

4. 与其他开发者交流。像 Apple,微软,Google 等大公司一样的新闻描述的一样,(与其他开发者交流)可以让你解决一些复杂的问题。虽然这并不能让你感觉到自己已经成一个团队或是社区的成员,但是这种方法可以让你接触到更多不同的想法。

不同类型的项目要求不同的设计方法,代码技术,开发流程和设计思想。如果你工作在一个小团队里,你不必与太多的人接触,只要在用户群会议中找到一些人(来讨论)即可。如果这样还不行的话,参与到在线论坛中与其他人讨论(这时你需要更努力地寻找高质量的讨论内容)。

6. 教会别人。相对于仅仅读代码之类的工作,教其他人学习可以让你更深入地学习某个技术,这种方法有着非凡的效果。教会别人某个技术,同样也会让你更专注于这种技术,并且可以比别人更深层次地理解它。同样你也会面对一些问题。

“如果你不能向一个六岁的儿童解析清楚一个概念,那么其实是你并没有完全理解它。”Albert Einstein说。

教学场景可以是无穷无尽的:与工作搭档一对一交流,休息碰面,非正式周会,学习茶会,教室,讨论发表会,等等。每周在相同理念开发者之间举办一次30分钟的非正式会议怎么样?每周,让几个人来就他们想要更深入了解话题,向大家传授这些技术知识,并且展开讨论。如果你知道你将要向团队成员们传授正学学习的知识,你是不是更想要了解这项技术的每个细节呢?

6. 收听网络电台。如果你有空闲的时间,可以订阅网络电台节目。我现在最喜欢的编程节目就是 .Net Rocks。这个节目还会做一些视频节目,叫做 dnrTV 。这样会让你即时捕捉到最新最好的技术。一个人是不能学习到所有知识的,而网络电台刚是一个学习了解广泛知识的途径。

7. 阅读博客。博客远远比阅读者要多,但是其中有一些却是极其优秀的。我这里不并不是要推荐博客,因为网络上已经有了足够多的博客。这是与真正在开发你所喜欢和使用的软件的开者联系的好方法。

8. 学习新的语言。即使你已经在 C(++,#) / JAVA 等语言上有很好的造诣,仍然有很多其他可以解决问题的编程语言。学习新的语言,是对你已有思维方式的挑战。这不仅仅是另一种语言,更是对思维的重新架构。的确,所有的语言最后都会被编译成汇编程序,但是这并不意味着高级语言毫无价值。

9. 学习不正确的方式。除了要学习应该怎么做,还要学习不应该怎么做。经常阅读 Dailywtf.com ,学习你并不知道的经验与教训。学习适当的面向对象设计方式,代码写作方式,和必须要写的代码等,是很好的方式,但是如果不细心的话也容易养成不良习惯。学习认识不正确的思路是负责项目开发至关重要的一环。

维基百科对很多觉的不正确方式有十分透彻的分类。

10. 要谦虚。

学习,意味着:

  • 用更好的知识代替不完美的知识
  • 增长你所不知道的知识

只有承认自己有所不足,才能有学习的动力。归根到底,就是谦虚,不对吗?如果你开始认为你已经掌握了所有需要的知识,那么你就危险了。真正的学习是如饥似渴地追逐知识并使其内在化,这需要很大的努力。我们都知道这一点,但是要必须时常不断地提醒自己。

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(134)
发表于:2008-4-22 20:14:38
标签:无标签

0

CRC16 原理

CRC16 原理
 

这里,不讨论CRC的纠错原理以及为什么要选下面提及的生成多项式,只是针对以下的生成多项式,如何获得CRC校验码,作一个比较详细的说明。

   标准CRC生成多项式如下表:

   名称        生成多项式              简记式*   标准引用
   CRC-4       x4+x+1                  3         ITU G.704
   CRC-8       x8+x5+x4+1              0x31                   
   CRC-8       x8+x2+x1+1              0x07                   
   CRC-8       x8+x6+x4+x3+x2+x1       0x5E
   CRC-12      x12+x11+x3+x+1          80F
   CRC-16      x16+x15+x2+1            8005      IBM SDLC
   CRC16-CCITT x16+x12+x5+1            1021      ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
   CRC-32      x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
   CRC-32c     x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
                             
   生成多项式的最高位固定的1,故在简记式中忽略最高位1了,如0x1021实际是0x11021。
I、基本算法(人工笔算):
   以CRC16-CCITT为例进行说明,CRC校验码为16位,生成多项式17位。假如数据流为4字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0];
数据流左移16位,相当于扩大256×256倍,再除以生成多项式0x11021,做不借位的除法运算(相当于按位异或),所得的余数就是CRC校验码。
发送时的数据流为6字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0]、CRC[1]、CRC[0];

II、计算机算法1(比特型算法):
1)将扩大后的数据流(6字节)高16位(BYTE[3]、BYTE[2])放入一个长度为16的寄存器;
2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式异或;
    否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);
3)重复第2步,直到数据流(6字节)全部移入寄存器;
4)寄存器中的值则为CRC校验码CRC[1]、CRC[0]。

III、计算机算法2(字节型算法):256^n表示256的n次方
    把按字节排列的数据流表示成数学多项式,设数据流为BYTE[n]BYTE[n-1]BYTE[n-2]、、、BYTE[1]BYTE[0],表示成数学表达式为BYTE[n]×256^n+BYTE[n-1]×256^(n-1)

+...+BYTE[1]*256+BYTE[0],在这里+表示为异或运算。设生成多项式为G17(17bit),CRC码为CRC16。
    则,CRC16=(BYTE[n]×256^n+BYTE[n-1]×256^(n-1)+...+BYTE[1]×256+BYTE[0])×256^2/G17,即数据流左移16位,再除以生成多项式G17。
    先变换BYTE[n-1]、BYTE[n-1]扩大后的形式,
    CRC16=BYTE[n]×256^n×256^2/G17+BYTE[n-1]×256^(n-1)×256^2/G17+...+BYTE[1]×256×256^2/G17+BYTE[0]×256^2/G17
         =(Z[n]+Y[n]/G17)×256^n+BYTE[n-1]×256^(n-1)×256^2/G17+...+BYTE[1]×256×256^2/G17+BYTE[0]×256^2/G17
         =Z[n]×256^n+{Y[n]×256/G17+BYTE[n-1]×256^2/G17}×256^(n-1)+...+BYTE[1]×256×256^2/G17+BYTE[0]×256^2/G17
         =Z[n]×256^n+{(YH8[n]×256+YHL[n])×256/G17+BYTE[n-1]×256^2/G17}×256^(n-1)+...+BYTE[1]×256×256^2/G17+BYTE[0]×256^2/G17
         =Z[n]×256^n+{YHL[n]×256/G17+(YH8[n]+BYTE[n-1])×256^2/G17}×256^(n-1)+...+BYTE[1]×256×256^2/G17+BYTE[0]×256^2/G17
    这样就推导出,BYTE[n-1]字节的CRC校验码为{YHL[n]×256/G17+(YH8[n]+BYTE[n-1])×256^2/G17},即上一字节CRC校验码Y[n]的高8位(YH8[n])与本字节BYTE[n-1]异或,

该结果单独计算CRC校验码(即单字节的16位CRC校验码,对单字节可建立表格,预先生成对应的16位CRC校验码),所得的CRC校验码与上一字节CRC校验码Y[n]的低8位(YL8[n])

乘以256(即左移8位)异或。然后依次逐个字节求出CRC,直到BYTE[0]。
    字节型算法的一般描述为:本字节的CRC码,等于上一字节CRC码的低8位左移8位,与上一字节CRC右移8位同本字节异或后所得的CRC码异或。   
    字节型算法如下:
    1)CRC寄存器组初始化为全"0"(0x0000)。(注意:CRC寄存器组初始化全为1时,最后CRC应取反。)
    2)CRC寄存器组向左移8位,并保存到CRC寄存器组。
    3)原CRC寄存器组高8位(右移8位)与数据字节进行异或运算,得出一个指向值表的索引。
    4)索引所指的表值与CRC寄存器组做异或运算。
    5)数据指针加1,如果数据没有全部处理完,则重复步骤2)。
    6)得出CRC。

unsigned short GetCrc_16(unsigned char * pData, int nLength)
//函数功能:计算数据流* pData的16位CRC校验码,数据流长度为nLength
{
    unsigned short cRc_16 = 0x0000;    // 初始化
   
    while(nLength>0)
    {
        cRc_16 = (cRc_16 << 8) ^ cRctable_16[((cRc_16>>8) ^ *pData) & 0xff]; //cRctable_16表由函数mK_cRctable生成
        nLength--;
        pData++;
    }
   
    return cRc_16;   
}


void mK_cRctable(unsigned short gEnpoly)
//函数功能:生成0-255对应的16CRC校验码,其实就是计算机算法1(比特型算法)
//gEnpoly为生成多项式
//注意,低位先传送时,生成多项式应反转(低位与高位互换)。如CRC16-CCITT为0x1021,反转后为0x8408
{
unsigned short cRc_16=0;
unsigned short i,j,k;

for(i=0,k=0;i<256;i++,k++)
{
      cRc_16 = i<<8;
      for(j=8;j>0;j--)
      {
if(cRc_16&0x8000)                 //反转时cRc_16&0x0001
             cRc_16=(cRc_16<<=1)^gEnpoly; //反转时cRc_16=(cRc_16>>=1)^gEnpoly
         else
             cRc_16<<=1;                   //反转时cRc_16>>=1
      }
      cRctable_16[k] = cRc_16;
}
}

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(426)
发表于:2008-4-15 10:08:45
标签:无标签

0

两种“软件陷阱技术”的比较

引 言

  单片机应用系统的抗干扰具体可分为软件和硬件两方面,其中,软件抗干扰以其设计灵活、节省硬件资源、降低成本等优势越来越得到广泛采用。软件抗干扰技术主要有“指令冗余技术”、“软件陷阱技术”、“软件看门狗技术”、“数字滤波技术”等。本文就软件陷阱技术对单片机应用系统抗干扰的原理与具体实现方法进行探讨和研究,给出实现软件陷阱技术的两种形式,并将该技术成功地使用在多个实际的单片机应用系统中,保证系统的可靠运行。

  1 程序跑飞和软件陷阱技术概述

  程序正常运行时,程序计数器PC始终指向正在执行的这条指令的下一条指令的第一个字节的程序存储器单元地址,这样就保证了单片机能够正确地读取每一条指令的各个字节,即CPU先读取操作码,再读取操作数(如果有操作数字节的话)。在MCS-51系列单片机中,程序计数器PC的寻址范围是0000H~FFFFH,共64 KB。用户应用程序中,根据系统要求,规定了程序运行的惟一路径。这体现在系统上电后,程序计数器PC有唯一的变化历程,保证了程序正常、有序地运行。程序跑飞是指系统受到某种干扰后,程序计数器PC的值偏离了给定的唯一变化历程,导致程序运

行偏离正常的运行路径。程序跑飞因素及后果往往是不可预计的。

  在很多情况下,程序跑飞后系统会进入死循环而导致死机。这时,应采取有效措施引导跑飞的程序尽快退出死循环并迅速复位。实践证明,软件陷阱技术能有效引导跑飞的程序尽快退出死循环并迅速复位。

  2 两种软件陷阱技术的比较分析

  当单片机应用系统的CPU受到干扰时,不良影响的主要形式有:①非正常修改程序计数器PC指针;②改写可编程输出端口的状态;③非正常修改重要数据区的数据。以上三个方面的不良影响会使单片机应用系统程序失控,控制状态失灵,其后果是非常严重的,它甚至会使系统崩溃,造成严重的工业事故。以上几个方面的不良影响可以使用软件陷阱技术加以解决。现将这一技术的实现方法归纳总结为两种。

  2.1 软件陷阱技术实现形式之一

  单片机应用系统的用户应用程序一般由循环结构的主程序和中断服务子程序组成,主程序的结构如图1所示。将下面的软件陷阱程序段插入到用户应用程序中(如何插入的问题将在下面的第3点中详细讨论),即在用户应用程序存储器不用区域写入代码“OO00020000H”。

      NOP
    NOP
    LJMP O000H

主程序的结构图

  当单片机应用系统工作正常时,单片机的CPU不会执行软件陷阱程序段;但是,当单片机应用系统受到干扰而程序跑飞后,由于程序计数器PC值错误,破坏了正常的指令格式,导致执行非正常指令,从而执行软件陷阱程序段,落入软件陷阱,将跑飞的程序引导到复位入口地址0000H。软件陷阱程序段中的连续2条NOP指令是为了增强“LJMP 0000H”被捕获的能力,即“IJMP0000H”不会被冲散,当程序跑飞后会得到完整地执行,从而使跑飞的程序纳入正常轨道。

  2.2 软件陷阱技术实现形式之二

  虽然上述的软件陷阱技术能实现可靠回复功能,但是有两个方面的严重隐患。第一,隐患主要是在对中断的处理上:首先,程序跑飞很可能是发生在中断服务子程序中,其次,一些未使用的中断很可能因为程序跑飞而被错误地激活,而这时只是简单地让跑飞的程序从头开始运行,就不能关闭已激活的中断,这样,单片机的中断系统会认为程序仍在处理中断,就不会再响应同级中断。第二,大部分单片机应用系统在上电复位初始化后,不希望在程序跑飞而用软件陷阱回复后又重新初始化。

  为了解决第一个隐患,当程序跑飞时,一定要想办法关闭可能发生的中断,然后再执行用户应用程序。大家知道,当CPU进入中断后,就只能用RETI指令关闭中断.解决第一个隐患的具体方法是,改变软件陷阱程序段:当程序跑飞后,将跑飞的程序引到0202H处,然后在0202H处完成关闭中断的工作,即在用户应用程序存储器不用区域写入代码“0000020202H”。需要注意的是,程序存储器不用区域的最后两个存储单元,一定要分别写入代码“00H”。

      NOP
    NOP
    LJMP 0202H ;前面的连续2条NOP指令是为了 
               ;增强“LJMP 0202H”被捕获的能力
    而在0202H开始的程序存储器单元进行如下的编程:
   ORG 0202H
    MOVDPTR,#ERRl
    PUSH DPL
    PUSH DPH
    RETI ;关闭第1级中断,并跳转到ERRl处
    ERRl: CLR A
    PUSH ACC
    PUSH ACC
    RETI ;关闭第2级中断,软件回复到0000H处

这样,就保证了无论在什么情况下,都可以关闭2级中断。当然,如果没有中断被激活时运行了这段程序,也不会有什么不良影响。

  为了解决第二个隐患,可以在系统主程序入口处加一个软件开关来判别是上电复位直接进入0000H的,还是经过软件

陷阱回复而进入0000H的,根据不同的判别结果执行不同的程序。

  单片机应用系统上电时,上电复位电路会使单片机处于复位状态。这一般称为冷启动。

  但是,软件陷阱技术使跑飞的程序回复到主程序入口地址0000H时,不影响特殊功能寄存器SFR的有效位。解决第二个隐患的具体方法是,设置上电复位标志。例如,以PSW.5作为上电标志位,当PSW.5=0时,表示是上电复位;当PSW.5=l时,表示是软件陷阱回复。图2是上电复位与程序跑飞后软件陷阱回复初始化处理框图。0000H是MCU的复位入口,程序启动后,首先判断是上电复位,还是程序跑飞后软件陷阱回复。上电复位是开机操作,要建立上电标志,并进行系统的完全初始化。程序跑飞后软件陷阱回复应该进行相关资源的检查与修复,以防止系统运行出错。另外,根据系统特点,需要保留一些过程数据,不得进行完全初始化。

程序启动后不同的初始化

  为了解决上述两个隐患,有如下具体编程。其中,START0为系统上电复位完全初始化于程序入口,ER-ROR为程序跑飞后软件陷阱回复应进行的系统部分初始化和相关资源的检查与修复程序入口,LOOP是用户应用程序功能模块入口。

      ORG0000H
    LJMP START
    ORG 0100H
    START: MOV C,PSW.5
    JC ERROR
    SETB C
    MOV PSW.5,C
    LCALL STARTO
    LJMP LOOP
    ERROR: ……
    L00P: …… ;应用程序功能模块
    LJMP LOOP
    ORG 0200H
    NOP
    NOP
    MOV DPTR,#ERRl
    PUSH DPL
    PUSH DPH
    RETl ;关闭第1级中断,并跳转到ERRl处
    CRRl: CLR A
    PUSH ACC
    PUSH ACC
    RETI ;关闭第2级中断,软件回复到0000H处

  3 软件陷阱在用户应用程序中的安排位置

  软件陷阱程序段可以插入到主程序中或者中断服务子程序中。根据实际应用情况,对软件陷阱程序段的位置安排可以有5种方式。

  (1)在主程序的应用功能模块之间

  在单片机应用系统程序设计时,将软件陷阱程序段分散地放在各应用功能模块之间空余的程序存储器单元里。当用户应用程序正常运行时,这些软件陷阱程序段并不会执行,但是,当单片机应用系统的CPU受干扰而使程序失控时,程序计数器PC指针一旦落入这些陷阱区,就可以马上将跑飞的程序拉回到正确的轨道。这种方法的确很有效。软件陷阱的多少一般依据用户应用程序大小而定,一般1KB的用户应用程序有2~3个软件陷阱就可以了,具体方法如下:

  • 应用功能模块1
  • 软件陷阱程序段
  • 应用功能模块2
  • 软件陷阱程序段

  (2)在闲置未使用的EPROM/Flash ROM空间

  在闲置未使用的EPROM/Flash ROM空间设置软件陷阱,即在这些闲置未使用的EPROM/Flash ROM空间写满代码“0000020202H”。值得注意的是,最后两个存储单元一定要分别写入代码“OOH”。当程序跑飞而进入此区后,便会被软件陷阱迅速拉回正常轨道。

(3)在中断服务子程序中

  软件看门狗(soltware watchdog)实际上是软件陷阱的一个应用实例。以MCS-5l系列单片机为例,在系统初始化时将MCU内部的定时器/计数器T0设置为定时器,并将TO定时溢出中断设置为高级中断.如果系统采用6 MHz时钟,可以用如下的初始化程序段使TO定时约130 ms来形成软件看门狗:

       · MOV TMOD, #01H ;将T0设置为16位定时器
     · SETB ETO ;允许TO中断
     · SETB PTO ;将TO定时溢出中断设置为高级中断
     · MOV TH0,#0;给TO赋初值,定时约130/ms
     · MOV TLO,#0
     · SETB TR0 ;启动T0开始定时
     · SETB EA ;允许CPU中断
     另外,TO定时溢出中断服务子程序编程如下:
     · INTO-PRo; MOV A,#02H
     · PUSH ACC
     · PUSH ACC
     · RET1 ;中断返回到0202H单元

  当用户应用程序运行正常时,在小于130 ms的时间内,CPU应该及时“喂狗”一一执行清狗指令“MOV THO,#0”和“MOV TLO,#0”。这样,TO就不会产生定时溢出,从而T0定时溢出中断服务子程序不会被执行。但是,当单片机应用系统的CPU受干扰而使程序失控时,CPU就不会及时执行清狗指令,以致于产生TO定时溢出中断,就可以马上将跑飞的程序拉回到正确的轨道。实现及时“喂狗”的具体方法是在用户应用程序中的适当位置插入指令“MOV TH0,#0”和“MOV TLO,#O”。实际上,TO定时溢出中断服务子程序就是一个软件陷阱,一旦执行T0定时溢出中断服务子程序,就是把跑飞的程序强行拉回到0202H程序存储器单元。由前面的分析可知,已经跑飞的程序可以迅速地被纳入正确的轨道。

  (4)在未使用的程序存储器地址空间

  对MCS-51系列单片机而言,程序计数器PC的寻址范围是0000H~FFFFH,共64 KB;然而,在实际的单片机应用系统中,一般没有使用到64 KB的程序存储器,这样就会余下大量的程序存储器地址空间。例如,系统中仅选用了1片2764作为程序存储器,其地址空间为8 KB。那么将有56 KB程序存储器地址空间被闲置。当CPU受到干扰而使程序计数器PC指向这些被闲置的程序存储器地址空间时,CPU取指令得到的指令代码为“0FFH”(这个结论可以根据图3所示电路分析后得出)。该代码是“MOV R7,A”指令的机器码。显而易见,当单片机应用系统的CPU受干扰而使程序失控时,程序计数器PC指针一旦落入这些被闲置的程序存储器地址空间时,CPU执行该指令不仅将错误地修改寄存器R7的内容,而且无法将跑飞的程序纳入正确的轨道。可以使用下面的软件陷阱技术解决这个问题。

在未使用的程序存储器地址空间设置软件陷阱

  如图3所示,EPROM芯片2764的地址空间为0000H~lFFFH,译码器74LSl38的输出Y0为其片选信号,2000H~FFFFH为未使用的程序存储器空间。当程序计数器PC的值落入2000H~FFFFH空间时,一定有Y0为高电乎;当取指令操作时,PSEN为低电平,则74LS244的选通信号有效,所以74LS244被选中。进一步分析图3所示电路可知,当用户应用程序失控而程序计数器PC指向被闲置的程序存储器地址空间2000H~FFFFH时,总线驱动器74LS244被选通,这时CPU通过总线读入的指令机器码为020202H,正好是一条转移指令“LJMP0202H”,这样,使程序计数器PC指向0202H程序存储器单元。由前面的分析可知,已经跑飞的程序可以迅速地被纳入正确的轨道。

  (5) 对外部RAM写操作实旆监控保护而设置软件陷阱

  在单片机应用系统的外部数据存储器RAM中,一般保存了大量的预置数据和程序运行时产生的中间数据。外部数据存储器RAM的写入是由“MOVX@DPTR,A”指令来完成的。当CPU受干扰程序跑飞而误执行了该指令时,就会改写RAM中内容,导致RAM中的重要数据丢失。为了减小这种RAM中数据丢失的可能性,应在外部RAM写操作之前,对写操作进行条件判断。如果条件满足才执行写入操作;如果条件不满足,则将写入操作屏蔽,并使程序落入陷阱,进入死循环。在程序落人死循环陷阱后,便只能由其他软、硬件抗干扰技术(如看门狗技术)使系统退出死循环陷阱,从而使系统恢复正常。具体源程序代码如下(不妨设要写入外部RAM的内容存放在累加器A中,要写入数据的外部RAM单元地址存放在DPTR中):

       · MOV 6EH, #55H
     · MOV 6FH, #OAAH
     ·  LCALL WRlTE
     · RET
     · WRITE:NOP
     · CINE 6EH,#55H, TRAP
    ;写入条件是(6EH)=#55H
     · CJNE 6FH,#OAAH,TRAP且(6FH)=#OAAH
     · MOVX @DPTR,A
     · NOP
     · M0V 6EH,#00H
     · M0V 6FH,#OOH
     · RET
     ·  TRAP, SJMP TRAP ;落入死循环陷阱

  4 结 论

  与第1种形式的软件陷阱技术比较,第2种形式的软件陷阱技术消除了两个严重的隐患,因此,第2种形式的软件陷阱技术是一种有效实用的单片机应用系统抗干扰技术。本文所介绍的软件陷阱技术已成功地使用在多个实际的单片机应用系统中,保证了系统的可靠运行。

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(138)
发表于:2008-4-15 10:06:38
标签:4-20mA  

0

为微控制器提供4到20mA回路的电路

在制造业设备的控制领域中,4到20mA的电流回路普遍存在。离散逻辑、微处理器和微控制器可以很容易使用控制方案的数字部分,例如:限制开关、按钮和信号灯。对初级微控制器而言, 4到20mA的输出接口存在问题。内置A/D转换器固然很好,但这样的设备对处理器来讲不经济。串行4到20mA芯片的确存在,但相对昂贵的,且需要串行设计,会使处理器价格过高。大部分低端芯片缺少专门的串行接口,并需要管脚编程。

  图1中的电路成本较低,不仅可以提供4到20mA的输出,而且提供数字反馈信号表征电流环中的明线。一个输出端口引脚用来输出电流,一个输入管脚用来监控回路线中的开路电流。这个电路的运行不需要电流环的开环反馈部分,为节省成本可省略这部分。

为微控制器提供4到20mA回路的电路

  电路由微处理器中简单的定时器输出驱动。定时器的占空比决定着电路的输出电流。第一个运放信号前端的RC网络调制来自处理器的脉动序列,以便运放认定其为直流电压。另外,这个网络确保即便输入接地时,最小输入电压也接近100mV,。当NPN晶体管Q1关闭时,最小电压确保第一个运放的反馈回路不会折回正极去。如果使用双极性供电,晶体管会有额外的电压在地电压下摆动,保

持其处于导通区而不被关断。NPN型晶体管Q1的射极电阻决定电流范围。微控制器由5V电压驱动,输出电流为20mA。而输入接地的输出电流小于1mA。12.5%的占空比驱动4mA的电流回路,显示了整个范围上的线性控制。尽管这并不是强制的,但大部分电流回路都有接地回路。第二个运放的目的是提供电流源,而不是前端电路的电流减小,提供接地回路。因此,PNP型晶体管Q3提供高位驱动。双极结合晶体管Q1和Q3满足成本考虑,但也可以用MOSFET获得稍好的性能。

  电路的开关反馈部分使微处理器分辨线路中存在的错误条件。处理器可执行报警,关机或其他控制功能来减少安全隐患。当开环情况发生时,Q3通过射-基极连接隔离整个回路电流,而通过680Ω电阻接到运放。电压经过680Ω电阻并导通Q2,导致微处理器处于逻辑为1的反馈。注意到,对这类控制系统的“零”输出状态而言,开环回路需要至少1mA电流表征开路的功能,这个电流低于正常的4mA。

  指令改变的响应时间约为500毫秒,对大多数的电流回路控制设备是可接受的,例如控制阀门。如果选择的微处理器有内置A/D转换器,响应时间通过消除输入滤波网络的两个多阶幅值而减少。如果使用单电源拓扑,运放的选择就很重要。运放维持接近其负极、地或轨的稳定性是很重要的指标。

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 整理

评论(0) | 阅读(158)
发表于:2008-4-15 9:44:50
标签:4-20mA  

0

基于MAXQ微控制器构建增强型智能4-20mA变送器

简单的环路工作

  在电流环路中,传感器的输出电压首先按比例转换成电流,一般4mA表示传感器的零电平输出,20mA表示满量程输出。远端接收器将4-20mA电流又转换为电压,利用计算机或显示模块做进一步处理。

  典型的4-20mA电流环电路包括四个部分:传感器/变送器、电压-电流转换器、环路电源和接收器/监视器。在环路供电的应用中,传感器驱动电压-电流转换器,其他三个部分串联连接,构成闭环回路(图1)。

4-20mA环路供电电路框图

图1. 4-20mA环路供电电路框图

  智能型4-20mA变送器

  传统上,4-20mA变送器包括一个安装在现场的器件,该器件感测物理参数并产生4-20mA标准范围内的比例电流。为适应工业需求,出现了称作“智能型变送器”的第二代4-20mA变送器,这种变送器采用微控制器(µC)和数据转换器调理远端信号。

  智能型变送器可以对增益和失调进行校准,通过将传感器模拟信号数字化(如RTD传感器和热电偶)实现线性化处理,用驻留在µC内部的数学算法处理信号,再将数字信号转换回模拟信号,结果以标准电流的形式沿环路传输。

  最新的第三代4-20mA变送器(图2)被认为是“增强型智能”变送器。它们增加了与4-20mA信号共享双绞线的数字通信功能。所提供的通信通道在传输传感器数据的同时,还可传输控制和诊断信号。

4-20mA增强型智能变送器框图

图2. 4-20mA增强型智能变送器框图

  智能型变送器所使用的通信标准是Hart协议,该协议基于Bell 202电话通信标准,采用频移键控(FSK)方式。其数字信号1和0分别由1200Hz和2200Hz频率表示。这些频率的正弦波叠加在传感器的直流模拟信号上,同时提供模拟和数字通信(图3)。

模拟和数字信号同时通信

图3. 模拟和数字信号同时通信

  因为FSK信号的平均值始终为零,4-20mA模拟信号在此过程中不受影响。数字状态每秒钟可以转换两到三次,而不会妨碍模拟信号。允许的最小环路阻抗为23。

  4-20mA增强型智能变送器对µC的基本要求

  要实现这种4-20mA电流环路应用,µC必须具备三种特定性能:

  串行接口,连接用于数据采集的ADC和用于设置环路电流的DAC。

  因为电流预算为4mA,所以要求低功耗。

  乘法-累加单元(MAC),既完成输入信号的数字滤波,又同时编码和解码Hart协议中的两种频率。

  选择µC

  MAXQ系列RISC µC具备上述所有必需的功能(图4)。

MAXQ µC架构框图

图4. MAXQ µC架构框图

  模拟功能

  MAXQ µC包含若干模拟功能。采用的时钟管理方案只对当前使用的模块提供时钟。例如,如果一条指令用到数据指针(DP)和算术逻辑单元(ALU),那么只给这两个模块提供时钟。这一技术降低了功耗和开关噪声。

  低功耗

  MAXQ µC具有先进的电源管理功能,通过动态地将µC处理速度与需要的性能水平相匹配,可使功耗降至最低。例如,工作量减少的情况下,功耗较低。要投入更多的处理能力时,µC就需要提高工作频率。

  软件可选的时钟分频操作,允许灵活地选择1、2、4或8个振荡器周期作为一个系统时钟周期。通过软件实现这一功能,因此µC在不需要增加额外硬件成本的情况下即可进入低功耗状态。

  还可为那些对功耗极其敏感的应用提供另外三种低功耗模式:

  PMM1: 256分频电源管理模式

  PMM2: 32kHz电源管理模式(PMME = 1,其中PMME是系统时钟控制寄存器的第2位)

  停止模式(STOP = 1)

  在PMM1模式下,一个系统时钟周期等于256个振荡器周期,µC降速工作,从而大大降低了功耗。在PMM2模式下,器件以32kHz振荡器作为时钟源,工作速度更低。使能的中断源发生中断时,可选的时钟返回功能可使器件快速退出电源管理模式,并返回到更快的内部时钟频率上。这些使能的中断源可以是外部中断、UART和SPI模块。所有这些功能使MAXQ µC的处理能力达到3MIPS/mA,性能远远超出最接近的其它处理器(图5)。

MAXQ与其他竞争产品的MIPS/mA性能比较

图5. MAXQ与其他竞争产品的MIPS/mA性能比较。

信号滤波处理

  MAXQ µC内部的MAC完成4-20mA应用所需的信号处理功能。模拟信号输入到ADC,在数字域滤波采样流。用以下等式可实现通用滤波功能:

  y[n] = bix[n-i] + aiy[n-i]

  式中,bi和ai分别表征系统的前馈和反馈响应特性。根据ai和bi的不同取值,数字滤波器可分为有限长冲激响应型(FIR)或无限长冲 激响应型(IIR)。当系统不包含反馈(所有ai = 0)时,滤波器为FIR型:

  y[n] = bix[n-i]

  然而,如果ai和bi都不为零,则滤波器是IIR型。

  从上面的FIR滤波器方程可以看出,主要的数学运算是将各输入采样乘以一个常数,然后将n个乘积累加。下面这段C程序可说明该运算:

  y[n]=0;

  for(i=0; i

  y[n] += x[i] * b[i]

  MAXQ µC的MAC需要4 + 5n个周期完成此运算,代码空间只有9个字(而传统µC和MAC需要12个字)。

  move DP[0], #x    ; DP[0] -> x[0]

  move DP[1], #b    ; DP[1] -> b[0]

  move LC[0], #loop_cnt   ; LC[0] -> number of samples

  move MCNT, #INIT_MAC  &nbs

p;; Initialize MAC unit

  MAC_LOOP:

  move DP[0], DP[0]    ; Activate DP[0]

  move MA, @DP[0]++    ; Get sample into MAC

  move DP[1], DP[1]    ; Activate DP[1]

  move MB, @DP[1]++    ; Get coeff into MAC and multiply

  djnz LC[0], MAC_LOOP.

  (MAXQ架构的数据存储器访问细节参见附录)。

  注意:在MAXQ的MAC中,装入第二个操作数时,自动执行被请求的操作,运算结果存入MC寄存器。还须注意:溢出前,MC寄存器宽度(40位)可以累加大量的32位乘法结果。该功能是对传统方法的改进,传统方法在每次基本操作后都要验证是否溢出。

  MAXQ2000 µC的独特性能

  低功耗、16位RISC微控制器MAXQ2000是Maxim MAXQ家族的第一个成员。它具有液晶显示器(LCD)接口,可驱动多达100 (-RBX)或132 (-RAX)段。MAXQ2000极为适合血糖监测应用,并且适合任何需要高性能、低功耗工作的应用。工作频率最大为14MHz (VDD > 1.8V)或20MHz (VDD > 2.25V)。

  MAXQ2000含有32k字的闪存(适合原型设计和小批量生产)、1k字RAM、3个16位定时器,以及1或2个通用同步/异步收发器(UART)。为了灵活起见,微控制器内核电源(1.8V)与I/O子系统电源独立。超低功耗的休眠模式使MAXQ2000成为便携式和电池供电设备的理想选择。

  MAXQ2000评估板

  功能强大的MAXQ2000 µC可以利用其评估板(EV)进行评估,该评估板提供了完整的MAXQ2000硬件开发环境(图6)。

 MAXQ2000评估板方框图

图6. MAXQ2000评估板方框图

  MAXQ2000评估板具有下列特点:

  板上MAXQ2000内核电源和VDDIO电源。

  可调电源(1.8V至3.6V),可用作VDDIO或VLCD电源。

  对应MAXQ2000所有信号和电源的插头引脚。

  独立的LCD子板连接器。

  LCD子板,装有3V、3.5位静态LCD显示器。

  连接串行UART (端口0)的RS-232电平驱动器,包括流量控制线。

  外部中断按钮和微控制器系统复位按钮。

  MAX1407多功能ADC/DAC芯片,连接到MAXQ2000的SPI总线接口。

  1-Wire接口和1-Wire EEPROM芯片。

  条型LED显示,指示端口引脚P0.7至P0.0的电平状态。

  JTAG接口,用于应用程序下载和在系统调试。

  因此,MAXQ2000评估板具备了构建智能型4-20mA变送器需要的所有功能:具有真正乘法-累加单元(用于滤波和频率编码/解码)的低功耗µC;转换传感器信号的ADC;产生模拟输出信号的DAC (图7)。加上一个低功耗Codec,如MAX1102,就可以实现一个HART调制解调器。

 MAXQ2000评估板方框图

图7. 基于MAXQ2000 µC的4-20mA变送器HART调制解调器的实现

  如果系统包含1 200Hz和2200Hz (分别代表1和0)频率编码器,同时要对这些频率进行检测,可以采用MAC实现HART调制解调器要求的这些功能。

  要产生所需的正弦波形,可以利用下述差分方程描述的两极点滤波器形式实现递归数字式谐振器:

  Xn = k * Xn-1 - Xn-2,

  式中,常数k等于2 cos(2*频率/采样率)。可以预先计算k的两个值,并存在ROM中。例如,要用8kHz采样率产生1200Hz频率,该值为k = 2 cos(2*1200/8000)。

  必须计算能使振荡器开始振荡的初始激励。如果 Xn-1和 Xn-2都为0,接下来的每个Xn也都将为0。要启动振荡器,将 Xn-1设为0, Xn-2采用如下设置:

  Xn-2 = -A*sin[2(频率/采样率)]

  在本例中,假设采用单位幅度的正弦波,该式简化为 Xn-2 = -1sin[(2(1200/8000)]。为进一步简化编码,首先,初始化两个中间变量(X1, X2)。X1初始化为0,X2为初始激励值(上面的计算结果),以启动振荡器。这样,要产生一个正弦波的采样,可进行下列运算:

  

X0 = kX1 - X2

   X2 = X1

   X1 = X0

  每个新的正弦值都需要一次乘法运算和一次减法运算。利用MAXQ µC的单周期硬件MAC,可以采用如下操作产生正弦波:

  move DP[0], #X1    ; DP[0] -> X1

  move MCNT, #INIT_MAC   ; Initialize MAC unit

  move MA, #k     ; MA = k

  move MB, @DP[0]++    ; MB = X1, MC="k"*X1, point to X2

  move MA, #-1     ; MA = -1

  move MB, @DP[0]--    ; MB = X2, MC="k"*X1-X2, point to X1

  nop       ; wait for result

  move @--DP[0], MC    ; Store result at X0.

  因为我们只需要检测两种频率,所以采用改进的Goertzel算法,这种算法可以用简单的二阶滤波器实现(图8)。

利用简单的二阶滤波器实现Goertzel算法

图8. 利用简单的二阶滤波器实现Goertzel算法

  要使用Goertzel算法检测特定频率,编译时要首先使用下式计算出常数:

   k = tone frequency/sampling rate

   a1 = 2cos(2k)

  随后,将中间变量D0、D1和D2初始化为0,并对每个收到的采样X进行下列计算:

   D0 = X + a1*D1 - D2

   D2 = D1

   D1 = D0

  得到足够多的采样值以后(采用8kHz采样率时,通常为205个采样),用最新计算出的D1和D2值进行下列计算:

   P = D12 + D22 - a1 * D1 * D2.

  这时,P包含了输入信号中测试频率的平方。

  要对两种频率解码,我们用两个滤波器处理每个采样。每个滤波器都有自己的k值和自己的一组中间变量,每个变量都是16位长,所以,整个算法需要48字节的中间存储器空间。

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(153)
总共 , 当前 /