mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DDS mit R/2R-Netzwerk, Output unsauber


Autor: Martin Geissmann (hb9tzw)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mein Signalgenerator hat Fortschritte gemacht und ich habe jetzt ein 
Ausgangssignal, dieses sieht aber aus wie in signal.jpg. Die Sinuskurve 
ist erkennbar, aber leider eben auch nur etwa die Hälfte davon.

Ich habe keine Ahnung, was diese Störung genau verursachen könnte. Die 
Schaltung mit dem R/2R-Netz ist auf schematic.gif und die Routine, die 
die Welle ausgibt, sieht so aus:
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0) {

  asm volatile(  "eor r18, r18       ;r18<-0"                     "\n\t"
          "eor r19, r19              ;r19<-0"                     "\n\t"
          "1:"                                                    "\n\t"
          "add r18, %0               ;1 cycle"                    "\n\t"
          "adc r19, %1               ;1 cycle"                    "\n\t"  
          "adc %A3, %2               ;1 cycle"                    "\n\t"
          "lpm                       ;3 cycles"                   "\n\t"
          "out %4, __tmp_reg__       ;1 cycle"                    "\n\t"
          "sbis %5, 1                ;1 cycle if no skip"         "\n\t"
          "rjmp 1b                   ;2 cycles. Total 10 cycles"  "\n\t"
          :
          :"r" (ad0),"r" (ad1),"r" (ad2),"z" (signal),
                "I" (_SFR_IO_ADDR(PORTE)), "I" (_SFR_IO_ADDR(PINA))
          :"r18", "r19" 
  );
}

Wenn sich da jemand einen Reim darauf machen kann wäre ich wirklich sehr 
froh, ich hab mir schon den Kopf zerbrochen aber kenne mich mit der 
Materie wohl einfach noch zu wenig aus.

Grüsse
Martin

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Martin Geissmann (hb9tzw)

>Ich habe keine Ahnung, was diese Störung genau verursachen könnte.

Ich tippe mal auf das Zweierkomplement. Deine Sinustabelle ist 
vorzeichenbehaftet. Du muss sie aber vorzeichenlos mit Offset erzeugen.

MFG
Falk

Autor: Martin Geissmann (hb9tzw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Falk

Dies ist die Sinustabelle:

const uint8_t sinewave[] PROGMEM = { //256 values
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0x 
ab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0x 
d5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0x 
f3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0x 
ff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0x 
f8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0x 
de,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0x 
b6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x 
86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x 
54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x 
2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x 
0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x 
00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x 
07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x 
21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x 
49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x 
79,0x7c
};

Kannst du das bestätigen? Ich verstehe, was du meinst, aber meiner 
Meinung nach geht die Welle nie "unter Null". Oder doch?

Grüsse
Martin

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Martin Geissmann (hb9tzw)

>Kannst du das bestätigen?

Nein.

> Ich verstehe, was du meinst, aber meiner
>Meinung nach geht die Welle nie "unter Null".

Ja, deine Tabelle ist OK, da ist schon ein Offset drin.

MFG
Falk

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

> "adc %A3, %2   ;1 cycle"  "\n\t"

Da wird anscheinend nur ZL beeinflusst. Falls das Ganze aber einen 
Übertrag nach ZH benötigt, wird das nicht berücksichtigt.

MfG Spess

Autor: Martin Geissmann (hb9tzw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Spess

Kannst du das bitte etwas genauer erläutern? Ich habe die Routine nicht 
selbst entwickelt und bin überhaupt kein Assembler-Spezialist. Könnte 
das diesen Effekt hervorrufen und wie (genau) wäre der Code 
umzuschreiben?

Die Routine und die Sinustabelle stammen vom selben Autor und haben bei 
ihm offenbar funktioniert, aber vielleicht muss ja doch noch etwas 
geändert werden.

Grüsse
Martin

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Das funktioniert nur wenn die Tabelle in einem Adressbereich von 
$XX00-$XXFF liegt. Also ZH für die gesamte Tabelle einen konstanten Wert 
hat. Wenn das nicht der Fall ist, werden die Werte aus Speicheradressen, 
die nicht zur Tabelle gehören, gelesen.

Beispiel: Deine Tabelle liegt im Speicher ab $1F80 dann wäre ZH=$1F. 
Wenn auf einen Tabellenoffset von $90 zugegriffen werden soll wäre das 
die Speicheradresse $2010. Tatsächlich greift der obige Programmteil 
aber auf $1F10 zu.

MfG Spess

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich auch so. Dort werden Programmteile auf dem DAC ausgegeben.
Hatte selber dieses Problem schon, habe das Bild vom Scope wiedererkannt 
;-)

Gruß

Jobst

Autor: Martin Geissmann (hb9tzw)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ihr beiden

Coole Sache, dank dem Hinweis habe ichs hinbekommen, aber darauf wäre 
ich sonst im Leben nie gekommen als C-Programmierer ;-)

Das dauerte noch etwas bis ich den Speicherbereich auch im AVRStudio 
zuweisen konnte mit der automatischen Makefile-Erzeugung, aber bei 
richtigem Eintrag unter "Project" > "Configuration Options" > "Memory 
Settings" funktionierts.

Vielen Dank!

Grüsse
Martin

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Coole Sache, dank dem Hinweis habe ichs hinbekommen,...

Freut mich.

MfG Spess

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An deinem DAC Ausgang fehlt noch ein Tiefpass um die Aliasfrequenzen 
auszufiltern. Sonst sieht dein Sinus aus wie mit Stacheldraht bewehrt.

Gruss Helmi

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da musst du aber aufpassen. Stell dir vor du  hast die Lockbits gesetzt 
und jemand kann dein Programm trotzdem über die generierte Spannung 
auslesen, wegen einem Bug ;)

Autor: Martin Geissmann (hb9tzw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-) Ich glaub den Tiefpass baue ich trotzdem noch rein, danke für den 
Tip!

Autor: Jack (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Martin
Wie kann man aus einem Analogen Signal so eine Hex.Tabelle erstellen, 
Software?? oder Stift,Papier und gerechnet
würde ich gerne meine R2R an verschiedene Signalformen testen, Sägezahn 
...
DANKE IM VORAUS
mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am einfachsten schreibt man sich am PC dafür ein Programm :-)

Im Prinzip kann man auch zb mit Excel die Werte ganz einfach erzeugen, 
allerdings ist dann bei der Übernahme in den C-Code wieder Handarbeit 
abgesagt.

Daher: den C Compiler am PC anwerfen und die Kurvenform programmieren.
Die meisten Kurvenformen sind ja trivial. Die meiste Arbeit geht für das 
anständige Formatieren der Ausgabe drauf :-)
#include <stdio.h>
#include <math.h>

int main()
{
  FILE * outFile;
  double alpha, increment;
  int nrValues, value;

  outFile = fopen( "wave.h", "w" );

  increment = 2 * PI / 256;
  nrValues = 0;

  for( alpha = 0.0; alpha < 2 * PI + increment / 2.0; alpha += increment ) {

    value = (int)( sin( alpha ) * 128.0 + 128.0 + 0.5 );
    fprintf( outFile, "%02x", value );

    nrValues++;
    if( nrValues == 16 ) {
      fprintf( outFile, "\n" );
      nrValues = 0;
    }
    else
      fprintf( outFile, ", " );
  }

  fclose( outFile );
}

Autor: Jack (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger
danke, würde ich dem Nächst probieren

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.