[LinuxFocus-icon]
首页  |  站点地图  |  索引  |  搜索

新闻 | 过往期刊 | 链接 | 关于LF
This document is available in: English  Castellano  ChineseGB  Deutsch  Francais  Italiano  Turkce  

[Photo of the Author]
by Guido Socher (homepage)

关于作者:

Guido喜欢linux不仅因为从这个系统可以找到最大可能的乐趣还因为人们潜心于它的设计


目录:

 

带LCD显示及RS232接口的1Hz-100Mhz 频率计

[Illustration]

摘要:

本文继续讲述AT90S4433系列。我建议您们先阅读一下前面那篇关于Atmel 微处理器编程设计,并注意以下两点::

  1. 怎样安装和使用Linux AVR 开发环境以及如何建立用户硬件目标系统:
    2002 第五期, AVR单片机GCC编程
  2. 如何制作你自己的印制线路板
    2002 第五期, 给你的Linux服务器加一个LCD前控制面板
这一次我们设计一个可以从测量1Hz到100MHz的频率计。您也可以用它来记录事件,如多少人穿过马路等 (只要是一个有效的数字脉冲)。这个频率计有一个LCD显示屏,带有RS232接口,用来显示由linux系统 得出的数据。



 

绪论

正弦波或方波信号的频率是由每秒钟振荡的次数来表示的。为了检测一个持续的信号的频率, 我们仅仅只需数它的振荡次数就可以了。这种方法我们需要检测这个持续振荡信号的第一个 谐波的频率。为了测量非连续音频信号,你必须要有一个频谱分析仪才能做到。 可是,对于硬件来说,这是一个很难的部分。现在,我们要设计一个用来测量持续振荡信号 的频率计。假设我们所取样的信号在某个时间段内频率是不变的。

我们的频率计分两步工作:
  1. 通过一个比较电压来减小一些信号的直流分量并把它转换成方波信号。
  2. 在每个时间段内数出脉冲数,并按一固定的时间段来划分。
 

所需器件

要搭建这个频率计你需要以下器件:

1 x Atmel At90S4433 Microcontroller
1 x 28pin 7,25 mm IC socket
2 x 16pin IC socket
1 x 1pin IC socket
1 x 14pin IC socket
No IC sockets for the MAX903 and the 74F74. Solder them directly to the board!
1 x MAX232
1 x 4,194304MHz crystal
1 x LEDs (green)
1 x BC557 PNP transistor
4 x 1uF capacitor (biased)
2 x 27pF ceramic capacitor
4 x 10nF mini ceramic capacitor
3 x 100nF mini ceramic capacitor
1 x 200nF mini ceramic capacitor
1 x 0,47uF mini ceramic capacitor
2 x resistor 470 Ohm
1 x resistor 470K
2 x resistor 100 Ohm
3 x resistor 1k
5 x resistor 10k
3 x resistor 47K
1 x resistor 220 Ohm
3 x resistor 4K7
1 x resistor 3k3
1 x resistor 2k2
1 x resistor 47 Ohm
1 x 4K7 potentiometer (as small as possible), if you want you can replace this potentiometer by a pair of resistors. This potentiometer is used to set the LCD contrast. For my LCD displays 100Ohm together with 1K gives a good contrast.
1 x Z-diode 4.3V
2 x small touch buttons
1 x 470uF capacitor (biased)
1 x 4,7uF capacitor (biased)
1 x 1N4001 diode
1 x 74HC02 TTL IC
1 x 74F74 fast TTL IC
1 x 74HC390 TTL IC
1 x LM393 voltage comparator
1 x MAX903 high speed voltage comparator, 8 Pin plastic DIP package, you can order it directly from www.maxim-ic.com in case your local dealer does not have it in stock.
1 x 7805 5V regulator
1 x 2 line 20 character LCD display with HD44780 compatible interface. With our without backlight (16 pin or 14 pin)

All LCD displays that I have ever seen with 14 or 16 pins on the connector were HD44780 compatible. You can also use a 3 or 4 line display but then you will need to modify the software a bit.

