首页



频 率 计
(转载请注明出自http://avr.cnta.net,谢谢)

   玩单片机经常会测一些脉冲频率,万用表的频率档只能测到20K。翻箱时找到一个电源外壳、左边有漏液的LCD2002、一块弃用的手机电池,又找了些接插件,动手做了个频率计,可显示脉冲频率和周期,完全满足本人一般应用。

  
  
采用MEGA8-AU芯片,8M外部晶振。TIMER0作为计时器,TIMER1作为计数器,T1脚输入信号,上拉,下降沿触发记数。
  BASCOM-AVR 1.11.9.5编译。

'-----------------------------------------------------------------------------------------
'Name                     : Cymometer.bas
'Copyright                : http://avr.cnta.net
'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., Db5 = Portd., Db6 = Portd., Db7 = Portd., E = Portc., Rs = Portc.5
Config Lcd = 20 * 2
Cursor Off Noblink

Ddrc.= 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

 

 goto1480@163.com