频 率 计
(转载请注明出自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.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 |
|