另外,您还需要一些线、连接头(BCD、电源、RS232)及及一个9V的变压器或者交、 直流供电源(150mA)。有时候您也可以通过直接插在墙壁上的用于给各种电器提供电 源的供电盒来得到电源。  

原理图和线路板图

我使用运行在linux下的 eagle 来设计原理图和线路板. 这个软件有一些让人不易理解的地方:所有的芯片电源输入都是5V。可是在进行电气规则 检查的时候会发现一些错误,事实上,设计是完全正确的
原理图 (点击放大):
[Schematic]

线路板图 (点击放大):
[board]


线路图是特别为一些电子爱好者设计的。只有蓝色那层才是最终要被做成 线路板的。红色的线是导线。制作一块单面印制板是非常容易而且并不需要非 常精确。您可以按照最短的线路来设置跳线(红色)。用Eagle我不用这么做。
最终的面板图以白色作为背景便于打印: 白色背景的印制板 (注: 这并不是您用来制作印制板的文件。 .)

所有的 Eagle 文件都包含在(linuxfreqcount-0.4)软件包中,您可以从本文最 后的相关链接中下载.  

工作原理

AT90S4433有两个内部计数器。一个是16位,另一个是8位的。在这里,我们用到 8位的计数器,通过AT90S4433时钟晶振来产生一个精确时基。为了达到这个目的, 我们用一个4.194304MHz的晶振,通过256内部分频来触发8位计数器计数(查看A T90S4433的数据手册,在本文末尾相关链接可下载)。配置8位计数器每次溢出时产生一个 中断。也就是说,我们得到了一个4.194304MHz/(256×256)=64Hz的时基。通过使 用一个循环变量,我们可以得到一个1Hz间隔或64Hz间隔的功能调用。

现在,我们已经拥有一个可以通过软件模式来设置的1Hz或者64Hz间隔的功能模块。现在我 们所要做的是,通过这个功能来读出16位计数器并显示出结果。这个16位的计数器(AT 90S4433第5脚)的脉冲信号由被测信号提供。

AT90S4433对输入信号进行采样,使其与内部时钟保持同步。根据采样规则,我们可以最大 限度的测出接近1/2内部晶振的信号频率。这是理论极限。实际上,我们可以用AT90S4433 来测量达到1.5MHz的信号。

我们需要通过逐级驱动来测量高频率。这就是为什么这里还需要74f74和74HC390了。74F74 是用作快速1/4异步分频,74HC390作为1/25分频。我们不能直接用74HC390来作1/100 分频,因为它最高工作频率是25MHz。

线路提供两个信号输入。一个是经过1/100分频,另一个是直接输入的。根据您所要测的 信号的频率来选用其中的一个输入端(不能同时输入)。

如果你只对接近1,5MHz感兴趣(例如设置成测量音频放大器的频率响应),你也可以构架 一个简易版本的计数器,放弃使用MAX903,74f74及74hc390。你仍可以使用同一个软 件及线路板。

使用2个电压比较器(高速的MAX903和LM393)的目的是为了放大信号并利用正弦信号产生方波信号。

在设计线路板及布线时要特别注意避免比较器产生自激振荡。你必须注意到MAX903是一个 超高速比较器。如果你使用一个噪音输入信号,想象一下一个100KHz被一个1MHz信号调制, 你就会在100KHz信号过零时,测得一些附加的1MHz脉冲信号。
加在MAX903上的220K电阻是用来避免由于噪音产生的一定程度正反馈引起自激。 就不会出现噪音信号被计数。

通过RS232和2个轻触开关(清除开关及模式开关)来控制处理器的工作过程。

2个输入通道通过一个或门(74hc02)输出。在74hc390输出口上虽然是 逻辑电平“1”,如果你没有联接1/100输入端,或门都会禁止信号输入。因此当 你改变计数模式或按下清除按钮时,74hc390就会被清除(pin2)。  

软件

