Hallo,
wie kann ich ein Interrupt zu einem bestimmten Zeitpunkt erst starten?
z.B. nach einer Switch Anweisung.
Hab zwei Interrupts in meinem Programm. Das eine wird gestartet sobald
das UART Receive Flag gesetzt wird, also Daten ankommen. Da hab ich
dann eine Switch Anweisung das je nach ankommenden Wert etwas
ausgeführt wird. Kann ich in der Switch Anweisung auch angeben, das bei
einem bestimmten Wert erst das andere Interrupt gestartet wird....??
Hi, Björn,
DU startest keinen Interrupt. Nie. Sondern irgendein Hardware-Ereignis
wie eben ReceiveComplete.
In dieser Interrupt zu warten, bis irgendein ein anderes externes Gerät
etwas tut, wäre ziemlich unzweckmäßig, da wäre der Prozessor vielleicht
sehr lange in Wartestellung.
Sondern Du holst das Zeichen nur ab und bist wieder in der
Main-Routine.
Schau Dir ein paar Beispiel-Programmme an.
Ciao
Wolfgang Horn
Hi, Björn,
indem Du im UCSRnB beispielsweise RXCIEn: RX Complete Interrupt Enable
setzt.
Bei der Initialisierung muß noch mehr passieren, Du findest
Beispielprogramme im Datenblatt zu den Atmega.
Ciao
Wolfgang Horn
Nicht mit Befehlen, sondern mit setzen entsprechender Flags.
Du setzt ja auch bei der UART-Geschichte das RXCIE-Flag, also das Flag,
das einen IRQ auslöst, wenn ein Zeichen im Empfangsbuffer vorhanden
ist.
LG EC
"Aber mit welchem Befehl kann ich einen bestimmten Intterupt
freigeben...??"
Mit garkeinem.
Jede Interruptquelle hat in ihren Konfigurationsregistern ein
Enable-Bit, das mußt Du setzen.
Peter
Hi,
also das mit den Flags beim UART funktioniert und hab ich auch
verstanden. Senden und empfangen klappt beides wunderbar.
Nun wollte ich noch ein Blinklicht dazu nehmen, welches bei einem
bestimmten über UART empfangenen Wert anfängt zu blinken.
Das hab ich so gemacht:
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
uint16_t count;
// irq_count um 1 erhöhen und...
count = 1+irq_count;
// ...alle 1000 IRQs die LED blinken
if (count >= INTERRUPTS_PER_SECOND)
{
count = 0;
PORT_LED ^= (1 << PAD_LED);
}
irq_count = count;
}
Das Blinken funktioniert auch, nur leider die ganze Zeit. Die LED soll
aber erst blinken, wenn ein entsprechendes Zeichen gsendet wird!
P.S.:
Das heißt aber nicht, daß dann erst die Interruptquelle aktiv wird.
Kam ein Interruptereignis (z.B. Byte empfangen) und Du setzt erst nach
10 Jahren das Enable-Bit, dann kriegst Du auch sofort den Interrupt auf
das Ereignis von vor 10 Jahren.
Will man das nicht, muß man unmittelbar vor der Freigabe erst das
Interrupt-pending-bit löschen, was bei den AVRs blöderweise Bit setzen
bedeutet (beliebte Fallgrube für 100% aller AVR-Anfänger).
Peter
> Das Blinken funktioniert auch, nur leider die ganze Zeit. Die LED> soll aber erst blinken, wenn ein entsprechendes Zeichen gsendet> wird!
In dem konkreten Fall hast du 2 Möglichkeiten.
Warum blinkt denn die LED?
Weil da ein Timer läuft der stänidg hochzählt und
irgendwann das Output Compare Ereignis auslöst. Bei der
Behandlung dieses Ereignisses wird dann das Blinken
geregelt.
Möglichkeit 1:
Wenn der Timer nicht läuft, tritt auch kein Output Compare
auf und folgerichtig blinkt auch keine LED.
Jetzt schau dir nochmal an, wie du den Timer initialisiert hast.
Irgendwann hast du mal den Vorteiler für den Timer eingestellt.
Dann nochmal Blick ins Handbuch: Es gibt eine bestimmte Stellung
der Vorteiler-Bits, die bewirken, dass der Timer nicht läuft.
Wenn das Programm hochfährt stellst du genau das ein: Timer
läuft nicht -> LED blinkt nicht. Kommt dann das Zeichen über
die UART wird der Vorteiler eingeschaltet, der Timer läuft,
die Output Compare Ereignisse kommen durch -> LED blinkt
Möglichkeit 2:
Mann muss ja nicht gleich mit Kanonen auf Spatzen schiessen.
Der Timer kann ja durchaus laufen, nur sollen halt die Output
Compare Ereignisse keinen Interrupt auslösen.
Wieder: Beim Hochfahren hast du irgendwann das Bit im
Konfigurationsregister gesetzt, dass dem µC mitteilt, dass er
bei Auftreten des Output Compare Ereignisses die Interrupt
Funktion anspringen soll.
Das nimmst du dort weg und setrzt dieses Bit erst dann, wenn über
die UART das entsprechende Zeichen angekommen ist.
Eigentlich ganz einfach, oder?
Vorteiler
> Nur soll die LED, wenn die Taste erneut gedrückt wird auch wieder> ausgehen.....
Das sollte jetzt aber kein Problem mehr sein :-)
Du machst einfach alles rückgängig, was du beim Einschalten
gemacht hast.
Stimmt, ne if Abfrage und nun klappt alles bestens.....!!!
Wie kann ich diese Stück umschreiben?
void moveservo(char pos)
{
for(int yy=0;yy<7;yy++)
{
PORTB=1; for(int i=0;i<pos;i++)
delay_20us();
PORTB=0;
for(int i=0;i<(1500-pos);i++) delay_20us();
}
}
Krieg immer ne Fehlermeldung.....
> for(int i=0;i<pos;i++)
In ANSI-C müssen Variablen am Anfang eines Blocks deklariert werden.
Also besser:
void moveservo(char pos)
{
int i, yy;
for(yy = 0; yy < 7; yy++)
{
PORTB = 1;
for(i = 0; i < pos; i++)
delay_20us();
//usw...
}
}
Danke,
bekomme aber immer noch diese Fehlermeldung:
../Servo.c:83: Fehler: Anfangsdeklaration in »for«-Schleife
auÃerhalb C99-Modus verwendet
Hab schon versucht das Makefile zu ändern..... klappt aber nicht...!!