圣龙扬特-AVR电子

标题: MEGA8做的简易频率计 [打印本页]

作者: admin    时间: 2013-2-26 08:01
标题: MEGA8做的简易频率计
  玩单片机经常会测一些脉冲频率,万用表的频率档只能测到20K。翻箱时找到一个电源外壳、左边有漏液的LCD2002、一块弃用的手机电池,又找了些接插件,动手做了个频率计,可显示脉冲频率和周期,完全满足本人一般应用。
  采用MEGA8-AU芯片,8M外部晶振。TIMER0作为计时器,TIMER1作为计数器,T1脚输入信号,上拉,下降沿触发记数。
  BASCOM-AVR 1.11.9.5编译。

[attach]4[/attach]


'---------------------------------------------------------------------------------------
'Name                     : Cymometer.bas
'Copyright                : 圣龙扬特-AVR电子
'Micro                    : AtMega8
'Author                   : slyt
'---------------------------------------------------------------------------------------
$regfile = "M8def.dat"                                      ' specify the used micro
$crystal = 8000000                                          ' used crystal frequency
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 20                                               ' default use 10 for the SW stack
$framesize = 40                                             ' default use 40 for the frame space

$lib "single.lbx"

'To use it as a COUNTER, you can choose on which edge it is trigereed
Config Timer1 = Counter , Edge = Falling
On Timer1 Tim1_isr

'Valid values are 1-0.125us , 8-1us, 64-8us, 256-32us or 1024-128us
Config Timer0 = Timer , Prescale = 64
On Timer0 Tim0_isr

Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.1 , Db6 = Portd.3 , Db7 = Portd.4 , E = Portc.4 , Rs = Portc.5
Config Lcd = 20 * 2
Cursor Off Noblink

Ddrc.1 = 1
Led Alias Portc.1

Dim Wf As Long                                              '频率变量,并记录COUNTER1中断次数
Dim Tim0_counter As Word                                    'Timer0中断次数
Dim Tim0_counter_times As Word                              'timer0中断次数倍数
Dim Tim1_counter As Byte                                    'Timer1中断次数
Dim Mybyte As Byte
Dim Ss As Single
Dim Lcdstr As String * 7

'Deflcdchar 0 , 32 , 9 , 9 , 9 , 14 , 8 , 16 , 32            ' replace ? with number (0-7)

Led = 1

Cls
Locate 1 , 8
Lcd "F: 000.00 KHz"
Locate 2 , 8
Lcd "T: 000.00  mS"


Tim0_counter_times = 250                                    '初始250倍,250X2=500ms,即第一次采样500ms后计算
Tim0_counter = 0
Counter1 = 0
Timer0 = 5
Wf = 0

Enable Interrupts
Enable Timer0
Start Counter1

Do
   Idle

   If Tim0_counter = Tim0_counter_times Then
      Disable Timer0
      Stop Counter1
      Wf = Wf * 65536
      Wf = Wf + Counter1                                    '总脉冲次数
      'Tim0_counter * 2/1000  '总计时毫秒数。除1000转换成秒
      Wf = Wf * 500                                         '频率=脉冲次数/总时间
      Wf = Wf / Tim0_counter                                '计算出Hz数

      Locate 1 , 18
      Select Case Wf
         Case Is > 999999                                   '显示MHz
            Lcd "MHz"
            Ss = Wf / 1000000
         Case Is > 999                                      '显示KHZ
            Lcd "KHz"
            Ss = Wf / 1000
         Case Else                                          '显示Hz
            Lcd " Hz"
            Ss = Wf
      End Select

      Lcdstr = Fusing(ss , "#.##")
      Mybyte = 7 - Len(lcdstr)
      Lcdstr = Space(mybyte) + Lcdstr                       '补齐6个字符

      Locate 1 , 10
      Lcd Lcdstr                                            '显示Hz数

      Locate 2 , 19
      Select Case Wf
         Case Is > 1000                                     '显示uS
            Lcd Chr(&He4) ; "S"
            Ss = 1000000 / Wf
         Case 0                                             '显示mS
            Lcd "mS"
            Ss = 0
         Case Else                                          '显示ms
            Lcd "mS"
            Ss = 1000 / Wf
      End Select

      Lcdstr = Fusing(ss , "#.##")
      Mybyte = 7 - Len(lcdstr)
      Lcdstr = Space(mybyte) + Lcdstr                       '补齐6个字符

      Locate 2 , 10
      Lcd Lcdstr                                            '显示周期数

      Locate 1 , 8
      Lcd "F:"
      Locate 2 , 8
      Lcd "T:"

      If Wf > 10000 Then                                    '如果频率大于10K,采样周期改为200ms
         Tim0_counter_times = 100
         Else
         If Wf > 500 Then
            Tim0_counter_times = 250                        '如果频率大于500Hz,采样周期改为500ms
            Else
            Tim0_counter_times = 500                        '采样周期为1S
         End If
      End If

      Wf = 0                                                '重置初始值
      Tim0_counter = 0
      Timer0 = 5
      Counter1 = 0
      Enable Timer0
      Start Counter1

   End If

Loop

End


'============计时2ms===============
'Timer0=5, 250*8=2000us=2ms
Tim0_isr:
   Incr Tim0_counter
   Timer0 = 5
Return

'=======计数器溢出次数=============
Tim1_isr:
   Incr Wf
Return
 

作者: 铜河    时间: 2013-2-26 10:51
顶起~~~~~~~~
作者: MCU-CN    时间: 2013-2-26 22:33
BASCOM 毁三观啊,,,,,,
作者: oneway    时间: 2013-2-28 18:22
偷师学艺来了
作者: 小涛电子工作室    时间: 2013-3-1 12:59
不错  顶一个
作者: p2pahz    时间: 2013-3-2 10:39
顶一个,向萧大学习了
作者: 多啦A梦    时间: 2013-3-2 13:16
顶起来,顺便问下老大如果加入计算占空比的话可行吗?
作者: admin    时间: 2013-3-2 13:28
可以,编程序时记录一下高或低电平时间,计算出占空比。
作者: 多啦A梦    时间: 2013-3-2 13:47
谢谢老大 照着这个思路写一下看看!

作者: avr_freshman    时间: 2013-3-2 15:39
学习了,虽然以前做过频率计,但是从来没有想到过做成这么漂亮的盒子,而且还是废旧宝贝,学习老大了。
作者: avrbase_lei    时间: 2013-3-2 16:41
怎么这个bascom的程序就这么点点长呢?
作者: admin    时间: 2013-3-2 19:44
avrbase_lei 发表于 2013-3-2 16:41
怎么这个bascom的程序就这么点点长呢?

BASCOM很多函数内部封装了。
比如驱动LCD1602。程序开始部分定义下引脚,程序中直接用LCD有关函数即可。所以程序看起来不大。
作者: swustlx86    时间: 2013-3-3 22:33
学习了        
作者: 我爱电子    时间: 2013-3-4 14:23
能分享制作质料吗?

作者: 箫天    时间: 2013-3-4 15:14
等我回去找找还有没有电路图
作者: hhdsdy    时间: 2013-3-5 09:46
这个可以测到多高的频率啊?
作者: shcqma    时间: 2013-3-12 07:51
学习来了,能测多高的频率




欢迎光临 圣龙扬特-AVR电子 (http://avr.cnta.net/) Powered by Discuz! X2.5