处理器软件在中断模式下设置了2个计数器。关于这两个计数器的如何运用, 在AT90S4433数据手册中描述得非常详细(参见参考文件)。你必须给寄存器设置 一个值,这是非常重要但重复提也是非常乏味的,我在这里不会再提到这一点。频 率计逻辑的绝大部分在 linuxfreqcount.c 这个文件中实现。其它所有的程序如LCD、 UART,等等都作为库文件存在。在写AT90S4433软件时你必须注意程序长度不能超过 128B RAM。这些都是我们必须做到的。因此,你最好在嵌套功能调用时不要用到太多 的参数。优先考虑使用标识符及全局变量作为传递参数。

当计数器被正确配置后,程序SIGNAL(SIG_OVERFLOW0)按照64Hz频繁调用。我们将读 出16位计数器并设置一个信号量(hflag)给进一步处理计数结果的函数handlecounterresult() 。在1Hz门开关作用下我们可以直接运用计数器的值,但是当在1/64门开关作用时,我们必须将计数 器的值乘以64。对于微处理器我们不能做太多的数学运算(我们没有32位奔腾处理器)。幸运的是, 乘以64只需要左移6次。我们用3个8位变量保存最终结果(counterval[3]).

现在我们可以得到一个24位的计数结果。为了能显示它,必须将他转变成十进制的ASCII码。 Printf用的是最常用的,但我们不会用这个方法,因为他会超出我们的存储范围。 我们将24位数字除以10得到结果,把二进制数转换成十进制数。结果都是十进制数。AT90S4433不能进 行24位运算,因此我们只能用8位处理模块(function divby10())来处理。都以零有效值的ASCII码增加 的每个阿拉伯数字最后都提供一个以ASCII表达的数字(function longtoascii())。

转换过的ASCII字符通过RS232接口被传送到LCD显示屏显示出来。  

制作印刷线路板

在软件包中包含了一个附件(linuxfcount.ps)里面是电路图。我个人觉得焊盘有太小了。因此, 我强力推荐在你动手蚀刻线路板前用油漆在这些地方作记号将他们扩大。关于如何自己动手做线路板的 程序在下面文档中详细描述了:2002第5期, 给你的Linux服务器加一个LCD前控制面板 有些读者跟我说,Kontakt Pausklar-21 油料很难找到。你也可以用煤油替代, 就象用油灯一样。在你将板子进行蚀刻之前必须用肥皂将煤油擦洗干净。  

如何为频率计制作一个外壳?

[final case, open] [wooden frame] 对于是一个业余电子爱好者,一个很主要的难题就是为自己设计制作的的线路板配上一个外壳。 通常制订一个铝合金的盒子是很昂贵的,而且自己动手想精确的弯曲一片金属片是不容易的。 我已经找到了一种即便宜又看上去有专业水准的方法。我用杉木来做边和角,您可以给它上点油漆, 使看上显得华贵一点。用水溶性油漆来漆内壁。盒子的前部、顶部及底部,我用一些金属片, 我不需要弯曲它们。只要将它们按正确的尺寸裁好就可以了。你可以在图片中看到盒子右侧木框架 的样子。在左侧你可以看到完成后的样子(顶上的盖不在)。  

装配板子

[circuit] 在焊接板子的时候,要特别注意高频区域(MAX903和74F74及其电阻、电容)。一般情况下, 我都推荐使用集成插座,这样在发生错误时,更换比较容易。但这两个集成芯片不能使用集成插座, 尽量减少产生寄生震荡干扰。在地与电源之间的滤波电容必须使用小一点瓷片电容。这个电容的大小 可以是10nF至100nF之间。

这是我们目前为止在LinuxFocus系统下设计的最复杂的一块电路板。我建意,边焊接边进行测试 不同的器件是否正常工作,如:
  1. 首先将是电源部分(如7805等)焊到板子上并测试是否工作。
  2. 焊接上所有的元器件,但是,我们只为处理器使用插座!
  3. LinuxFocus 0.4版本软件包中包含了一个测试程序,avr_led_lcd_test.c,用来测试微处理器 及LED、LCD,将它安装到你的电脑上。将编程电缆按照第一篇关于AVR的文章 (2002 第五期, AVR单片机GCC编程) 所描述的那样接好,然后键入"make testload"从 linuxfreqcount-0.4软件包中安装 avr_led_lcd_test软件。LED应该在闪烁,LCD应该显示“HELLO”。
  4. 完成以上所有工作后,将所有的集成芯片插到插座上。调用最后一个软件。进一步作测试, 首先,测试低频部分,其次是高频部分。你需要一些各种类型的振荡来作频率源(如方波信号作 为首选的输出信号)。
 

