Hallo zusammen. Ich habe ein Rechtecksignal bei dem ich eine Frequenzauswertung machen will (Schwellfrequenzüberwachung). Dazu benötige ich eine Positive Flanke und ich weiss nicht wie das geht, bin Anfänger auf MCs. Meine Programmierüberlegung: while(1) { if (POSITIVE FLANKE PINB) { _delay_ms(0.8); if (PINB & (1<<PB2)) { laenger_0_8ms(); } else { kuerzer_0_8ms(); } } } void laenger_0_8ms() { PORTB=(0<<PB0); } void kuerzer_0_8ms() { PORTB=(1<<PB0); } Jetzt weiss ich nur nicht wie ich eine positive Flanke mache, kann mir da jemand helfen? Danke bereits im Voraus und Gruss
Entweder du tastest ab, wie es dein Beispiel zeigt, oder die verwendest PCINT (Pin change interrupts). Zur Abtastung und Erkennung der positiven Flanke:
1 | int state = (PINB << PB2) & 1; /* PB2 auslesen */ |
2 | |
3 | while(1) { |
4 | int current = (PINB << PB2) & 1; |
5 | if(state == 0 && current) { |
6 | /* letzter Zustand 0 und PB2 ist jetzt das erste mal 1
|
7 | --> positive Flanke */
|
8 | state = 1; |
9 | }
|
10 | else if(state == 1 && !current) { |
11 | /* letzter Zustand 1 und PB2 ist jetzt das erste mal 0
|
12 | --> negative Flanke */
|
13 | state = 0; |
14 | }
|
15 | }
|
Nicht funktionierend ist
1 | _delay_ms(0.8) |
da wird ein Integer erwartet. Zu Interrupts: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Interrupts
U. H. schrieb: > Dazu benötige ich eine Positive Flanke und ich weiss nicht wie das geht, > bin Anfänger auf MCs. Hallo! Ich würde den INT0 verwenden. Für den kannst du einstellen, den kannst du nämlich so einstellen, dass er nur durch eine positive Flanke ausgelöst wird und nicht durch eine negative. Beim Pin-change-Interrupt ist das leider nicht möglich. Bis zu welcher Frequenz soll die Auswertung funktionieren? Wenn du in den MHz-Bereich kommst, dann würde ich eher Assembler verwenden. Als Alternative könntest du die Takt-Zählfunktion des µC verwenden. Je nachdem, wie schnell du auf den Frequenzwechsel reagieren willst...
Von einer Hardwareflanke INT0 habe ich schonmal etwas gehört, aber wie verwende ich diese? wird dadurch nicht ein Interrupt ausgelöst? Danke und gruss
U. H. schrieb: > Von einer Hardwareflanke INT0 habe ich schonmal etwas gehört, aber > wie > verwende ich diese? wird dadurch nicht ein Interrupt ausgelöst? > > Danke und gruss Das ist der Knackpunkt ! Du liest Dir erstmal das Datenblatt durch und versuchst zu verstehen was INT0 bedeutet und wie man die Register für die steigende Flanke beschickt. Dann nimmst Du den INT0 Interrupt der jedesmal mit der steigenden Flanke ausgelöst wird und zählst in der IRQ eine volatile Variable hoch. Nun weißt Du wie oft das passiert ist und brauchst noch was um Deine Frequenz zu erhalten ?
Ja, GANZ SCHRECKLICH, bei richtiger Beschaltung und Freigabe des INT0 wird dieser Interrupt ausgelöst! Und nun? Dann wertest du ihn in der INT0-Interrupt-Routine aus. Und dann? Dann haste, was du wolltest.
Ich muss ja in die Bits ISC01 und ISC00 im MCUCR je eine 1 schreiben, um eine rising edge Interrupt auslösen zu können. wie mach ich das nun? und wo? vor der while(1) Schleife in der main Schleife oder vor der main Schleife? und wie setze ich die Bits? So: MCUCR=(1<<ISC00)|(1<<ISC01); ? und wie verwende ich nun das Interrupt das ausgelöst wird? Danke und Gruss
U. H. schrieb: > Ich muss ja in die Bits ISC01 und ISC00 im MCUCR je eine 1 > schreiben, um > eine rising edge Interrupt auslösen zu können. > > wie mach ich das nun? und wo? vor der while(1) Schleife in der main > Schleife oder vor der main Schleife? > > und wie setze ich die Bits? > So: > MCUCR=(1<<ISC00)|(1<<ISC01); ? > und wie verwende ich nun das Interrupt das ausgelöst wird? > > Danke und Gruss Ob Du die Initialisierung nun direkt in der main oder einer eigenen init() Prozedur machst ist egal. Das es VOR der Hauptschleife sein muß sollte klar sein, oder willst Du für immer den IRQ neu anschalten ? Woher kennst Du die Bits die gesetzt werden müssen ? Lies Dir hier die Tutorials durch, dann weißt Du auch wie man einen Internetvektor verwendet. Achte bei der Variable die in der IRQ einfach
1 | uZaehler++; |
macht darauf das sie volatile ist und wie bekommst Du nun eine Frequenz von dem Wert ?
Sorry aber was ist IRQ? Und wäre es vielleicht möglich, dass Du mir ein Beispielprogramm machen könntest, wie ich das Interrupt verwenden kann, das durch die Positive Flanke ausgelöst wird? Die Aufgerufenen Bits reichen schon oder? Oder muss ich da auch noch etwas machen?
Hast du noch nie ein Programm geschrieben? Ein C-Programm beginnt mit der main()-Funktion. Dann initialisiert man alles - und danach beginnt eine while(1)-Schleife, in der alles abgehandelt wird, was vom Programm bearbeitet werden soll. Neben der main()-Funktion werden Interrupt-Routinen (z.B. für INT0) und weitere Funktionen programmiert. Hier musst du - ein paar Speicherplätze global vorhalten (z.B. für den Messwert aus der INT0-Routine), - einen freilaufenden Timer passend für die Zeitmessung initialisieren und den - INT0 initialisieren. In der INT0-Routine fragst du den Zählerstand des Timers ab, speicherst ihn ab und setzt den Timer wieder auf NULL. In der while(1)-Schleife schaust du nach, ob am vereinbarten Speicherplatz ein neuer Messwert (ungleich NULL) von der INT0-Routine vorhanden ist. Diesen Messwert kopierst du und schreibst in den vereinbarten Speicherplatz wieder eine NULL. Jetzt überprüfst du den Wert und reagierst entsprechend... Wenn das nicht hilft, solltest du erst mal mit "hello_world.c" anfangen!
U. H. schrieb: > Sorry aber was ist IRQ? Tante Wikipedia ist so schlau, die weiß fast alles. Probiers ruhig mal, sie beißt nicht! :-) Besser erklären als sie könnt ich es auch nicht.
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.