Hallo,
habe mittlerweile das Tutorial "durchgearbeitet" und bin jetzt auf
jeden Fall um einiges schlauer! Aber schon bei meinem ersten Projekt
habe ich ein kleines Problem : Wie kann ich nach einer bestimmten Zeit (
z.B. 1,5 Sekunden ) eine Led aufleuchten lassen ? Eigentlich benötige
ich nur eine Funktion, die den MC eben diese Zeit nichts tun lässt (
außer "nop" ) . Ich habe mal etwas von "delay" gelesen ( Tutorial : LCD
) , kann nun aber damit nicht sonderlich viel anfangen . Ich habe z.Z.
einen 4433 @ 4 MHz und schreibe noch meine Programme in ASM, auf Anraten
einiger Teilnehmer hier. Ich denke mal, dass das nicht so schwer sein
wird, oder ?
Gruß
Steffen
Hallo Steffen!
Die von Dir angeschprochene Möglichkeit funktioniert natürlich,
wenn Du aber Deinen µC 1,5 sek lang zum "Nichtstun" verdonnern willst,
brauchst Du 6 Millionen nop´s. Außerdem ist Dein Controller während der
Wartezeit außer Gefecht gesetzt und kann keine anderen Aufgaben
ausführen (z.B. Tastaturabfrage). Darum ist es wohl besser, Du erledigst
solche Aufgaben mit einem Timer. Die zum Einstellen des Timers
notwendigen Register findest Du im Datenblatt Deines Controllers.
Achtung: Interrupts müssen auch aktiviert sein.
Gruß,
Rudi
Hallo,
mit einem Timer ist es sicher besser.
Trotzdem die sache mit Delay ist so:
.def Delay = rXX
.def Delay1= rXX
Loop:
Programm
Dly:
dec delay
brne Dly
dec delay1
brne Dly
rjmp loop
Delay(1) wird von 0 - 255 gezählt.
Da beide gezählt werden ist die zeit bis zum Rücksprung größer.
Das ganze läst sich durch weitere Delay's ausbauen.
Viele Grüße
Michael T
Hallo,
erstmal Danke. Das mit dem Timer hört sich eigentlich schon ganz gut an
! Sehe ich das richtig : Wenn der 8-bit Timer jeden Takt bis 255 gezählt
hat und dann eins weiter springt, dann gibt's einen Interrupt. Gut und
was nun ? Man sollte nun noch die Anzahl der Interrupts zählen , damit
man auf eine bestimmte Zeit kommt, aber wie ? Hat das Oqverflow-Bit im
SRG eigentlich etwas mit dem Timer zu tun ?
Gruß
Steffen
Hallo Steffen!
Bin auch Neuling und hab den Timer schon vor einigen Wochen ausprobiert
- wenn ich mich recht erinnere geht das so: (hoffentlich erzähl ich
keinen Blödsinn!)
Der Timer zählt im Reg. TCNT0 (ich glaub nach unten), wobei Du
a) in selbiges Register einen Ausgangswert schreiben kannst
b) in TCCR0 einen Vorteiler einstellen kannst (max. 1024 - dann wird nur
jeder 1024te Taktzyklus gezählt)
Den Interrupt gibt´s, wenn TCNT0 überläuft (Bit7 von TIMSK muß gesetzt
sein). Du erhältst also etwas weniger als 4000x /sec. einen Inerrupt.
Diese hohe Impulsfrequenz kannst Du Durch Zähler in Deinem Interrupt -
Handler (nach dem Delay-Muster von Michael) weiter teilen.
Du kannst auch mehrere Zähler einfügen und somit einen Timer für mehrere
Aufgaben nutzen.
Rudi
hi!
ich beschäftige mich auch gerade mit den timern und hab auch ne frage
dazu!
wielange dauert jetzt bei einem 4 MHz kristall ein takt? also wenn ich
1024 taktzykeln verstreichen lass, wieviele s bzw ms sind das dann?
Bernhard
Hallo,
ich habe mich nun etwas näher mit dieser Materie befasst und folgendes
ist dabei herausgekommen :
----------------------------------------------
.INCLUDE "4433def.inc"
.DEF mp = R16 ; Zähler für Anzahl Nulldurchgänge
.DEF z1 = R0
.DEF z2 = R17
rjmp main
main:
ldi mp,RAMEND ;Initiate Stackpointer (Unterprogramme!)
out SPL,mp
ldi mp,0 ; z1 kann nicht direkt gesetzt werden, da R0
mov z1,mp ; Kopieren von mp in das Register z1
ldi mp,0x04 ;Initiate Timer/Counter 0 Vorteiler (256)
out TCCR0,mp ; an Timer 0 Control Register
ldi mp,0xFF ; alle Bits als Ausgang
out DDRB,mp ; in Datenrichtungsregister
loop:
in mp,TCNT0 ; Inhalt des 8-Bit-Zählers lesen
cpi mp,0 ; auf Null testen
brne loop ; Wenn nicht null, dann wieder loop
rcall IncZ1 ; Unterprogramm Software-Zähler erhöhen
warte:
in mp,TCNT0 ; Inhalt Zähler 0 lesen
cpi mp,0 ; auf Null testen
breq warte ; Warte bis nicht mehr Null
rjmp loop ; Nächste Runde
IncZ1:
inc z1 ; Erhöhe Software-Zähler
cpi z1,0
breq IncZ2
rjmp warte
IncZ2:
inc z2
cpi z2, 100 ; Wenn 100 erreicht -> Ausgabe ( nach ca. 6,5 Sec )
breq ausgabe
rjmp warte
ausgabe:
ldi r18, 0b11111100 ;0b11111100 in r16 laden
out PORTB, r18 ;r16 ins IO-Register PORTB ausgeben
ende: rjmp ende ;Sprung zur Marke "ende" -> Endlosschleife
----------------------------------------------------
Dieses tolle Programm soll nach ca. 6,5 Sekunden 2 LEDs anschalten. Die
Programmteile sind aus veschiedenen Tutorials zusammengesetzt, aber
AVRStudio findet immer einen Fehler ( bei " cpi z1,0 " ). Wo ist da das
Problem ? Cpi heißt doch : vergleiche mi ner Konstante (0) . Gruß
Steffen