Forum: Mikrocontroller und Digitale Elektronik 8bit DAC an Mega32


von Christian B. (Gast)


Lesenswert?

Mein Problem ist folgendes:


Ich steuere ein 8bit parallel adc AD7305 mit einem ATmega32L.
Ich erzeuge mit einer LookUp-Table (sin_table[255]={...})
ein 4-phasen wechselspannungs-Signal.

Mit den internen ADC des mega lese ich eine Spannung 0...5V ein, wobei
    0V einer externen Spannung von -10V entsprechen(links)
und 5V einer externen Spannung von +10V entsprechen(rechts)

funktioniert auch ganz gut,wenn ich eine richtung Programmiere.
Das Programm sieht in etwa so aus(grob)



main()
{
 unsigned char sin_table[255]={...};
 unsigned char ...
 unsigned int ...

 ad7305init();
 intern_adc_init(CH0);

 for{;;}
  {
   adc_value = hole_adcWandlungswert();
   ...

if(X <= Y)
  {   ...
   ...
   schrittweite = ...;   // schrittweite in der die Tabelle
                         // durchlaufen wird

   adresse += schrittweite;

   dacOut(CH_d, sin_table[adresse]);        // Kanal A Wert zuweisen
   dacOut(CH_c, sin_table[64 + adresse]);   // Kanal B ...
   dacOut(CH_b, sin_table[128 + adresse]);
   dacOut(CH_a, sin_table[192 + adresse]);
   }

 }

}

....


So wie der Code oben sinngemäß widergegeben ist funktioniert alles
wunderbar.

ABER, und jetzt kommts, wenn ich eine zweite 'if' -Anweisung
hinzufüge
in etwa so

if(x <= y)
{...}
        +
if(x > y)
{...}

dann funktioniert alles nicht mehr richtig. Hat den anschein als würde
etwas "übersprechen" in der Adressierung. Habe jedoch auch nach
längerer suche keine Verdrahtungsfehler gefunden. Habe die Vermutung,
dass der Mege(compiler) bestimmte Feldvariablen überschreibt, so dass
das Programm an manchen stellen was vergisst. Kann irgendwer
helfen????


bin schon recht verzweilfelt, da die sache eigentlich eine ganz
einfahce ist. ich will nur ein Feld durchlaufen nur mit umgekehrter
Reihenfolge der adressierung Verdrahtet über A0 und A1.

von Sebastian (Gast)


Lesenswert?

verändererst du "x" oder "y" in deinen if blöcken??


x=1
y=2

if(x <= y)
{
  mach irgendwas...
  x=(ergebnis von irgendwas);  => wenn ergebnis > 2 ist dann ist das
2.
  if auch wahr abfrage.
}

if(x > y)
{...}


schon mal mit "else if(x > y)" probiert?

von Christian B. (Gast)


Angehängte Dateien:

Lesenswert?

also im ersten if wird verglichen, ob

die adc-größe größer als der halbe wert ist

also
     if(adc >= 512){...}

und im zweiten, ob die adc-größe kleiner als der halbe wert ist

also
     if(adc < 512){...}


Der fehler tritt sofort auf, sowie ich "eine" zweite, egal welche,
if
hinzufüge...


Else habe ich anfangs auch schonmal ohne erfolg probiert. und zwar in
der Form:

         if(adc >= 512){...}

         else{...}


muss man "else if{...}" schreiben, damit es funktioniert?
ich würde euch ja gern ein Oszibild von den Signalen schicken, doch ich
habe die technischen mittel dazu nicht. Ich versuche vielleich bis
morgen es mit hand zu zeichnen.
Denn im Grund funktioniert es ja, doch der eigentliche Werte-Verlauf,
wird von einem scheinbar zweiten Werte-Verlauf gestört. dieser zerhakt
das eigentlich signal stark.
Wie gesagt, hab mir auch mal mit dem Oszi den Ablauf der
Adressleitungen A0 und A1 angesehn, wenn der Fehler auftritt, ist dort
der wurm drin, doch ich konnte nichts finden, was die adress-infos
überschreiben soll.

von Uwe Nagel (Gast)


Lesenswert?

Dumme Frage: greifst Du hier nicht ständig hinter dein Array unsigned
char sin_table[255] ?
Bei den Zugriffen steht u.a.
  sin_table[192 + rueck]
und rueck hat 8 Bit und wird durch nichts begrenzt. Also greifst Du
auch mal auf sin_table[192+255] zu und da steht irgendwas...
Oder was habe ich da übersehen ?

Uwe

von Christian B. (Gast)


Lesenswert?

@Uwe

Ja kann sein, dass dies ein problem ist, dass ich noch nicht genau
genug betrachtet habe.

Gedacht hab ichs mir so:

meine Sinustabelle besteht aus 2^8(0...255) Elementen und ist vom Typ
'unsigend char'.
... und ich lasse meine laufvariable (auch 'unsigned char') einfach
immer hochzählen und egal wieviel ich addiere, nach dem Überlauf wird
weiter addiert (192 + 255 = 192).

Glaube ich hatte auch schonmal versucht diese Laufvariable vor
Benutzung in sin_table[...] in eine 'unsigned char' auszudrücken
etwa so:
------------------------------------
unsigned char LW, vor;
...
LW = 192 + vor;
dac_out(CH_a, sin_table[...]);
------------------------------------

Hatte so aber glaube ich auch keinen sichtlich entscheidenden Erfolg.
Werde mich aber wohl nochmals damit auseinandersetzen, nachdem du mich
förmlich nochmals mit der Nase draufgestupst hast. g

THX UWE

####################

nur nochmal zum Verständnis, wenn ich eine 'unsigned char'-Größe
munter erhöhe, egal wie groß der wert (0..wert..255) ist den ich
addiere, wird nach dem Überlauf der Rest zu NULL addiert?!
weil genau so mein prinzip ablaufen soll.

####################


Für Hilfe bin ich sehr dankbar
littlecb

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.