Hallo zusammen! Ich würde gerne, ganz einfach mit einem Spannungsimpuls eine Led blinkend schalten, und wenn dieser Impuls nochmal angelegt wird, dann so die LED wieder aufhören zu blinken. (Atmega 8) Die Forensuche hat leider nicht geholfen. Ich habe schon viele C Codes kopiert und versucht auf mein Problem umzuschreiben aber es gelingt mir einfach nicht. Die meinsten Beispielprojekte sind mit zwei Tastern und ohne blinkende LEDs. Ich hoffe das meine Frage verständlich formuliert ist und hoffe auf schnelle Antwort. Schönen Gruß & Danke!!!
Sefco schrieb: > Hallo zusammen! > > Ich würde gerne, ganz einfach mit einem Spannungsimpuls eine Led > blinkend schalten, und wenn dieser Impuls nochmal angelegt wird, dann so > die LED wieder aufhören zu blinken. (Atmega 8) > Die Forensuche hat leider nicht geholfen. Ich habe schon viele C Codes > kopiert und versucht auf mein Problem umzuschreiben aber es gelingt mir > einfach nicht. Die meinsten Beispielprojekte sind mit zwei Tastern und > ohne blinkende LEDs. > > Ich hoffe das meine Frage verständlich formuliert ist und hoffe auf > schnelle Antwort. > > Schönen Gruß & Danke!!! Meinst Du ein Stromstossrelais plus Blinkled, oder muss es unbedingt ein uC Progranmm sein? Gruss Harald
dann zeigt doch mal was du bis jetzt hast - aber da diese aufgabe recht überschaubar ist, würde ich sagen du fängst bei 0 an und kopierst nichts aus dem netzt - dann lernt man etwas. Impuls erkennen -> (wenn timer aktiv -> timer abschalten) (wenn timer abgeschalter-> aktivieren)
Hey! Ich möchte nüchtern ausgedrückt mit dem uC ein Haftrelais ersetzten. while (1) { Impuls an PD2: Led blinkt Impuls an PD2: Led hört auf } Das bräuchte ich dringend. Und das würde ich gerne mit nem uC machen weil ich den halt hier habe. C Code wäre am besten. Gruß!
1 | /* Pseudo, aber sowas von Pseudo Code */
|
2 | if(impuls&&!blinken) |
3 | blinken=1 |
4 | else if(impuls&&blinken) |
5 | blinken = 0 |
6 | (else /* Unnötig */ |
7 | asm(" nop"); |
8 | )
|
9 | ISR(timer) |
10 | if(blinken) |
11 | led^=1 |
Musst dir ja nur merken ob die LED schon blinkt oder nicht. Blinkt sie, schalteste das Blinken uas, Blinkt sie nicht schaltest du das Blinken ein.
@ Peter II Das Problem ist, dass ich wenn ich bei 0 anfange, das gesammte Tut lesen muss. Ich habe leider momentan nicht so viel Zeit dafür. Wenn ich nen Code hätte, dann könnte ich es mir daran schneller erklären. Das hätte ich hier zusammenkopiert: #include <stdlib.h> #include <avr/io.h> #include <avr/signal.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/delay.h> // definiert _delay_ms() #define delay_us(us) _delay_loop_2 (((F_CPU/4000)*us)/1000) // wartet µs void delay_ms(int ms) // wartet ms Millisekunden { int t; for(t=0; t<=ms; t++) _delay_ms(1); } unsigned int on=0; //Varibale zum Schalten des Blinkers ISR(INT0_vect) //Die Interruptroutine. Kein ";" dahinter sonst Fehlermeldung beim Compilieren! // INT0_vect ist der Interruptvektor. { if(on==0) { on=1; } else { on=0; } } int main (void) { DDRD &= ~(1<<DDD2); //setzt PD2 (INT0) auf Eingang DDRB |= (1<<PB1); //setzt PB1 auf Ausgang. Hier ist eine LED angschlossen. MCUCR |= (1<<ISC01) | (1<<ISC00); //(Ausloesen des Interrupts bei steigende Flanke an INT0) GICR |= (1<<INT0); //Aktiviert den Pin PD2 (INT0) und den Pin PD3 (INT1) des Atmega8 sei(); //einschalten der Interrupts. Setzt das Global Interrupt Enable Bit im Status Register. while(1) { if (on==1) { PORTB = PINB ^ ( 1 << PB0 ); // LED an PB0 umschalten delay_ms (800); } } return 0; }
Sefco schrieb: > Das Problem ist, dass ich wenn ich bei 0 anfange, das gesammte Tut lesen > muss. Ich habe leider momentan nicht so viel Zeit dafür. du hast bestimmt schon mehr zeit mit testen verbracht als wenn du bei den Grundlagen angefangen hättest. > ISR(INT0_vect) //Die Interruptroutine. Kein ";" dahinter sonst > Fehlermeldung beim Compilieren! wenn ich das schon lesen, dann sollest du dir erstmal C lernen und dich dann zu einen µC vorarbeiten.
Ich kann C. Wie gesagt, dass ist kopiert, denn Kommentar habe ich nicht geschrieben.
Sefco schrieb: > Ich kann C. dann schreibt man sotwas nicht: //Die Interruptroutine. Kein ";" dahinter sonst > Fehlermeldung beim Compilieren!
Hast du gelesen was ich geschrieben habe? Ich sags dir gerne nochmal: Ich habe das nicht geschrieben, dass ist kopiert aus einem Tutorial. Ich weiß sehr wohl, dass bei Funktionen ein ";" nichts zu suchen hat, sondern Funktionen mit { und } begonnen und beendet werden. Willst du mir jetzt helfen oder weiter motzen?♠
Sefco schrieb: > willst du mir jetzt helfen oder weiter motzen?♠ wenn du jetzt noch sagst wo das Problem mit dem code ist könnte man eventuell doch helfen. Was geht und was geht nicht?
Das Problem ist, dass die LED einfach aus ist. Sie ist mit Minus an PB0 angeschlossen und über einen Widerstand an +5V. Ich habe mir dann das Kabel von meinem Multimeter mit der Messspitze genommen, ins Netzteil eingesteckt was den uC versorgt und an PD2 kurz gehalten. Passiert einfach nix. Led bleibt aus. Der Code stimmt soweit?
Sefco schrieb: > Der Code stimmt soweit? PORTB = PINB ^ ( 1 << PB0 ); das sieht mir ein wenig merkwürdig aus. teste mal mit: PORTB = PORTB ^ ( 1 << PB0 );
Hatte noch was falsch. Hab die LED an PB0, also sollte ich auch DDRB |= (1<<PB0); machen. LED ist dauerhaft an. Sonst passiert nichts.
Sobald ich hier das schreibe: ... unsigned int on=0; ... while(1) { if (on==0) { PORTB = PORTB ^ ( 1 << PB0 ); // LED an PB0 umschalten delay_ms (700); } } blinkt die LED. Sobald ich ... unsigned int on=0; ... while(1) { if (on==1) { PORTB = PORTB ^ ( 1 << PB0 ); // LED an PB0 umschalten delay_ms (700); } } leuchtet die LED dauerhaft. Komisch?!
Sefco schrieb: > Komisch?! leider kannst du ja in den code nicht beeinflussen welchen status die LED hat wenn der Impuls erkannt wird. Sie blinkt zwar nicht mehr, bleibt aber im letzen Status. teste doch erstmal den input. while(1) { if ( PIND & (1<<PD2) ) { PORTB = PORTB ^ ( 1 << PB0 ); // LED an PB0 umschalten delay_ms (700); } } jetzt sollte die LED nur blinken wenn die an PD2 den high pegel hast. Du solltest ein definierten pegel an PD2 haben, etweder den Pull-UP aktivieren oder mit einem Pull-down auf masse legen - ein offener eingang kann 0 oder 1 sein!
Peter II schrieb: > Du > solltest ein definierten pegel an PD2 haben, etweder den Pull-UP > aktivieren oder mit einem Pull-down auf masse legen - ein offener > eingang kann 0 oder 1 sein! Das musst du mir bitte nochmal erklären. Habe das gemacht was du gesagt hast: Nach dem schreiben in den Controller leuchtet die LED dauerhaft. Wenn ich den Impuls auf PD2 gebe, dann blinkt die LED ca 4 oder 5 mal und bleibt dann aus. Gebe ich den Impuls nochmal, blinkt sie wieder ein paar mal und bleibt dauer an. Und dann wieder von vorne. Wieso blinkt die denn jetzt ein paar mal? Versteh ich nich so ganz.
Sefco schrieb: > Wieso blinkt die denn jetzt ein paar mal? Versteh ich nich so ganz. wenn du nichts an dem eingang angeschlossen hast, dann hast du weder 1 noch 0 sondern das eingang inst undefiniert. sorge also erstmal dafür das der Eingang immer auf Low oder High ist (interner PullUP oder externen PullDown)
Wunderbar! Jetzt habe ich über 10k PD2 auf Masse gelegt und wenn ich Pulse, dann geht die LED an, und wenn ich wieder pulse geht sie aus. Schonmal super! Wie bekommen wir das jetzt mit dem blinken hin? Kannst du mir erklären, wass genau if ( PIND & (1<<PD2) ) bedeutet?
Sefco schrieb: > Kannst du mir erklären, wass genau if ( PIND & (1<<PD2) ) > bedeutet? http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Eing.C3.A4nge_.28Wie_kommen_Signale_in_den_.C2.B5C.29 das mit dem Puls wird ein wenig zufallen sein, halte doch mal länger den High pegel dann sollte dir auch klar sein was genau passiert.
OK, das habe ich verstanden. Ich weiß jetzt aber leider immer noch nicht genau, wie ich das realisieren soll, was ich gerne hätte. Wenn ich da richtig verstanden habe, dann hat if ( PIND & (1<<PD2) ) ja garnichts mit Interrupts zutun, sondern ich lese hier nur den Port. Für mein Problem muss ich aber halt irgendwie Interrupts einbinden. Das hier: ISR(INT0_vect) //Die Interruptroutine. Kein ";" dahinter sonst Fehlermeldung beim Compilieren! // INT0_vect ist der Interruptvektor. { if(on==0) { on=1; } else { on=0; } } Wird doch ausgeführt, wenn an PD2 eine 1 liegt, richtig?
Sefco schrieb: > Wird doch ausgeführt, wenn an PD2 eine 1 liegt, richtig? das ist abhängig von der Registern. //(Ausloesen des Interrupts bei steigende Flanke an INT0) MCUCR |= (1<<ISC01) | (1<<ISC00); //Aktiviert den Pin PD2 (INT0) und den Pin PD3 (INT1) des Atmega8 GICR |= (1<<INT0); schau doch mal im Datenblatt nach was du einschaltest - wenn die kommentare passen das müsste der Interupt bei jeder Steigenenden Flanke ausgelöst werden. Hier ist aber das nächste Problem: unsigned int on=0; //Varibale zum Schalten des Blinkers der compiler weiss nichts davon das du die variable im interupt änderst, damit wird sie wegoptimiert und auserdem ist es eine ganz schöne verschwendung wenn du ein int für 1bit brauchst. volatil uint8_t on = 0;
Ich finds echt klasse, dass du mir so hilfst, aber sag mir doch bitte einfach wies geht. Zu jedem deiner Posts kommen mir wieder zich Fragen hoch. Z.b. wieso weiß der Compiler nichts davon das ich die Variable im Interrupt änder? Sag mir bitte bitte bitte^^ einfach wies geht :P
Sefco schrieb: > einfach wies geht :P steht doch da, lesen musst du schon selbst: volatil uint8_t on = 0;
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_.28Integer.29_Datentypen #include <stdint.h>
Könntest du den gesammten Quelltext mal bitte korrekt aufschreiben? Ich habe die Variable on extra global definiert aber jetzt ist sie überall unbekannt.
Peter II schrieb: > #include <stdint.h> Sefco schrieb: > Könntest du den gesammten Quelltext mal bitte korrekt aufschreiben? hast du auch das include hinzugefügt? Was kommen denn sonst noch für warnungen - hast du warnungen überhaupt eingeschlatet? Ich dachte du kannst C?
ich habe hier weder einen compiler noch eine etwicklungsumgebung. Nur aus dem Kopf bekomme ich es auch nicht sofort hin. Welche Warnungen/Fehler bekommt du denn?
#include <inttypes.h> #include <stdlib.h> #include <avr/io.h> #include <avr/signal.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/delay.h> #include <stdint.h> // definiert _delay_ms() #define delay_us(us) _delay_loop_2 (((F_CPU/4000)*us)/1000) // wartet µs void delay_ms(int ms) // wartet ms Millisekunden { int t; for(t=0; t<=ms; t++) _delay_ms(1); } volatil uint8_t on = 0 //Varibale zum Schalten des Blinkers ISR(INT0_vect) //Die Interruptroutine // INT0_vect ist der Interruptvektor. { if(on==0) { on=1; } else { on=0; } } int main (void) { DDRD &= ~(1<<DDD2); //setzt PD2 (INT0) auf Eingang DDRB |= (1<<PB0); //setzt PB1 auf Ausgang. Hier ist eine LED angschlossen. MCUCR |= (1<<ISC01) | (1<<ISC00); //(Ausloesen des Interrupts bei steigende Flanke an INT0) GICR |= (1<<INT0); //Aktiviert den Pin PD2 (INT0) sei(); //einschalten der Interrupts. Setzt das Global Interrupt Enable Bit im Status Register. while(1) { //if ( PIND & (1<<PD2) ) if (on==1) { PORTB = PORTB ^ ( 1 << PB0 ); // LED an PB0 umschalten delay_ms (700); } } return 0; } Fehler: ../Interrupt.c:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'uint8_t' ../Interrupt.c: In function '__vector_1': ../Interrupt.c:28: error: 'on' undeclared (first use in this function) ../Interrupt.c:28: error: (Each undeclared identifier is reported only once ../Interrupt.c:28: error: for each function it appears in.) ../Interrupt.c: In function 'main': ../Interrupt.c:56: error: 'on' undeclared (first use in this function)
Entschuldige bitte das ich diesen Datentyp in einem Semester C nicht gelernt habe^^ Noch nie gehört dieses Wort. Das klappt jetzt, aber nicht besonders gut. Ab und an bleibt die LED einfach ganz an oder ganz aus. Und ich habe das Gefühl ich muss immer ne kleine Pause machen zwischen dem Pulsen weil der uC sonst durcheinander kommt. Teilweise blinkt er auch einfach weiter... ?
Sefco schrieb: > nd ich habe das Gefühl ich muss immer ne > kleine Pause machen zwischen dem Pulsen weil der uC sonst durcheinander > kommt. nein, genau im gegenteil - wenn du dein draht an den Pin drück, dann bekommt der µC bestimmt 100 impulste oder auch 99. aber zum glück gibt es ja auch hier wieder eine genau anleitung http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#.28Tasten-.29Entprellung
Ach das ist also entprellen....danke =) Habe da schon einiges drüber gelesen aber den Link den du gepostet hast habe ich noch nicht gefunden.
Ich beabsichtige, den Controller in einem RC Auto einzusetzen. Ich habe mir da mal durchgelesen, wie das Signal vom Empfänger an ein Servo aussieht. Das sollte doch perfekt sein für einen uC. Muss ich da eigentlich noch entprellen?
Sefco schrieb: > Ich beabsichtige, den Controller in einem RC Auto einzusetzen. Ich habe > mir da mal durchgelesen, wie das Signal vom Empfänger an ein Servo > aussieht. Das sollte doch perfekt sein für einen uC. Muss ich da > eigentlich noch entprellen? aber den dem Anschluss für ein Servo kommen sehr viel impulse pro sekunden, selbst wenn der Servo sich nicht bewegt. Und ja dafür bräuchtest du nichts entprellen.
Ich will den Blinker von meinem RC Auto schalten, indem ich den Hebel an der Fernbedienung einfach einmal hoch mache und wieder zurück flitschen lasse. Da kommen dann also sehr viele Impulse an... Das heißt der uC macht den Blinker sehr oft an und aus und ich kann nicht garantieren, dass der Blinker dann auch angeht. Wie könnte ich das Problem lösen?
du musst einen Programm erweitern. als 1. Muss du erstmal die impule unterscheiden zwischen hebel unten und hebel oben. (Das sind aber nich bloss 3 code zeilen!) als nächstes muss du nur übewachen ob er voher oben und jetzt unten ist und dann deinen Blinker umschalten.
Auf der Servo-Steuerleitung kommen so um die 50 Impulse pro Sekunde, unabhängig von der Stellung. Es ändert sich die Länge der Pulse.
Oh Gott...wie soll ich das nur machen? Eigentlich hab ich mir das so gedacht: Hebel Hoch: Blinker links an. Hebel Hoch: Blinker links wieder aus. Hebel Runter: Blinker rechts an. Hebel Runter: Blinker recht wieder aus.
Sefco schrieb: > Oh Gott...wie soll ich das nur machen? Indem du die Grundlagen lernst > Eigentlich hab ich mir das so gedacht: Denken kann man vieles. Aber in der Praxis funktionieren nun mal die Dinge ein klein wenig komplizierter als man das naiver Weise annimmt. > > Hebel Hoch: Blinker links an. > Hebel Hoch: Blinker links wieder aus. > > Hebel Runter: Blinker rechts an. > Hebel Runter: Blinker recht wieder aus. Ist alles machbar. Nur halt nicht so einfach wie du dir das vorstellst. Denn: Was du die ganze Zeit verschwiegen hast (*): Zwischen Hebel und Blinker sitzt bei dir noch eine Fernsteuerungsstrecke. Der Auswertung ist es egal, ob du da einen Hebel hast oder nicht. Die bekommt Fernsteuerimpulse und muss die auswerten. Ob du an deinem Sender da einen Schalter, einen Taster, ein Drehrad oder einen Kreuzknüppel hast, ist der Auswertung völlig wurscht. Die sieht nur die Pulse, die sie vom Fernsteuerempfänger bekommt. Und die müssen zunächst mal ausgewertet werden, denn in in der Pulslänge steckt die Information, in welcher Stellung sich der Schalter auf deiner Fernsteuerung befindet. Und erst dann kann man sich darüber unterhalten, wie man die Schalterstellungen bzw. den Wechsel dieser (der sich in den Pulsen versteckt) so auswertet, dass dein Blinker entsteht. Alles in allem würde ich sagen, in 3 bis 4 Monaten fleissigem lernens bist du soweit, dass du über dein eigentlich zu lösendes Problem erstmals nachdenken kannst. In der Zwischenzeit heißt es: Grundlagen lernen. AVR-Tutorial AVR-GCC-Tutorial (*) und genau das was du die ganze Zeit verschwiegen hast, nämlich das das über eine Fernsteuerung läuft, das ist der eigentliche Knackpunkt an der ganzen Geschichte. Das ist der komplizierte Teil. Den Blinker an die Pulslängen (wenn man sie einmal hat) zu koppeln ist der Pipifax Teil in deinem Projekt.
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.