hallo ihr lieben,
da ich mal wider etwas mit der messung von niedrigen frequenzen machen musste (wollte), ist noch ein verbesserter code entstanden, den ich hier posten möchte.
der einwnd von besserwessi über die int-überschneidung wurde berücksichtigt.
der hintergrung dieser neuen version ist die tatsache, dass ich ein zweikanaliges gerät benötigte. da der M8 aber nur eine icp-einheit hat und zudem die int-priorität für icp sehr niedrig ist, habe ich mich entschieden den int0 eingang für das zu messende signal zu nehmen und das entsprechde programm möglichst efficient zu gestalten.
im ende kam ein programm heraus, bei dem man wahlweise den int0 oder den int1 verwenden kann. beide int vectoren müssen auf die gleiche isr zeigen.
durch einfaches enablen und disablen des int1 oder int0 kann man dann den messkanal umschalten.
einen weiteren vorteil dieser programmierung sehe ich darin, dass die int-routine als (ein besseres wort fällt mir jetzt nicht ein) als Flip-Flop INT programmiert ist und das im ende noch als Inline assembler.
nach durchführung einer Messung, kann man in Ruhe seine calculationen oder LCd ausgaben machen, da die ganze messung bis zum nächsten aufruf stoppt und es laufen keine weiteren wartenden Ints mehr auf, die sich störend auswirken könnten.
auf die umrechnung des messwertes (in prozessortakten, je eingangsperiode) habe ich verzichtet, da die reziprokberechnung über single oder gar double für meine anwendung nicht nötig ist und den code nur unnötig verschmutzt.
gruss klaus
Code:
hier also nun der liebevoll erzeugte code:
Code:
$baud = 256000 'set baudrate depending on cpu clockspeed
$crystal = 32000000 'and your clockrate must be set too
'********** no joke... my M8 is running on 32Mhz now without any problems
' but take care .. its dangerous because some parts of your cpu may fail at high clockrates
'########## warning !!!!!!!!!!!!!
' this software is made for atmega 8
'Inside The Int0isr : The Register Tccr1b Is Directly Adressed .
' so .. if you use a different processor, check for register names and adresses.
$regfile = "m8def.dat"
$hwstack = 32
$swstack = 10
$framesize = 40
Config Portd.2 = Input 'int 0
Portd.2 = 1
Config Timer1 = Timer , Prescale = 1
'Tccr1b.6 = 0
Stop Timer1 'we stop the timer , because it will be activated
'inside the int0 routine
Config Int0 = Falling 'must be falling for efficient programming
On Int0 Int0isr Nosave 'nosave .. saves time and code
Enable Int0
On Ovf1 T1overflow Nosave 'again nosave
Enable Ovf1
'about nosave : if you use the int routines "called ORIGINAL BASCOM" please comment
'out the NOSAVE DIRECTIVE
Enable Interrupts
' **************************************************************************************
' *** hier kommen zwei spezialkonstukte, die rechenzeit sparen .. was zum nachdenken !!
Dim Periodelow As Word
Dim Periodehigh As Word
Dim Pericount As Long At Periodelow Overlay
Dim T1overlow As Byte
Dim T1overhigh As Byte
Dim T1overflows As Word At T1overlow Overlay
' ** ENDE von *** hier kommen zwei spezialkonstukte, die rechenzeit sparen .. was zum nachdenken !!
' **************************************************************************************
Dim Messzyklus As Byte 'fertig = 0 -- also eine ganze periode gemessen
Messzyklus = 0
Dim Status As Byte ' 0=stop timer 1 = start timer
Status = 0
Print "Starting "
Wait 2 '
Do
'************ do not change below this line, if you are not sure what you are doing
If Messzyklus = 0 Then
Periodelow = Timer1
Periodehigh = T1overflows
'************ do not change above this line, if you are not sure what you are doing
' ##### your code below this line #####
Print "timer" ; Timer1
Print "ovr" ; T1overflows
Print "pericount " ; Pericount
Waitms 100 'das kann auch waitdays=100 sein.. gibt es ja nicht
'genausogut kann es entfallen, wenn man in der zeit genug anderes machen will
' #### your code above this line #####
'************ do not change below this line, if you are not sure what you are doing
Pericount = 0
T1overflows = 0
Timer1 = 0
Messzyklus = 1
Status = 1
End If
'************ do not change above this line, if you are not sure what you are doing
Loop
End
'Int0isr: 'ORIGINAL Bascom
'Tccr1b = Status
'If Status = 0 Then
'Messzyklus = Status
'End If
'Status = 0
'Return
Int0isr: ' FASTER VERSION
push r23
PUSH R24 ' since we are going to use R24 we better save it
IN r24, SREG ' get content of SREG into R24
PUSH R24
' we can save a register
lds r24,{status}
!out tccr1b,r24
cpi r24,0
brne exitthis
sts {messzyklus},r24
Exitthis:
cbr r24,1
sts {status},r24
POP R24 'get content of SREG
!OUT SREG,r24 ' save into SREG
POP R24
pop r23 ' get r24 back
Return
'T1overflow: ' ORIGINAL Bascom
'T1overflows = T1overflows + 1
'Return
T1overflow: ' FASTER VERSION
push r23
PUSH R24 ' since we are going to use R24 we better save it
IN r24, SREG ' get content of SREG into R24
PUSH R24 ' we can save a register
lds r23,{t1overlow}
lds r24,{t1overhigh}
inc r23
brne kein_uebertrag
inc r24
Kein_uebertrag:
sts {t1overlow} , r23
sts {t1overhigh} , r24
POP R24 'get content of SREG
!OUT SREG,r24 ' save into SREG
POP R24
pop r23 ' get r24 back
Return
Lesezeichen