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


von Martin G. (hb9tzw)


Angehängte Dateien:

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:
1
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0) {
2
3
  asm volatile(  "eor r18, r18       ;r18<-0"                     "\n\t"
4
          "eor r19, r19              ;r19<-0"                     "\n\t"
5
          "1:"                                                    "\n\t"
6
          "add r18, %0               ;1 cycle"                    "\n\t"
7
          "adc r19, %1               ;1 cycle"                    "\n\t"  
8
          "adc %A3, %2               ;1 cycle"                    "\n\t"
9
          "lpm                       ;3 cycles"                   "\n\t"
10
          "out %4, __tmp_reg__       ;1 cycle"                    "\n\t"
11
          "sbis %5, 1                ;1 cycle if no skip"         "\n\t"
12
          "rjmp 1b                   ;2 cycles. Total 10 cycles"  "\n\t"
13
          :
14
          :"r" (ad0),"r" (ad1),"r" (ad2),"z" (signal),
15
                "I" (_SFR_IO_ADDR(PORTE)), "I" (_SFR_IO_ADDR(PINA))
16
          :"r18", "r19" 
17
  );
18
}

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

von Falk B. (falk)


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

von Martin G. (hb9tzw)


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

von Falk B. (falk)


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

von spess53 (Gast)


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

von Martin G. (hb9tzw)


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

von spess53 (Gast)


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

von Jobst M. (jobstens-de)


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

von Martin G. (hb9tzw)


Angehängte Dateien:

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

von spess53 (Gast)


Lesenswert?

Hi

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

Freut mich.

MfG Spess

von Helmut L. (helmi1)


Lesenswert?

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

Gruss Helmi

von Simon K. (simon) Benutzerseite


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

von Martin G. (hb9tzw)


Lesenswert?

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

von Jack (Gast)


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

von Karl H. (kbuchegg)


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 :-)
1
#include <stdio.h>
2
#include <math.h>
3
4
int main()
5
{
6
  FILE * outFile;
7
  double alpha, increment;
8
  int nrValues, value;
9
10
  outFile = fopen( "wave.h", "w" );
11
12
  increment = 2 * PI / 256;
13
  nrValues = 0;
14
15
  for( alpha = 0.0; alpha < 2 * PI + increment / 2.0; alpha += increment ) {
16
17
    value = (int)( sin( alpha ) * 128.0 + 128.0 + 0.5 );
18
    fprintf( outFile, "%02x", value );
19
20
    nrValues++;
21
    if( nrValues == 16 ) {
22
      fprintf( outFile, "\n" );
23
      nrValues = 0;
24
    }
25
    else
26
      fprintf( outFile, ", " );
27
  }
28
29
  fclose( outFile );
30
}

von Jack (Gast)


Lesenswert?

@Karl heinz Buchegger
danke, würde ich dem Nächst probieren

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.