Hallo, Mit einem Atmega 162 möchte ich ein niederfrequentes Sinussignal ausgeben. Da der µC noch andere Dinge machen soll, hatte ich mir gedacht das Auslesen der LUT über eine von Timer 0 gesteuerte ISR zu realisiseren. Habe über den ISR TIMER0_COMP_vect erstmal versucht das Auslesen direkt zu machen. Das ging nicht.Habe es entsprechend auskommentiert gelassen.(s.Code) Dann habe ich das Aufrufen in die while Schleife gelegt, in Abhängigkeit von einer Flag, die in der ISR gesetzt wird. Das Ergebnis, was ich über PD4 ins Oszi gebe, sieht gruselig aus, entspricht in keinster Weise der ISR freien "delay-Variante" Kann mir jemand einen Tipp geben, was ich falsch mache? Gruß Thomas
das geht aber nicht so dass du einfach bei jedem Interrupt die 72 Werte raushaust, also den Interrupt mit der gewünschten Abtastrate kommen lassen, dann bei jedem Interrupt einen neuen Wert ausgeben
Hi
>Kann mir jemand einen Tipp geben, was ich falsch mache?
Wenn dein Flag gesetzt wurde gibst du alle Werte deiner Tabelle in einem
Rutsch aus. Du darfst aber nur einen (den nächsten) Wert ausgeben.
MfG Spess
Auweia: ISR (TIMER0_COMP_vect) // { // for(a = 1; a < 72; a++) //{ //OCR3A = Tabelle[a]; //} //} { flag = 1; } 1. Ein Array[72] hat den Index 0..71 und nicht 1..72. 2. Du darst pro ISR-Aufruf nur einen Wert ausgeben, nicht die ganze Tabelle. Hab ich gerade anderswo gepostet: Der Mensch denkt dezimal, der µC rechnet binär. Deshalb am besten beim Programmieren Dezimalmodus im Gehirn abschalten. --> Tabelle hat 64 oder 128 Einträge. #define TABLESIZE 64 ISR (TIMER0_COMP_vect){ OCR3A = Tabelle[a=(a+1)&(TABLESIZE-1)]; }
wennst dich schon eprofi nennst: i<72 -> array würde von 1 bis 71 adressiert. Deshalb am besten beim Programmieren Dezimalmodus im Gehirn abschalten. --> Tabelle hat 64 oder 128 Einträge. so einen quatsch, d.h. wenn ich mal 65 byte als datenspeicher brauche dann muss ihc 128 byte im RAM verbraten weil der uC nichts anderes kennt? vlt. solltest das nochmal überdenken! grüße
> unsigned int a; 8 Bits reichen! > OCR3A = Tabelle[a=(a+1)&(TABLESIZE-1)]; Funktioniert nur, wenn TABLESIZE ein Vielfaches von 2 ist. So wird die ISR noch schneller: ISR (TIMER0_COMP_vect){ static uint8_t a; OCR3A = Tabelle[++a&(TABLESIZE-1)]; }
Hi >So wird die ISR noch schneller: >ISR (TIMER0_COMP_vect){ > static uint8_t a; > OCR3A = Tabelle[++a&(TABLESIZE-1)]; > } Ein bitweises 'and' ist Blödsinn. Wann schon, dann ein Modulo. Allerdings dürfte das dir ISR stark aufblähen. MfG Spess
gggg, glaubst Du im Ernst, ich hätte das übersehen? Das ändert nichts an der Korrektheit meiner Aussage und dem Nicht-wie-gewünscht/erwartet-Funktionierens des Programmes. spess53, was ist der Unterschied zwischen &63 und %64 oder &127 und %128 (zumindest im positiven Zahlenraum)?
Hi >spess53, was ist der Unterschied zwischen &63 und %64 oder &127 und >%128 (zumindest im positiven Zahlenraum)? Hast du doch selbst gaschrieben: >Funktioniert nur, wenn TABLESIZE ein Vielfaches von 2 ist. Also bei einer Tabelle mit 72 Einträgen unbrauchbar. MfG Spess
>>Funktioniert nur, wenn TABLESIZE ein Vielfaches von 2 ist. > Also bei einer Tabelle mit 72 Einträgen unbrauchbar. 72 ist ein Vielfaches von 2... :-o Kontrollrechnung: 2 * 36 = 72 Sollte wohl heißen: Funktioniert nur, wenn TABLESIZE eine Zweierpotenz ist.
Vielen Dank für die Antworten! ich dachte allerdings, dass ich mit for (a=1; a<72; a++) {OCR3A = Tabelle[a]}; die Tabellenpositionen inkrementiere. Ich hatte zuvor die Variante ohne ISR mit delay gebastelt.Das funktioniert. (s.Code) Habe auch ein Oszibild angehängt. Der Sinus ist pur , nicht geglättet etc. Wieso klappt das in der while Schleife mit dem inkementieren und in der ISR nicht? Sorry, bin Anfänger würde es gern verstehen..... Gruß Thomas
Thomas schrieb: > ich dachte allerdings, dass ich mit > > for (a=1; a<72; a++) > {OCR3A = Tabelle[a]}; > > die Tabellenpositionen inkrementiere. die Tabellenpos. inkementierst du schon, aber du änderst die Werte von OCR3A so schnell, das die PWM dem gar nicht folgen kann! Wie gesagt, speichere die Tabellenpos in einer globalen Variable und in der ISR steht dann nur
1 | OCR3A = Tabelle[a++]; |
2 | if (a>71) a=0; |
Sascha
@ Thomas (Gast) >Wieso klappt das in der while Schleife mit dem inkementieren und in der >ISR nicht? Weil es ein anderes Prinzip ist. Mit delay geht es in einer normalen Schleife, 1.Wert ausgeben 1ms Delay 2. Wert ausgeben 1ms Delay 3. Wert ausgeben 1ms Delay .... Mit ISR ist das Delay durch den Timer eine Schleife. Z.B 1ms Timer ISR. 1ms, ISR, 1. Wert ausgeben 2ms, IRS, 2. Wert ausgeben 3ms, ISR, 3. Wert ausgeben Der nächste ISR kommt 1ms später, dort wird der nächste Wert ausgegeben. Wenn du in der ISR in einer Schleife alle auf einmal ausgibst, gibt es zwischen den Werten keine Pause! Lies mal den Artikel Multitasking, dort ist ein Beispiel drin, der das erklärt. Auch wenn dort keine ISRs drin sind, das Prinzip ist das Gleiche. MFG Falk
Aha! das hat mir nun wirklich weitergeholfen! Vielen Dank. Den Artikel Multitasking werde ich mir zu Gemüte führen.... Gruß Thomas
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.