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
der CPI Befehl lässt sich nur in Verbindung mit den Registern R16 bis R31 benutzen.
Bei mir blinkts so: .include "4433def.inc" .def temp = r16 .def counter = r17 .def leds = r18 .equ start = 256 - 244 ; bei 8 MHz entspricht das ca. 1/32 sec .equ loops = 32; rjmp reset ; Reset Handler reti ; IRQ0 Handler reti ; IRQ1 Handler reti ; Timer1 Capture Handler reti ; Timer1 compare Handler reti ; Timer1 Overflow Handler rjmp timer0 ; Timer0 Overflow Handler reti ; SPI Transfer Complete Handler reti ; UART RX Complete Handler : RXCIE reti ; UDR Empty Handler reti ; UART TX Complete Handler reti ; ADC Conversion Complete Interrupt Handler reti ; EEPROM Ready Handler reti ; Analog Comparator Handler reset: ldi temp, RAMEND out SP, temp; set stack pointer ldi temp, 0xFF out DDRC, temp ; PORTC configured for output ldi temp, 0xFF out PORTC, leds ; LEDs ausschalten ldi temp, 1<<TOIE0 ; 0000 0010 out TIMSK, temp ; timer 0 interrupt ein ldi temp, start out TCNT0, temp ; Startwert des Timers ldi temp, 0b00000101 out TCCR0, temp ; Timer starten mit Vorteiler 1024 ldi counter, loops ldi leds, 0xFF sei ; interrupts generell aktivieren main: loop: rjmp loop ;-------------------------------------------------- timer0: dec counter brne restart ldi counter, loops com leds out PORTC, leds restart: ldi temp, start out TCNT0, temp ; Timer fängt wieder von vorn an reti
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.