Thomas U.
17.05.2004, 12:14
Ich hab mir vor ein paar Wochen das AVR- Buch und Experimentierboard von R. W. zugelegt, und will mir nun den Umgang mit dem Mega8 damit beibringen. Leider hatte ich vorher nicht wirklich Programmierkenntnisse (lediglich eine Ausbildung zum Energieelektroniker vor ca. 10 Jahren.). Obwohl ich Mittlerweile nun aber doch schon mit Interrupt und Timer ein bisschen was anfangen, hab ich nun ein Problem, wo ich selbst nicht mehr weiter komme.
Ich denke aber, dass mir da bestimmt von euch jemand weiterhelfen kann.
Also,
es sollen 2 LED`s abwechselnd blinken, und zwar 10 mal. Danach soll sich`s mit der Blinkerei aufhören, und erst nach Tastendruck soll das Ganze wieder von vorne beginnen.
Über Timer2 gebe ich den Blinktakt vor, und Timer0 arbeitet als Zähler. Das funktioniert auch alles sehr gut. Auch habe ich es noch geschafft, daß beide LED`s nach 10-maligem Blinken dauerhaft aus sind. Dies machte ich entweder über „Disable Timer“ bzw. „Stop Timer“. Allerdings schaffe ich es nicht, daß das Programm nach einem Tastendruck wieder zu laufen beginnt.
Im angehängeten Listing ist mein letzter Versuch zu sehen: in der Hauptschleife sollten die beiden Timer mit ‚Stop Timer’ angehalten werden, und in der Sub Neustart, welche über PD2
aktiviert wird, soll mit ‚Start Timer’ die Timer wieder zu laufen beginnen. Funktioniert so aber nicht.
Vielleicht kann sich ja von euch jemand kurz die Zeit nehmen, und mir dabei weiterhelfen.
Gruss, Thomas
Und hier ist noch das Bascom-Listing dazu:
'Einfache Anwendung mit Timer0 als Zähler und Timer2 als Taktgeber
'Timer2 gibt Zähltakt vor
'Timer0 zählt bis 10, und lässt LED`s an PD5 und 6 (invertiert zu 5) den Status wechseln
'----------------------------------------------------------
'
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 3686400 'Quarz: 3,6864 MHz
Declare Sub Neustart
On Timer0 Timer0ein 'Interruptroutine für Timer0-Overflow
On Timer2 Timer2ein 'Interruptroutine für Timer2-Overflow
Dim Y As Integer 'Variable Y definieren
Y = 0 'Startwert von Y definieren
Ddrd = &B11101000 'Pin PD3, 5, 6, 7 sind Ausgänge
Portd.4 = 1 'Pull up von PD4/T0 aktivieren(externer Takt)
Portd.2 = 1 'Pull up von PD2 aktivieren
Config Timer2 = Timer , Prescale = 256 'Timertakt Timer2 = Quarz/256
Tccr0 = &B00000110 'Timer0 extern, fallende Flanke
Enable Timer0 'Timer0-Overflow-Interrupt ein
Enable Timer2 'Timer2-Overflow-Interrupt ein
Enable Interrupts 'Interrupts global einschalten
'Hauptschleife--------------------------------------------
Tcnt0 = 245 'Timer0 voreinstellen
Do
Debounce Pind.2 , 0 , Neustart , Sub 'Taster an PD2 entprellen, und die Sub Neustart definieren
If Tcnt0 = 255 Then
Stop Timer0 'Wenn der Zähler voll ist (bis 10), sollen die Timer inaktiv werden
Stop Timer2 'und PD5 und 6 (LED`s) Low werden.
Portd.5 = 0
Portd.6 = 0
End If
Loop
'Sub------------------------------------------ 'Sollte die Timer wieder aktivieren, und die Led`s wieder von vorne 10 mal blinken lassen.
Sub Neustart
Start Timer0
Start Timer2
Toggle Portd.7 'Dient nur zum anzeigen, ob überhaupt die Sub funktioniert
End Sub
'Timer0(Zähler)-Interrupt-Routine----------------------------------
Timer0ein:
Tcnt0 = 246 'Timer0 erneut voreinstellen
Return
'Timer2-Interrupt-Routine----------------------------------
Timer2ein:
If Y = 50 Then
Toggle Portd.3
Toggle Portd.5
'Toggle Portd.6
Y = 0
Else
Y = Y + 1
End If
If Portd.5 = 1 Then 'If-Anseisung, um PD6 gegenüber PD5 zu invertieren
Portd.6 = 0
Else
Portd.6 = 1
End If
Return
End
Ich denke aber, dass mir da bestimmt von euch jemand weiterhelfen kann.
Also,
es sollen 2 LED`s abwechselnd blinken, und zwar 10 mal. Danach soll sich`s mit der Blinkerei aufhören, und erst nach Tastendruck soll das Ganze wieder von vorne beginnen.
Über Timer2 gebe ich den Blinktakt vor, und Timer0 arbeitet als Zähler. Das funktioniert auch alles sehr gut. Auch habe ich es noch geschafft, daß beide LED`s nach 10-maligem Blinken dauerhaft aus sind. Dies machte ich entweder über „Disable Timer“ bzw. „Stop Timer“. Allerdings schaffe ich es nicht, daß das Programm nach einem Tastendruck wieder zu laufen beginnt.
Im angehängeten Listing ist mein letzter Versuch zu sehen: in der Hauptschleife sollten die beiden Timer mit ‚Stop Timer’ angehalten werden, und in der Sub Neustart, welche über PD2
aktiviert wird, soll mit ‚Start Timer’ die Timer wieder zu laufen beginnen. Funktioniert so aber nicht.
Vielleicht kann sich ja von euch jemand kurz die Zeit nehmen, und mir dabei weiterhelfen.
Gruss, Thomas
Und hier ist noch das Bascom-Listing dazu:
'Einfache Anwendung mit Timer0 als Zähler und Timer2 als Taktgeber
'Timer2 gibt Zähltakt vor
'Timer0 zählt bis 10, und lässt LED`s an PD5 und 6 (invertiert zu 5) den Status wechseln
'----------------------------------------------------------
'
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 3686400 'Quarz: 3,6864 MHz
Declare Sub Neustart
On Timer0 Timer0ein 'Interruptroutine für Timer0-Overflow
On Timer2 Timer2ein 'Interruptroutine für Timer2-Overflow
Dim Y As Integer 'Variable Y definieren
Y = 0 'Startwert von Y definieren
Ddrd = &B11101000 'Pin PD3, 5, 6, 7 sind Ausgänge
Portd.4 = 1 'Pull up von PD4/T0 aktivieren(externer Takt)
Portd.2 = 1 'Pull up von PD2 aktivieren
Config Timer2 = Timer , Prescale = 256 'Timertakt Timer2 = Quarz/256
Tccr0 = &B00000110 'Timer0 extern, fallende Flanke
Enable Timer0 'Timer0-Overflow-Interrupt ein
Enable Timer2 'Timer2-Overflow-Interrupt ein
Enable Interrupts 'Interrupts global einschalten
'Hauptschleife--------------------------------------------
Tcnt0 = 245 'Timer0 voreinstellen
Do
Debounce Pind.2 , 0 , Neustart , Sub 'Taster an PD2 entprellen, und die Sub Neustart definieren
If Tcnt0 = 255 Then
Stop Timer0 'Wenn der Zähler voll ist (bis 10), sollen die Timer inaktiv werden
Stop Timer2 'und PD5 und 6 (LED`s) Low werden.
Portd.5 = 0
Portd.6 = 0
End If
Loop
'Sub------------------------------------------ 'Sollte die Timer wieder aktivieren, und die Led`s wieder von vorne 10 mal blinken lassen.
Sub Neustart
Start Timer0
Start Timer2
Toggle Portd.7 'Dient nur zum anzeigen, ob überhaupt die Sub funktioniert
End Sub
'Timer0(Zähler)-Interrupt-Routine----------------------------------
Timer0ein:
Tcnt0 = 246 'Timer0 erneut voreinstellen
Return
'Timer2-Interrupt-Routine----------------------------------
Timer2ein:
If Y = 50 Then
Toggle Portd.3
Toggle Portd.5
'Toggle Portd.6
Y = 0
Else
Y = Y + 1
End If
If Portd.5 = 1 Then 'If-Anseisung, um PD6 gegenüber PD5 zu invertieren
Portd.6 = 0
Else
Portd.6 = 1
End If
Return
End