sinus LUT über Interrupt auslesen

Gast #1981872
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
Angehängte Dateien:
Gast #1981889
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
Gast #1981896
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
Gast #1981902
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)];
  }
Gast #1981928
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
Gast #1981945
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)];
  }
Gast #1981956
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
Gast #1981969
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)?
Gast #1981977
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
Gast #1982261
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
Angehängte Dateien:
#1982276
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
#1982381
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren