PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega 16 - Timer und hochzählen mit Ausgabe auf Display



blondie
07.09.2008, 12:59
Hallo!

Ich bin gerade dabei, mir die Timerfunktion näher anzuschauen. Es gibt ja das tolle Programm RNAVR, das mir wirklich schon gut geholfen hat.

Ich möchte im ersten Schritt nur sekundenweise hochzählen. Jedoch habe ich hier schon probleme. Hier ist mal mein Code (Es handelt sich bei mir um ein Entwicklungsboard aus der Elektor:


'Initialisieren inkl. LCD
$regfile = "m16def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 8000000
$baud = 9600

'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.5 , Rs = Portc.4
Config Lcd = 20 * 4a , Chipset = Ks077
Config Lcd = 20 * 4
Config Lcdbus = 4
Initlcd

'Einsllen der Ein und Ausgänge
Config Porta = Input
Config Portb = Output
Config Portc = Output 'Display!!!
'Config PORTD = 'Nicht belegt / RS232

'Namen für die Ausgänge vergeben
Led1 Alias Portb.0
Led2 Alias Portb.1
Led3 Alias Portb.2
Led4 Alias Portb.3
Led5 Alias Portb.4
Led6 Alias Portb.5
Led7 Alias Portb.6
Led8 Alias Portb.7

'Namen für die Eingänge
S1 Alias Porta.0
S2 Alias Porta.1
S3 Alias Porta.2
S4 Alias Porta.3
S5 Alias Porta.4
S6 Alias Porta.5
S7 Alias Porta.6
S8 Alias Porta.7

'Ausgänge vorschalten
Led1 = 1

'Deklarationen
Dim A As Byte
Dim Sekunden As Byte





'###############################################

'Timer einstellen


Config Timer1 = Timer , Prescale = 256 'Hier wird der Timer und der Teiler festgelegt

'Hier wird das Unterprogramm festgelegt, das
'in dem von ihnen eingestellten Intervall aufgerufen wird
On Timer1 Timer_irq

'Diese Vorgabe wurde berechnet um die genaue Intervallfrequenz zu erreichen
Const Timervorgabe = 34286


'Hier werden die Timer aktiviert
Enable Timer1
Enable Interrupts


'Dies ist der Programmteil, der in dem von ihnen gewählten
'Intervall aufgerufen wird
Timer_irq:
Timer1 = Timervorgabe

'################



'Hier könnte nun ihre beliebige IRQ-Routine stehen
'Dabei sollte man darauf achten das diese nicht mehr Zeit
'benötigt, als das Intervall zuläßt

'Der Zustand der LED wir umgekehrt, wodurch sich blinken in der halben Frequenz ergibt
'Hohe Frequenzen sind natürlich nicht mehr sichtbar
Toggle Led2

Sekunden = Sekunden + 1 'Sekunden +1


'################################################# ############################

'Displayausgabe
Cls 'Display löschen (IMMER ERST LCD LÖSCHEN UND DANN POSITION ANGEBEN!!!)
Locate 1 , 1 'Zeile1 Zeichen1
Lcd Sekunden

Return


Es handelt sich also nur um den Code, der durch RNAVR erzeugt wurde und dem hinzugefügten:
Sekunden = Sekunden + 1

Dann die displayausgabe der Sekunden.

Das Toggeln der LED funktioniert wunderbar im Sekundentakt, jedoch die Displayausgabe bleibt bei 1.

Eigentlich müsste doch der Wert "Sekunde" nach jedem überlauf weitergezählt werden? Wo ist mein denkfehler?

Ich hoffe ihr könnt mir Helfen O:)

Gruß

blondie

Michael
07.09.2008, 14:50
Hallo blondie,

ich vermisse in deinem Programm die Hauptschleife.
Dein Programm erreicht gleich nach dem Initialisieren das Label Timerirq, toggelt die LED, addiert 1 Sekunde und zeigt dieselbe an.
Dann kommt ein return und das Programm springt... ja wohin?

Vor die Interruptroutine gehören mindestens diese 3 Befehle:
do
loop
end
(in der Reihenfolge)

Gruß, Michael

P.S.: JTAG-Fuses sind aber abgeschaltet?

blondie
07.09.2008, 15:09
Hallo!

Also muss die Hauptschleife vorhanden sein, damit dort wieder hingesprungen wird?

Ich habe diese jetzt mal hinzugefügt. Funktioniert. Bestens! Vielen Dank!

Gruß

Blondie

Michael
07.09.2008, 16:23
Hallo blondie,



Also muss die Hauptschleife vorhanden sein, damit dort wieder hingesprungen wird?
Es muß überhaupt ersteinmal eine Programmstruktur vorhanden sein, die unterbrochen werden kann.
Interrupt heißt Unterbrechungsanforderung.

Dein Programm ist einfach in einen Bereich gelaufen, wo es nichts zu suchen hatte.


Funktioniert. Bestens! Vielen Dank!
;)

Gruß, Michael