使用计数器

计数器可以运行在不同模式下:
  1. 1.连续计数
  2. 利用1Hz门开关作为频率测量。在这种模式下,通过1/100分频,你可以测量的频率最大可达16位, 65535Hz或6553500Hz
  3. 利用64Hz门开关作为频率测量。在这种模式下,你可以测量的频率最大可达1.5M,或者通过1/100分频, 您可以测量品率达到100M。
[RS232 ASCII 命令接口]
RS232 ASCII 命令接口.
你可以通过改变模式选择按钮来改变模式,也可以通过ASCII命令控制RS232端口来改变。 RS232 ASCII控制端口如何工作在2002年5月的那篇文章 AVR单片机GCC编程 中有详细描述。一些命令语句都在 README.commands这篇文章中有描述。

当门打开时,绿的LED被点亮,这时表示,脉冲能够进入计数器并被计数。

第二个按钮是清除按钮。这个按钮可以用来清除计数器(主要针对计数模式)并将它乘以100后正常显示。 乘以100将引起显示结果也乘以100。这种方法你不必经过很复杂的计算。当你使用1/100驱动时, 这是非常有用的。  

如何提高精度?

任何一个数字式计数器都有一个±1的精度。尽管你使用一个非常稳定的输入信号,最后的数字总 是会有一点点的误差。如果频率门是64Hz,那么结果就在计数器内部乘以64,这就意味着精度 是±64。同样的,1/100驱动也会影响测量精度。无论怎么说,这个计数器还是非常不错的。 关键问题出在4194304Hz晶振的温度飘移上。在温度较高时,晶振速度会比较慢一些。 这是一个物理现象,你唯一能做的就是通过精确的控制温度来消除它。

如果有很好的参考信号,你也可能校准计数器。你可以通过软件校准,在函数handlecounterresult() 中加入一个小小的延时。我曾将我的计数器与一个参考信号做了比较,发现我们计数器是几乎没有误差。 因此,校准延时普遍地出现在源代码当中。你可以通过改变其中的一个27pF的电容来微调晶振的频率 (你不得不用10pF、50pF等的电容一个个的做实验)。

在常规情况下使用时,不必要去校准。标准的4194304Hz晶振是非常精确的。  

工作中的计数器

这是一张计数器运行中的照片:
[频率计照片]

 

深入学习

在这篇文章中并没有提供Linux系统下的应用程序来自动的测出结果的值。 有一点可以 想到的是你可以用这个频率计来测量偏远区域的风速或另外任何一种可以被转变成数字 信号的事件。在Linux系统下写一个长时间测量的软件并不是一件很麻烦的事。你可以修改 2002 第5期, 给你的Linux服务器加一个LCD前控制面板 这篇文章中提供的程序,如果你只想把测量的结果储存到一个文件中,只要用以下两个命令就可以了:

ttydevinit /dev/ttyS0
cat /dev/ttyS0 > your_logfile.txt

假设频率计被连接在电脑的 COM1 端口 (=ttyS0).
这个很容易不是吗 :-)?  

参考文献

   

对这篇文章发表评论

每篇文章都有各自的反馈页面。在这个页面里,您可以提交评论,也可以查看其他读者的评论:
 反馈页面 

主页由LinuxFocus编辑组维护
© Guido Socher, FDL
LinuxFocus.org

点击这里向LinuxFocus报告错误或提出意见
翻译信息:
en --> -- : Guido Socher (homepage)
en --> zh: hejoin <tech(at)hejoin.com>

2002-03-13, generated by lfparser version 2.27