Forum: Mikrocontroller und Digitale Elektronik sinus LUT über Interrupt auslesen


von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

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

von Walter (Gast)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

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

von eProfi (Gast)


Lesenswert?

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)];
  }

von gggg (Gast)


Lesenswert?

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

von eProfi (Gast)


Lesenswert?

> 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)];
  }

von Spess53 (Gast)


Lesenswert?

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

von eProfi (Gast)


Lesenswert?

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)?

von Spess53 (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>>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.

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

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

von Sascha W. (sascha_w)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@  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

von Thomas (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.