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....??
Kein Problem, Du gibst erst den entsprechenden Interrupt frei, wenn Du Ihn benötigst.
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
Aber mit welchem Befehl kann ich einen bestimmten Intterupt freigeben...?? Ist bestimmt jetzt voll simpel, aber ich kapier oder weiß es nicht.....!!
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
Hey, war echt ganz einfach....!!! Hat sofort geklappt....!! Nur soll die LED, wenn die Taste erneut gedrückt wird auch wieder ausgehen.....
> 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...!!
Du musst aus allen for-Schleifen die Variablendeklarationen rausnehmen oder im Makefile c99 einstellen, dann gehts auch so...
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.