Forum: Mikrocontroller und Digitale Elektronik DDS Sinus erzeugung


von Fantamann (Gast)


Lesenswert?

Guten Morgen in die Runde.


Ich habe mir ein Programm geschrieben, das mittels Lookup Table einen 
Sinus ausgibt. Das tut es auch soweit.

Allerdings erreiche ich nur 1kHz Ausgangsfrequenz, aber da wird der 
Sinus schon enorm eckig und man sieht die Abtastschritte deutlich (ohne 
Filter).

Eckdaten:

- DDS Berechnungsfrequenz: 10kHz
- ATmega16 mit Ref.Freq: 16MHz
- Phasenakkumulator: 32Bit
- Anzahl der Stützwerte im Sinus: 512

Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die 
ich durchführen muss.

Meine Frage: Was genau bestimmt die max. mögliche Ausgangsfrequenz und 
was muss ich tun um den Sinus bei höheren Werten mit mehr Punkten 
auszugeben?


Vielen Dank!

von spess53 (Gast)


Lesenswert?

Hi

Siehe:

Beitrag "DDS normal ?"

MfG Spess

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)


>Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die
>ich durchführen muss.

jain. Andere Leute schaffe deutich mehr, siehe DDS.

>Meine Frage: Was genau bestimmt die max. mögliche Ausgangsfrequenz

Mit dem Herrn Shannon.

f_max <= 1/2 f_DDS.

>und was muss ich tun um den Sinus bei höheren Werten mit mehr Punkten
>auszugeben?

Gar nichts, es ist nunmal so, dass bei höheren Frequenzen weniger 
Stützstellen verfügbar sind. Ist aber kein Problem, der FILTER am 
Ausgang löst das Problem. Den hast du aber noch nicht, darum siehst du 
unschöne Signale. Der Filter ist aber notwendig.

MFG
Falk

P S Jaja, eine DDS kann auch >1/2 f_dds ausgeben, aber das ist für 
fortgeschrittene Semester.

von Fantamann (Gast)


Lesenswert?

@Falk Brunner

Danke für die Antworten. Die max. Frequenz nach Shannung ist meines 
Verständnisses nach nur rein theoretisch. Ich muss ja schon ein
paar berechnungen durchführen. Seh ich das richtig?

Das könnte ich effizienter gestallten, da hast du recht. Filter habe ich 
auch mal drangemacht, aber der verzerrt mir mein Rechteck. Ich hab ihn 
mit
fg=10kHz ausgelegt.

von Fantamann (Gast)


Lesenswert?

>>Die Berechnungsfrequenz ergibt sich durch die Dauer der Berechnungen die
>>ich durchführen muss.
>
> jain. Andere Leute schaffe deutich mehr, siehe DDS.

Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.
Ich weiß noch nicht wie ich das effizienter gestallten kann.

von K. (Gast)


Lesenswert?

Falk Brunner schrieb:
> Ist aber kein Problem, der FILTER am
>
> Ausgang löst das Problem. Den hast du aber noch nicht, darum siehst du
>
> unschöne Signale. Der Filter ist aber notwendig.
Man sollte das dahingehend präzisieren, dass es sich um den Anti 
AliasingFilter handelt, der später nach einem DAC sitzt.

Für die rein digitalen Werte ist man nach der DDs fertig, wenn es weiter 
verrechnet werden soll. Das einzige, was dnekbar wäre, ist ein 
FIR-Filter, um die Funktion zu glätten, wenn die Tabelle zu wenig 
Y-Auflösung hat.

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)

>Danke für die Antworten. Die max. Frequenz nach Shannung ist meines
>Verständnisses nach nur rein theoretisch.

Auch praktisch.

> Ich muss ja schon ein paar berechnungen durchführen. Seh ich das richtig?

Nö. Für deine Zwecke passt das schon. Die Vollprofis rechnen noch ne 
Weile an einem perfekten Filter, der dann 120dB Dämpfung für die 
Oberwellen bringt.

>Das könnte ich effizienter gestallten, da hast du recht. Filter habe ich
>auch mal drangemacht, aber der verzerrt mir mein Rechteck.

Logisch, aber du willst doch einen SINUS! Wenn man auch ein jitterarmes 
RECHTECK haben will, muss man NACH dem Filter einen Komparator 
platzieren.

>Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.

???
Die macht man doch nur einmalig, wenn man die Frequenz ändert.

>Ich weiß noch nicht wie ich das effizienter gestallten kann.

Poste Code. Oder schau dir an, wie dass andere machen. Der Jesper macht 
es schon sehr gut.

http://www.myplace.nu/avr/minidds/index.htm

MfG
Falk

von Fantamann (Gast)


Lesenswert?

Ich hab vergessen zu erwähnen dass ich alles einprogrammiert habe: 
Sinus, Rechteck, Sawtooth, Dreieck.

>>Die größte Verzögerung erzeugt mir die berechnung der Schrittweite.
>
> ???
> Die macht man doch nur einmalig, wenn man die Frequenz ändert.

Du hast vollkommen recht. Ich jedesmal mitberechnet. Wenn ich es 
auslagere, dann hab ich ca. 15µs die ich brauche für die Ausgabe. Das 
macht etwa 65kHz Berechnungsfrequenz. Damit das ganze Filterlos noch 
nach Sinus aussieht, brauche ich etwa 10 Werte, das heißt über 6,5kHz 
komm ich nicht hinaus.

Das erscheint mir wenig :-/

von Fantamann (Gast)


Lesenswert?

Bei Änderung der Frequent
1
//Critical Section
2
stepsize = (uint64_t)fout*(MAX/FCALC);
3
stepsize_old = stepsize;


Innerhalb eines Timers mit 100us Takt
1
  phase = (counter >> 24);
2
  counter = counter + stepsize;
3
4
  if(output==ON)
5
  {
6
    if(mode == SINE)
7
      putDAC(sine[phase]);
8
    else if(mode == SAW)
9
      putDAC(saw[phase]);
10
    //...
11
    else
12
      putDAC(0x00);
13
  }
14
  else
15
  {
16
    putDAC(0x00);
17
  }

von Falk B. (falk)


Lesenswert?

Formal ist dein Code richtig, aber für maximale Leistung braucht man 
hier wirklich Assembler wie beim Jesper. Dann braucht man auch nur 8 
Takte pro Datenausgabe und kommt damit auf gut 2 MHz Ausgabetakt mit 
einem AVR!
Was man schon mal ändern könnte ist, die Abfrage der Wellenform aus der 
ISR rauszunehmen, das spart reichlich Zeit. mit einem Trick kann man 
auch das Schieben um 24 Bit sparen, über einen Union-Zugriff. Und 
Funktionen ruft man in ZEITKRITISCHEN ISRs besser nicht auf sondern 
schreibt es direkt hin. etwa so
1
#define PORT_DAC PORTD
2
3
// Tabellen für Wellenform
4
5
uint8_t wave_sin[512] = { blub};
6
uint8_t wave_saw[512] = { peng};
7
uint8_t wave_off[512] = { nischt};
8
9
uint8_t *table_p;
10
11
// im main bei Auswahl der Wellenform
12
13
  if(output==ON)
14
  {
15
    if(mode == SINE)
16
      table_p = wave_sin;
17
    else if(mode == SAW)
18
      table_p = wave_saw;
19
    //...
20
  }
21
  else
22
  {
23
    table_p = wave_off;
24
  }
25
26
// ISR
27
union {
28
    uint32_t counter;
29
    uint8_t phase;
30
} dds_cnt_t;
31
32
dds_cnt_t dds_cnt;
33
34
  dds_cnt.counter = dds_cnt.counter + stepsize;
35
  PORT_DAC = table_p(dds_cnt.phase);

von Fantamann (Gast)


Lesenswert?

okay, danke. Darüber werde ich mal nachdenken.

Meine eingangs gestellt Frage, welcher Teil des Codes jetzt bestimmend 
für die max. Ausgangsfrequenz ist, hast du jetzt indirekt beantwortet.

Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben 
hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist. 
Alles andere berechne ich aus dem counter-Wert heraus.

Zum Beispiel
1
if(mode == SAW)
2
      putDAC(phase);

Das mit der Union werde ich aber in Angriff nehmen.

Danke und Grüße

von Falk B. (falk)


Lesenswert?

@Fantamann (Gast)

>Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben
>hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist.
>Alles andere berechne ich aus dem counter-Wert heraus.

Was schon mal ein weiterer Leistungsverlust ist. Und das alles wegen ein 
paar läppischen Bytes? Die müssen nicht im RAM liegen, ein Lesezugriff 
auf den Flash über pgm_read_byte ist praktisch genauso schnell. Oder du 
kopierst jeweils bei der Auswahl die Daten vom Flash in den RAM, das 
wäre ein guter Kompromiss.

MFG
Falk

von Fantamann (Gast)


Lesenswert?

Falk Brunner schrieb:
> @Fantamann (Gast)
>
>>Das mit der Auswahl der Wellenform funktioniert so wie du es beschrieben
>>hast nicht bei mir, weil die nur der Sinus im Speicher abgelegt ist.
>>Alles andere berechne ich aus dem counter-Wert heraus.
>
> Was schon mal ein weiterer Leistungsverlust ist.

Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes 
aus dem Speicher mit anschließender ausgabe schneller ist als ein 
einfaches:
1
PORTD = counter;

?

Counter muss ich doch sowieso inkrementieren.

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)

>Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes
>aus dem Speicher mit anschließender ausgabe schneller ist als ein
>einfaches:

>PORTD = counter;

Weil deine ganzen Abfragen der Wellenform immer wieder ausgeführt werden 
müssen! Deine if else Kette.

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Fantamann schrieb:

>> Was schon mal ein weiterer Leistungsverlust ist.
>
> Das verstehe ich nicht. Wie kann es sein, dass ein auslesen eines bytes
> aus dem Speicher mit anschließender ausgabe schneller ist als ein
> einfaches:
>
>
1
PORTD = counter;

Weil du in deiner ISR Fallunterscheidungen brauchst!
Auch die kosten Zeit!

In der ISR willst du nach Möglichkeit nur noch Bytes an den Port 
rausblasen. Nicht mehr. Alles was nicht unmittelbar damit zusammenhängt 
ist für den µC Arbeit, die nicht sein muss.
Du willst nicht da irgendwelche Sonderfälle berücksichtigen müssen oder 
sonstiges bedenken müssen. Die ISR soll sich darauf stützen können, dass 
das alles für sie schon so mundgerecht aufgearbeitet wurde, dass sie nur 
noch Bytes schaufeln muss.

Das geht dann in allen Fällen immer gleich schnell und erlaubt dir, die 
ISR Aufruffrequenz bis ans Limit zu treiben. CTC_Modus und den soweit 
hochtreiben, dass gerade noch soviel Rechenzeit übrig bleibt, dass du 
per Bedienelement die Ausgabe wieder abstellen kannst (weil du zb den 
Wert verändern musst), indem du notfalls den Timer stoppst und so 
Rechenlast durch die ISR wegnimmst.

Bei Falk kommt das im Code nicht so gut raus, aber das hier
1
ISR( ... )
2
{
3
  dds_cnt.counter = dds_cnt.counter + stepsize;
4
  PORT_DAC = table_p[dds_cnt.phase];
5
}

ist seine ganze ISR. Absolutes Minimum. Noch weniger geht nicht.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

spess53 schrieb:
> Siehe:
> Beitrag "DDS normal ?"
> MfG Spess

Hi, dieser Thread dort ist sehr lang geworden und geht meist um mein 
Unvermögen....
Niemand liest mehr bis zum Ende :0(

Hier mein Stand der Dinge.
Interrupts taugen nicht.
Hochsprachen taugen nicht.
Für diesen Zweck zählt jede Nanosekunde.

Grüße Werner

von Route_66 (Gast)


Lesenswert?

Hallo!
@Falk: Der jesper braucht übrigens 9 Takte. Deshalb machen sich bei 
seiner 256er-Tabelle Quarzfrequenzen mit Vielfachen von 9x256 besonders 
gut, sind aber nicht handelsüblich.

von Falk B. (falk)


Lesenswert?

@Route_66 (Gast)

>@Falk: Der jesper braucht übrigens 9 Takte.

OK, dann eben 9.

> Deshalb machen sich bei
>seiner 256er-Tabelle Quarzfrequenzen mit Vielfachen von 9x256 besonders
>gut, sind aber nicht handelsüblich.

Ist vollkommen egal. Perfekt jitterfrei sind sowieso nur Frequenzen mit 
2^n im Increment der DDS, macht bei 24 Bit nur 23 Frequenzen. Der Rest 
jittert sowieso, mal mehr, mal weniger.

MFG
Falk

von Werner (Gast)


Lesenswert?

Falk Brunner schrieb:
>>@Falk: Der jesper braucht übrigens 9 Takte.
> OK, dann eben 9.

Schon die bescheidene Qualität des UrJesper kann man einfach steigern.
Vorausgesetzt man kopiert die Tabellen in das SRAM und recycled den 
rjmp.


  add    r28,r24
LOOP1:
  adc    r29,r25    ; 1
  adc    r30,r26    ; 1
  lp                ; 2
  out    PORTB,r0   ; 1    UpDate
  add    r28,r24    ; 1
  adc    r29,r25    ; 1
  adc    r30,r26    ; 1
  add    r28,r24    ; 1
  lp                ; 2
  out    PORTB,r0   ; 1    UpDate
  rjmp   LOOP1      ; 2 => 14/2 = 7 cycles

und dann geht natürlich noch viel mehr.

von Werner (Gast)


Lesenswert?

Werner schrieb:
> lp                ; 2

Tipfehler lp = ld :0( RAM eben nicht FLASH sind schon 11,5%

Jespers Auflösung für den Sägezahn kann man in 5 Takten erledigen.
Es Jittert nur viel weniger....

    add  r28,r24
    STL2:
    adc  r29,r25     ; 1
    adc  r30,r26     ; 1
    out  PORTD,r30   ; 1  UpDate
    add  r28,r24     ; 1
    adc  r29,r25     ; 1
    adc  r30,r26     ; 1
    add  r28,r24     ; 1
    out  PORTD,r30   ; 1  UpDate
    rjmp STL2;       ; 2  => 10/2 = 5 cycles

eine Tabelle braucht es dann nicht

von Werner (Gast)


Lesenswert?

Jespers Rechteck kann man kaum so nachmachen.
Nimmt man einen AVR der PIN toggle kann ( evtl. nicht fair, ich kenne 
seinen Chip nicht ) kann man ein Rechteck in 7 Takten produzieren.
Die Auflösung der Phase steigt aber bereits um ein Bit auf 9 Bit.
Die Auflösung der Frequenz wird ebenfalls um den Carry auf 25 Bit 
erhöht.
Das Ganze läuft 23% schneller ab, obwohl die Auflösung deutlich zunimmt.

    ser r31         ; initial
    out PORTD,r31

    RM2:
    add  r28,r24     ; 1
    adc  r29,r25     ; 1
    adc  r30,r26     ; 1
    brcc out1        ; 2
    out  PIND,r31    ;   toggle Bit 0..7
    out1:
    rjmp RM2;        ; 2 7 cycles

von Werner (Gast)


Lesenswert?

In 9 Takten kann man ein Rechtecksignal gleicher Auflösung (Qualität
wie Jesper ) erzeugen, nur es gibt ein geschenktes Tastverhätnis 
zwischen 0 und 255 dazu.

; Duty cycle 0 to 255
.equ DUTY = r13

    ser  r31
    clr  r27

    RM11:            ; on   off
    add  r28,r24     ; 1    1
    adc  r29,r25     ; 1    1
    adc  r30,r26     ; 1    1
    cp   r30,DUTY    ; 1    1
    brsh off         ; 2    1
    nop              ;      1
    out  PORTD,r31   ;      1
    rjmp RM11        ;      2
    off:
    out  PORTD,r27   ; 1
    rjmp RM11        ; 2      9 cycles

von spess53 (Gast)


Lesenswert?

Hi

>In 9 Takten kann man ein Rechtecksignal gleicher Auflösung (Qualität
>wie Jesper ) erzeugen, nur es gibt ein geschenktes Tastverhätnis
>zwischen 0 und 255 dazu.

Wenn ich ein Rechteck haben will nehme ich einen Timer und nicht so ein 
Gedödel.

MfG Spess

von Werner (Gast)


Lesenswert?

Yoh, Gedödel klingt hart.
Schon, mit dem Timer geht das gut,
nur eben nicht für fast beliebige Frequenzen. ( Auflösung )

Es soll auch kein Glaubenskrieg werden ...

von rulix (Gast)


Lesenswert?

Werner schrieb:
> Hier mein Stand der Dinge.
> Interrupts taugen nicht.
> Hochsprachen taugen nicht.
> Für diesen Zweck zählt jede Nanosekunde.

So ist es!

http://www.elektronik-labor.de/AVR/DDSGenerator.htm

von Werner (Gast)


Lesenswert?

Da hatte doch jemand die gleiche Idee....

Der UrJesper verschenkt Zeit, um so langsamer um so größer wirde die 
Schrittweite.
Desto größer die Schritte um so mehr verfehlt man das Ziel.
Wirklich gut fand ich ihn erst nachdem die Auflösung erhöht wurde.

So wie im 88DDS,
- lange Tabellen eff. 1024 Schritte pro 360°
- 9 Bit D/A Ausgabe
- 26 Bit Addierregister
- bei höherer Abtastrate (9 bzw 10 Takte bei 22MHz clock)

von Falk B. (falk)


Lesenswert?

@  Werner (Gast)

>Schon die bescheidene Qualität des UrJesper kann man einfach steigern.

Bleib mal auf dem Teppich. Der Ansatz von Jesper war und ist gut, auch 
unter dem Gesichtspunkt der Resourcennutzung, die DDS läuft auf einem 
ATtiny!. Klar kann man noch einiges Verbessern und 7 gegen 9 Takte sind 
nochmal 23% weniger Zeit, aber das Grundprinzip, nämliche eine 
ultrakompakte Hauptscheife in ASM ändert man kein bisschen. Für eine 
reine Softwarelösung schon sehr gut. Wenn man höhere Takte braucht nimmt 
man ehe Hardware.

MfG
Falk

von Fantamann (Gast)


Lesenswert?

Nochmal zu meinem Ursprünglichen Problem.
Möchte ich zeitgewinnen und lege alles in Tabellen ab,
dann ist der ram relativ schnell vol :-(

Find ich doof.

von Jobst M. (jobstens-de)


Lesenswert?

spess53 schrieb:
> Wenn ich ein Rechteck haben will nehme ich einen Timer und nicht so ein
> Gedödel.

Sehe ich genau so. Wenn es Quarzgenau sein muß, auch mit PLL.


Gruß

Jobst

von Fantamann (Gast)


Lesenswert?

ups verzeigung, habe zu früh auf Senden gedrückt:
Wo soll ich die Tabellen ablegen und wie?

von Karl (Gast)


Lesenswert?

In der letzten Elektor gab es da einen Artikel, der sich damit 
beschäftigt. Vielleicht als Anregung:

http://www.elektor.de/jahrgang/2012/marz/sdr-mit-avr-%281%29.2084469.lynkx

Die schreiben, dass sie ein brauchbares Signal um die max. 200 kHz 
erhalten (kombiniert C/Assembler).

von Fantamann (Gast)


Lesenswert?

Vergesst mein vorigen Post, habs hinbekommen.

meine ISR sieht jetzt folgendermaßen aus:
1
ISR(TIMER0_COMP_vect) 
2
{
3
phase = (counter >> 24);
4
counter = counter + stepsize;
5
6
if(output == ON)
7
{
8
  putDAC(p_table[phase]);
9
}

Was jetzt aber am DAC ausgegeben wird ist... mist :D
Findet jemand den Fehler?

von Fantamann (Gast)


Lesenswert?

1
putDAC(*p_table+phase);

so ist's besser. Danke für's Zuhören :)

von Heinz (Gast)


Lesenswert?

Karl schrieb:
> In der letzten Elektor gab es da einen Artikel, der sich damit
> beschäftigt. Vielleicht als Anregung:
>
> http://www.elektor.de/jahrgang/2012/marz/sdr-mit-a...
>
> Die schreiben, dass sie ein brauchbares Signal um die max. 200 kHz
> erhalten (kombiniert C/Assembler).

Das hat Werner der Länge nach doch alles er- & geklärt.

P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der 
Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.

von spess53 (Gast)


Lesenswert?

Hi

>P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der
>Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.

Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den 
deutschen Wetterdienst.

MfG Spess

von Heinz (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der
>>Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.
>
> Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den
> deutschen Wetterdienst.
>
> MfG Spess

Mag sein, Spess, aber die Elektor habe ich nach dem Titelbild gekauft. 
Auf dem stand SDR. Nur drinn war ziemlich wenig SDR.

von Fantamann (Gast)


Lesenswert?

Hört mir eigentlich noch jemand zu? :-)
Mein Programm hat folgende Struktur

MAIN:
1
uint8_t *p_table;
2
3
if(output==ON)
4
{
5
    if(mode == SINE)
6
      p_table = wave_sine;
7
    else if(mode == SAW)
8
      p_table = wave_saw;
9
    //...
10
}
11
else
12
{
13
    table_p = wave_off;
14
}


ISR:
1
phase = (counter >> 24);
2
counter = counter + stepsize;
3
4
putDAC((*p_table+phase));


Das funktioniert leider nicht. Am DAC kommt immer das gleiche raus, d.h. 
das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich 
falsch mache?

Danke und Grüße,

Fantamann

von Werner (Gast)


Lesenswert?

Du benutzt C, eine Hochsprache und steckst den wichtigsten, 
zeitkritischen Teil in ein Interrupt Routine.
Du willst gehört werden, liest aber nicht.

Wenn Du die kürzest mögliche Schleife in C ( kenne mich da nicht aus )
zum Addieren, Tabelle lesen und Ausgabe in Main packst
und das von Zeit zu Zeit mit Frequenz- oder Modusänderunger 
unterbrichst...
kommt evtl. etwas raus, sicher nicht viel Gute

von Helmut L. (helmi1)


Lesenswert?

Fantamann schrieb:
> Am DAC kommt immer das gleiche raus, d.h.
> das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich
> falsch mache?

Wo liegt denn wave_sine und wave_saw?
Liegen die im RAM oder im Flash?
Wenn im Flash muss du die Daten anders holen mit pgm_read_byte.

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)

>Möchte ich zeitgewinnen und lege alles in Tabellen ab,
>dann ist der ram relativ schnell vol :-(

>Find ich doof.

Dein ATmega16 hat 1kB RAM, da werden doch wohl läppische 256Byte für die 
Tabelle übrig sein. Wenn dir das immer noch zuviel ist, pack die Tabllen 
in den Flash, ist nicht nennenswert langsamer. Hab ich alles aber schon 
dreimal erzähl. Jaja, diese Jugend . . . ;-)

Beitrag "Re: DDS Sinus erzeugung"

Falsh ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF 
gerade mal läppische 768 Bytes.

>Mein Programm hat folgende Struktur

Warum so halbgar? Hast du Angst vor zu viel Leistung? Lies mein Posting 
noch mal und mach es richtig.

>Das funktioniert leider nicht. Am DAC kommt immer das gleiche raus, d.h.
>das "umbiegen" der Zeiger in MAIN macht Probleme. Sieht jemand was ich
>falsch mache?

ja, du postet keinen vollständigen Code im Anhang. Siehe Netiquette.

MfG
Falk

von Werner (Gast)


Lesenswert?

Falk Brunner schrieb:
> Flash ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF
> gerade mal läppische 768 Bytes.

Eigentlich braucht man für hohe Ausführungsgeschwindigkeiten nur 
Tabellen für Sinus und Dreieck, wegen der Wendepunkte bzw. nicht 
monotonen Steigung.
Das kann man realistisch in Echtzeit nicht schneller leisten.
Dann sollten sie im Sinne der Auflösung so lang wie möglich sein.
In einer 256er Sinus Tabelle stecken nicht einmal 7 Bit 
Amplitudenauflösung.
Viele Werte kommen garnicht vor.

Eine Tabelle für OFF ??

von Fantamann (Gast)


Lesenswert?

> Wenn Du die kürzest mögliche Schleife in C ( kenne mich da nicht aus )
> zum Addieren, Tabelle lesen und Ausgabe in Main packst
> und das von Zeit zu Zeit mit Frequenz- oder Modusänderunger
> unterbrichst...
> kommt evtl. etwas raus, sicher nicht viel Gute

Ich mache es aus diesem Grund genau andersherum ;-)


Helmut Lenzen schrieb:
> Wo liegt denn wave_sine und wave_saw?
> Liegen die im RAM oder im Flash?
> Wenn im Flash muss du die Daten anders holen mit pgm_read_byte.

habe sie am Programmbeginn mit uint8_t wave_sin[256]={...} deklariert. 
Also müsste es im Flash liegen, oder?

Werner schrieb:
> Falk Brunner schrieb:
>> Flash ist gewöhnlich mehr als genug vorhanden, für SIN, SAW und OFF
>> gerade mal läppische 768 Bytes.
>
> Eigentlich braucht man für hohe Ausführungsgeschwindigkeiten nur
> Tabellen für Sinus und Dreieck, wegen der Wendepunkte bzw. nicht
> monotonen Steigung.

Das hatte ich in diesem Thread auch gesagt, wurde aber verneint. 
Deswegen hab ich jetzt alles in Tabellen abgelegt.


An alle: Ich möchte bei meiner Lösung bleiben und bin auch mit dem 
Resultat zufrieden. Ich möchte lediglich mit Zeigern auf die Waves 
zugreifen um schneller zu werden, aber da hab ich irgendwo einen 
Syntaxfehler vermute ich.

Sieht diesen jemand?

von Heinz (Gast)


Lesenswert?

> Sieht diesen jemand?

Ja - du bist boniert?

von Fantamann (Gast)


Lesenswert?

Verstehe ich und gebe ich auch zu.

von Fantamann (Gast)


Lesenswert?

Korrektur meines Posts oben, hab ich vertippt: Die Tabellen liegen im 
Ram.

Gruß fanta

von Werner (Gast)


Lesenswert?

Fantamann schrieb:
> Ich möchte lediglich mit Zeigern auf die Waves
> zugreifen um schneller zu werden, aber da hab ich irgendwo einen
> Syntaxfehler vermute ich.

Du hast nicht gesagt, dass Du weitaus häufiger den Modus oder die 
Frequenz
wechseln willst / wirst,
als die Kurve aktuallisiert werden soll.

von Fantamann (Gast)


Lesenswert?

Werner schrieb:
> Du hast nicht gesagt, dass Du weitaus häufiger den Modus oder die
> Frequenz
> wechseln willst / wirst,
> als die Kurve aktuallisiert werden soll.

Ok, jetzt verstehe ich was du meinst. Ich hatte zu Beginn das Problem, 
dass ich in der Main unterschiedliche Laufzeiten des Programms hatte, 
wegen den ganzen ifelse abfragen. Ich sollte es besser andersrum machen?

von Fantamann (Gast)


Lesenswert?

Nachtrag: Wobei das im Design von Falk Brunner weiter oben ja genauso 
gemacht wurde wie ich das jetzt habe.

von Werner (Gast)


Lesenswert?

ich Werner, nicht Falk

von Fantamann (Gast)


Lesenswert?

Werner schrieb:
> ich Werner, nicht Falk

OKay, hab es umgebaut. So scheints mir jetzt auch klüger zu sein.

Ich habe jetzt noch ein bissl weiterprobiert. Sobald
ich mehr als 3 Signale als Tabelle einfüge gehts nicht mehr.

const uint8_t wave_sine[256]={...}
const uint8_t wave_saw[256]={...}
const uint8_t wave_revsaw[256]={...}
const uint8_t wave_triangle[256]={...}
const uint8_t wave_square[256]={...}

d.h. wenn ich triangle und square auskommentiere (oder auch zwei 
beliebige andere) dann gehts :-/

Also irgendwo scheints mit der Datenmenge probleme zu geben.
Gibt es noch irgendwen der eine IDee hat?

von Werner (Gast)


Lesenswert?

sorry Werner NIX C

von Helmut L. (helmi1)


Lesenswert?

Fantamann schrieb:
> Also irgendwo scheints mit der Datenmenge probleme zu geben.
> Gibt es noch irgendwen der eine IDee hat?

Wie voll ist dein Flash denn?

const liegt im Flash

von Werner (Gast)


Lesenswert?

Obwohl, wenn das im SRAM ist, 3 mal 256 Byte und dann ein mords Stack 
vom C

Das soll ein MEGA16 sein ?
1K RAM

Dann ein mords Stack für das C Gedönste ?
Wie soll das gehen?

Wie gesagt durch brauchst maximal zwei Tabellen und von denen immer nur 
eine zu einer Zeit ....

von hans (Gast)


Lesenswert?

Du brauchst in deinem RAM nur eine Tabelle und zwar
die für die Ausgabe ausgewählte.

Bei der Auswahl wird diese neu gefüllt. Bei Rechteck,
Dreieck etc.  (also leicht und schnell zu rechnen)
über eine Berechnung, bei Sinus eher über eine Tabelle
im Flash und kopieren.

hans

von Fantamann (Gast)


Lesenswert?

Werner schrieb:
> Obwohl, wenn das im SRAM ist, 3 mal 256 Byte und dann ein mords Stack
> vom C
>
> Das soll ein MEGA16 sein ?
> 1K RAM

Das klingt plausibel. Was spricht dagegen die Tabellen einfach im
Flash abzulegen?

Kann mir bitte jemand kurz erklären wie das geht? Ich habe es wie oben 
gesagt mit const angedacht, aber das scheint ja irgendwie nicht zu 
reichen.

Danke und Gruß,
Fantamann

von hans (Gast)


Lesenswert?


von Werner (Gast)


Lesenswert?

ich weiss nicht wie C den Unterschied RAM und FLASH behandelt.
Von Haus aus und damit durch C auch nicht veränderbar dauert es 1/3 
länger ein Byte aus dem Flash zu lesen.
In einem DDS ist Zeit knapp,,,

Du braucht kein Tabelle OFF, SAW, REC usw.
Eine Dreieck kann man in wenigen Zeilen Code errechenen, wenn denn 
Dreieck
gewäht wird.
Einen Sinus berechent man lieber vorher und legt ihn ihn FLASH ab.
Wenn denn dann Sinus gewählt wird kopiert man diese in das RAM.

Die Main Routine gibt immer den gleichen Speicherbereich aus dem RAM 
aus.
Nur es mus halt drin sthen, was angesagt ist.

von Werner (Gast)


Lesenswert?

schmeiss C für das Ding weg
und schau Dir den Assembler Code im 88DDS an.

von Werner (Gast)


Lesenswert?

Werner schrieb:
> Von Haus aus und damit durch C auch nicht veränderbar dauert es 1/3
> länger ein Byte aus dem Flash zu lesen.

Das war natürlich untertrieben.
Ein ld aus dem RAM dauert zwei Takte. Ein lpm aus dem FLASH drei.
lpm is also 50% langsamer als ld.
Gute Nacht.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> schmeiss C für das Ding weg
> und schau Dir den Assembler Code im 88DDS an.

Na Na Werner.

Es gibt auch den goldenen Mittelweg wie immer.

Zeitkritische Teile in Assembler, alles andere in C schreiben.

So mach ich das immer.

Und beim GCC kannst du Assemblerteile in dein C Programm miteinbinden.

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)

>Das klingt plausibel. Was spricht dagegen die Tabellen einfach im
>Flash abzulegen?

In deinem Fall gar nichts.

>Kann mir bitte jemand kurz erklären wie das geht? Ich habe es wie oben
>gesagt mit const angedacht, aber das scheint ja irgendwie nicht zu
>reichen.

Muss man beim AVR anders machen.
1
uint8_t wave_sine[256] PROGMEM ={...};
2
3
...
4
5
putDAC(pgm_read_byte(p_table+phase));

MFG
Falk

von Falk B. (falk)


Lesenswert?

@Werner (Gast)

>Ein ld aus dem RAM dauert zwei Takte. Ein lpm aus dem FLASH drei.
>lpm is also 50% langsamer als ld.

Theoretisch richtig, praktisch irrelevant. Der OP WILL bei seiner eher 
langsamen Interruptlösung bleiben. Da spiel ein Takt mehr oder weniger 
keine Rolle. Damit ist die lpm-Lösung prakitsch gleichwertige mit der 
RAM-Lösung.

MfG
Falk

von Fantamann (Gast)


Lesenswert?

Falk Brunner schrieb:
> Muss man beim AVR anders machen.
> uint8_t wave_sine[256] PROGMEM ={...};
>
> ...
>
> putDAC(pgm_read_byte(p_table+phase));
>
>
> MFG
> Falk

Dankeschön

von Fantamann (Gast)


Lesenswert?

Werner schrieb:
> Du braucht kein Tabelle OFF, SAW, REC usw.
> Eine Dreieck kann man in wenigen Zeilen Code errechenen, wenn denn
> Dreieck
> gewäht wird.
> Einen Sinus berechent man lieber vorher und legt ihn ihn FLASH ab.
> Wenn denn dann Sinus gewählt wird kopiert man diese in das RAM.

Dieser Ansatz führte jetzt vorerst zum Erfolg. Ich erreiche damit etwa 
200kHz, mit Filter würd ich sagen dass etwa 20kHz noch als Sinus zu 
bezeichnen sind.

Ich bin jetzt weg von der interrupt Lösung und lasse die Lookuptable mit 
maximaler Geschwindigkeit abtasten.

Danke für die vielen Beiträge. Grüße!

von Helmut L. (helmi1)


Lesenswert?

Fantamann schrieb:
> Falk Brunner schrieb:
>> Muss man beim AVR anders machen.
>> uint8_t wave_sine[256] PROGMEM ={...};
>>
>> ...
>>
>> putDAC(pgm_read_byte(p_table+phase));
>>
>>
>> MFG
>> Falk
>
> Dankeschön

Hatte ich dir auch schon gesagt.

Beitrag "Re: DDS Sinus erzeugung"

von Fantamann (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Hatte ich dir auch schon gesagt.
>
> Beitrag "Re: DDS Sinus erzeugung"

Hast recht, ich hab den ersten Beitrag dieser Art zitiert, den ich beim 
hochscrollen gefunden habe. Dir natürlich genauso: Dankeschön!

von Werner (Gast)


Lesenswert?

Fantamann schrieb:
> mit Filter würd ich sagen dass etwa 20kHz noch als Sinus zu
> bezeichnen sind.

Na dann.
Jetzt kennst Du auch den Unterschied C zu Assembler :0)

Die Bilder oben 
http://www.mikrocontroller.net/attachment/preview/136650.jpg
sind übrigens ohne jedes Filter, die Abtastrate ist so hoch, dass der 
Innenwiderstand des R2R und die Eingangskapazität des Scopes reichen.

Schönen Sonntag noch allerseits
Werner

von Fantamann (Gast)


Angehängte Dateien:

Lesenswert?

Hier möchte ich euch mal das Ergebnis zeigen.

Aufnahmen bei 20kHz ohne Filter gemacht.

Grüße

von Falk B. (falk)


Lesenswert?

@  Fantamann (Gast)

>      20120305_100545.jpg
>      2,6 MB, 0 Downloads
>      20120305_100730.jpg
>      2,3 MB, 0 Downloads

>Aufnahmen bei 20kHz ohne Filter gemacht.

Und ohne Hirn. Lies mal was über Bildformate!

von Fatamann (Gast)


Lesenswert?

ich hätts besser gelassen :-)

Ein Haufen selbstgefälliger Prinzipienreiter seid ihr. Sorry
wenn ich das jetzt mal sagen musste :-)

Warum gibts denn keine automatische Skalierung der Bilder? Das ist doch 
in jedem anderen Forum auch so. Hab mich jedenfalls drauf verlassen.

von Fatamann (Gast)


Lesenswert?

Würde den Post mit den Bildern bitte jemand löschen? Ich kann es nicht 
als Gast.

von Falk B. (falk)


Lesenswert?

@  Fatamann (Gast)

>Warum gibts denn keine automatische Skalierung der Bilder?

Weil das hier kein Kindergarten- und Klingeltonform ist sondern man von 
den Leuten erwartet und ihnen zutraut, ein wenig mitzudenken.

von Fantamann (Gast)


Lesenswert?

>>Warum gibts denn keine automatische Skalierung der Bilder?
>
> Weil das hier kein Kindergarten- und Klingeltonform ist sondern man von
> den Leuten erwartet und ihnen zutraut, ein wenig mitzudenken.

So kann man es auch nennen. Du fährst auch ohne Sicherheitsgurt, weil 
man von dir erwarten kann, dass du gefälligst nicht durch die 
Windschutzscheibe fliegst. Du bist ja schließlich erwachsen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fantamann schrieb:
> Du bist ja schließlich erwachsen.

Du nicht?

Woher soll den deine automatische Skalierung wissen, welches Bild in
welcher Auflösung vorliegen muss, damit man sinnvoll seinen Inhalt
darstellen kann?

Ich hab' sie jetzt verkleinert, das nächste Mal nimmst du bitte ein
Bildbearbeitungsprogramm deiner Wahl und machst sie so groß, wie es
für deinen Zweck sinnvoll ist.

von Fantamann (Gast)


Lesenswert?

> Ich hab' sie jetzt verkleinert, das nächste Mal nimmst du bitte ein
> Bildbearbeitungsprogramm deiner Wahl und machst sie so groß, wie es
> für deinen Zweck sinnvoll ist.

merci

von Werner (Gast)


Lesenswert?

Hallo,

ist im grünen Bereich, wie zu erwarten.

> ... , der FILTER am Ausgang löst das Problem.
> Den hast du aber noch nicht, darum siehst du unschöne Signale.
> Der Filter ist aber notwendig.

So kommen diese Aussagen zustande.

> Für eine reine Softwarelösung schon sehr gut.
> Wenn man höhere Takte braucht nimmt man eh Hardware.

Es wird nicht unterschieden, das ist halt Software DDS.

> .... kommt evtl. etwas raus, sicher nicht viel Gutes.

Wenn ich nun einen Sinus kaufen wollte, welchen würde ich nehmen ?
Zumal der Preis gleich ist.

Sinus ist nun Peanuts.
Es wurde dann auch von Recht- und Dreieck bzw. Sägezahn geschrieben.
Diese Kurvenformen sind ungleich schwieriger zu erzeugen.
Da hilft Dir das Filter nix mehr.
Also wenn Deine Abtastfrequenz so niedrig ist , so dicht an der 
Sollfrequenz sitzt.

Grüße Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

wo es dunkel ist.
Ich kann das leider nicht photographieren,
das sind eigentlich durchlaufende Muster.
So habe ich 'mal lange belichtet.

Das sind 444 kHz aus dem 88DDS.
Da könnte man filtern, es lohnt aber nicht. (evtl. für einen Sinus)
Jenseits 150 oder 200 kHz fehlt Auflösung für Phase und Amplitude.
Du kannst nicht gegen die 12 Bit Phase und 10 Bit D/A dieser AD9XYZs :0)

von Werner (Gast)


Lesenswert?

Heinz schrieb:
> spess53 schrieb:

>>>> In der letzten Elektor gab es da einen Artikel, der sich damit
>>>> beschäftigt. Vielleicht als Anregung:
>>>> http://www.elektor.de/jahrgang/2012/marz/sdr-mit-a...

>>>> Die schreiben, dass sie ein brauchbares Signal um die max. 200 kHz
>>>> erhalten (kombiniert C/Assembler).

>>> P. S. Die Elektor-Titelseite ist reiner Etikettenschwindel. Auf der
>>> Titelseite steht SDR und im Innenteil werden olle DDS aufgewärmt.
>> Ist auch nur Teil 1 eines Artikels. Geplant ist ein Empfänger für den
>> deutschen Wetterdienst.
>> MfG Spess

> Mag sein, Spess, aber die Elektor habe ich nach dem Titelbild gekauft.
> Auf dem stand SDR. Nur drinn war ziemlich wenig SDR.

Hallo,

den Artikel habe ich mir angesehen, wohl nur weil er so weit vom Thema 
schien,
Ich weiss nicht genau was das werden soll.
Wenn es ein Sinusgenerator wird, dann ist dort auch ein schönens 
Beispiel wie man den Jesper eine Nuance schlechter kopieren kann ...
Wozu dient der Interrupt, der die Samplerate versaut??
"Das Jittert enorm, aber im Mittel stimmt die Frequenz ... "
Betse Voraussetzungen für ein SDR ?
LOL

Grüße Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

man kann dem Jesper auch (A)FSK entlocken.
1
TableLoop_FSK:    
2
3
  ; 2.2 Mc sampling rate 
4
  ; 25 Bit resolution on frequency
5
  ; 360/512° resolution on phase
6
  ; 8 Bit resolution on voltage
7
  ; Data tables from $0100 to $03FF in SRAM
8
  ; adds MARK or SPACE depending on PB0 status
9
  ; 24 Bit shift max.
10
11
.def highSpace = r6
12
.def midSpace  = r5
13
.def lowSpace  = r4
14
.def highMark  = r3
15
.def midMark   = r2
16
.def lowMark   = r1
17
18
    clr  r27
19
    ldi  r31,3
20
    mov  lowSpace,r24
21
    mov  midSpace,r25
22
    mov  highSpace,r26
23
24
    sbi PORTC,3         ; READY
25
26
  TL_FSK:               ; cycl.
27
    ld   r0,z           ; 2  
28
    out  PORTD,r0       ; 1  update BIT 0..7
29
    sub  r28,r24        ; 1
30
    sbc  r29,r25        ; 1
31
    sbc  r30,r26        ; 1
32
    sbc  r31,r27        ; 1
33
    in   r0,PINB        ; 1  get PB0 ...
34
    bst  r0,0           ; 1  and remember in T flag
35
    ori  r31,0x02       ; 1  limit to 1.5 * table length
36
    ld   r0,z           ; 2
37
    out  PORTD,r0       ; 1  update BIT 0..7
38
    sub  r28,r24        ; 1
39
    sbc  r29,r25        ; 1
40
    sbc  r30,r26        ; 1
41
    sbc  r31,r27        ; 1   
42
    ld   r0,z           ; 2  
43
    sub  r28,r24        ; 1
44
    sbc  r29,r25        ; 1
45
    sbc  r30,r26        ; 1
46
    out  PORTD,r0       ; 1  update BIT 0..7
47
    sbc  r31,r27        ; 1
48
    ori  r31,0x02       ; 1  limit to 1.5 * table length
49
    ld   r0,z           ; 2
50
    sub  r28,r24        ; 1
51
    sbc  r29,r25        ; 1
52
    sbc  r30,r26        ; 1
53
    brts TL_Mark        ; 1
54
    sbc  r31,r27        ; 1
55
    out  PORTD,r0       ; 1  update BIT 0..7
56
    mov  r24,lowSpace   ; 1
57
    mov  r25,midSpace   ; 1
58
    mov  r26,highSpace  ; 1
59
    rjmp Waste_two      ; 2  make it 40, we divide by 10 :o(
60
   TL_Mark:
61
    out  PORTD,r0       ; 1  update BIT 0..7
62
    sbc  r31,r27        ; 1
63
    mov  r24,lowMark    ; 1
64
    mov  r25,midMark    ; 1
65
    mov  r26,highMark   ; 1
66
    ori  r31,0x02        ; 1  limit to 1.5 * table length (not needed here)
67
    Waste_two:
68
    rjmp TL_FSK         ; 2 => 40 / 4 = 10 cycles

wenn man sich auf 16 Bit maximalen Shift beschränkt auch in 9 Takten.

... und PSK sollte auch kein Hexenwerk sein.

MfG Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Nicht durch den Äther aber durch ein Kabel.
"The quick brown fox jumps .... "
( der Fachmann hört sofort es ist ASCII 7,E,2 50 BAUD und nicht BAUDOT )
QRG 147,2575 kHz (Space) & 147,3425 kHz (Mark) ~ 85 Hz shift.

:o)

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

geht auch:
1
TableLoop_PSK:    
2
3
  ; 2.44 Mc sampling rate 
4
  ; 25 Bit resolution on frequency
5
  ; 360/512° resolution on phase
6
  ; 8 Bit resolution on voltage
7
  ; Data tables from $0100 to $03FF in SRAM
8
  ; 180° phase shift depending on change on PB0
9
10
    ldi  r31,3
11
12
    ldi  r27,0x01    ; enable PinChangeFlag on PB0
13
    sts  PCMSK0,r27 
14
    out  PCIFR,r27   ; clear last toggle
15
16
    clr  r27
17
18
    sbi PORTC,3     ; READY
19
20
    TL_PSK:         ; cycl.
21
    ld   r0,z       ; 2  
22
    out  PORTD,r0   ; 1  update BIT 0..7
23
24
    sub  r28,r24    ; 1
25
    sbc  r29,r25    ; 1
26
    sbc  r30,r26    ; 1
27
    sbc  r31,r27    ; 1
28
    ori  r31,0x02   ; 1  limit to 1.5 * table length
29
    ld   r0,z       ; 2
30
    sub  r28,r24    ; 1
31
    out  PORTD,r0   ; 1  update BIT 0..7
32
    sbc  r29,r25    ; 1
33
    sbc  r30,r26    ; 1
34
35
;   additional for PSK
36
    in   r20,PCIFR  ; 1  get PB0 toggle
37
    out  PCIFR,r20  ; 1  clear flag
38
39
    sbc  r31,r27    ; 1   
40
    ld   r0,z       ; 2  
41
    sub  r28,r24    ; 1
42
    out  PORTD,r0   ; 1  update BIT 0..7
43
    sbc  r29,r25    ; 1
44
    sbc  r30,r26    ; 1
45
    sbc  r31,r27    ; 1
46
    ori  r31,0x02   ; 1  limit to 1.5 * table length
47
    ld   r0,z       ; 2
48
    sub  r28,r24    ; 1
49
    sbc  r29,r25    ; 1
50
    out  PORTD,r0   ; 1  update BIT 0..7
51
    sbc  r30,r26    ; 1
52
    sbc  r31,r27    ; 1
53
54
;   additional for PSK
55
;   180° is 255 increments away ( 1 x r31 )
56
    ori  r31,0x02   ; 1  limit to 1.5 * table length
57
    sub  r31,r20    ; 1  sub phase
58
59
    rjmp TL_PSK     ; 2 => 36 / 4 = 9 cycles

Ohne den PinChange der 48/88/168er etc. nur mühsam?
Lange kein BellModem mehr gehört :0)
Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

is' der Ulrich (aus DDS normal) denn noch da ?
Also nicht jetzt gleich ...

Gute Nacht
Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Schade, Ulrich brachte immer den Kick.
Einen Takt extra, ein Bit mehr.
Solange ich an dem DDS bastele...
Unterwegs habe ich den einen oder anderen Takt oder
das eine oder andere Bit verloren.
Der interne PulUp hatte immer auf "out PORTx" Probleme gemacht.
Wie ich erst jetzt lese kann man das im 48/88/168 abwählen ...
Wahlweise PB0..3 ~ entspricht Bit 8. OK, übersehen.

Nun denn, sei es drum.

Den zweiten Kondensator habe ich nie gebraucht.
So wie die Ports verteilt sind sehe ich ein Potential für
AM FM PM U/f einen VCO aus dem verbliebenen AD Eingang.

Wieder kein Hexenwerk ...

Ob ein 100 kHz FM Sender Sinn macht ?
Zumindest ein schöner U/f Konverter kann das werden

P.S. Das findet keiner interessant ?

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Ob ein 100 kHz FM Sender Sinn macht ?

Bei 100kHz sendet immer noch Loran C Navigationssignal.
Auch ist die Bandbreite eines FM-Senders wesentlich groesser als bei AM 
so das es keinen Sinn macht bei niederigen Frequenzen.

Bei deiner PSK Modulation schaltest du hart um, damit wird deine 
Signalbandbreite ziemlich gross. Besser ist das vor dem umschalten der 
Phase die Amplitude zu senken und danach wieder anzuheben.

von Werner (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Bei 100kHz sendet immer noch Loran C Navigationssignal.

Ich will natürlich nicht "on air" gehen.
Langwelle wäre besser als Frequenz gewählt gewesen.
Mein Grundstück ist auch kaum 50 Meter lang :0)

> Bei deiner PSK Modulation schaltest du hart um, damit wird deine
> Signalbandbreite ziemlich gross.

Ja, klar.
Senden dürfen die meisten nicht. Manche auf manchen Frequenzen.
Wenn das durch einen Sender mit ein paar RESONANTEN Stufen ginge,
wäre das sowieso weg.
Auf Langwelle hätte man in resonanten Senderstufen eher das Problem 
Sendeantenne und Senderstufen breitbandig genug zu bekommen ?
Drahtgebunden, wie bei den Telefonmodems stört das wohl nicht.

> Besser ist das vor dem umschalten der Phase die Amplitude
> zu senken und danach wieder anzuheben.

Macht man das so im realen Leben ?

Ich will ja nur probieren wieviele Funktionen man in so einen Jesper 
packen kann.
Also als ein EinChip ATmega AVR "custom build" IC.
FAXen machen, HELL schreiben ? usw.
Bzw. ein möglichst vielseitiger Funktionsgenerator.
Sorry; ich habe Fantamans Post unbewusst gekapert,
aber Sinus kommt immer wieder vor :0))

Ich glaube ein paar Dinge gemacht zu haben, die ich so noch nicht 
gesehen habe und jede Idee oder Verbesserung ist gerne gesehen.
Natürlich auch Links, falls es das schon gab / gibt und ich es einfach 
nicht kenne.

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
>> Besser ist das vor dem umschalten der Phase die Amplitude
>> zu senken und danach wieder anzuheben.
>
> Macht man das so im realen Leben ?

PSK31 Modems machen das so. Dann braucht man dahinter nichts mehr zu 
filtern.

http://www.moetronix.com/ae4jy/files/winpsktech10.pdf

von Werner (Gast)


Lesenswert?

Helmut ist HAM ?

>> Dann braucht man dahinter nichts mehr zu filtern.

> This means that the transmitter must not compress or limit the audio
> waveform otherwise the signal will again get much wider in bandwidth.
> This is perhaps the biggest problem with setting up a PSK31 station.
> It is very easy to overdrive and distort the PSK31 signal by applying
> the relatively high amplitude audio signal from the PC soundcard into
> the low level microphone input of a SSB transmitter.

Ok, kenne mich da nicht aus.
Ein SSB Sender sollte bereits einen Haufen Filter darstellen, wenn er 
nicht übersteuert wird ?
Das geht leicht in die - 80 bis 90dB > 3kHz.

Wenn man denn nur eine kleine Dose bauen wolte aus der auch (B)PSK 
kommt...

73 de DB7EW

von Helmut L. (helmi1)


Lesenswert?

Werner schrieb:
> Helmut ist HAM ?

Nö. Habe so was nur als interesse mal ausprobiert.
Habe auch den Decoder dazu. Das ganze läuft auf einer ARM uC mit 50 MHz.
Hatte heute Nachmittag mal ausprobiert wie stark man das Signal noch mit 
Rauschen überlagern kann. Auf dem Skope sah man das Signal im Rauschen 
nicht mehr aber der Decoder konnte es noch einwandfrei decodieren.
Platinchen ist ca 80x80 mm.

von Werner (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Auf dem Skope sah man das Signal im Rauschen nicht mehr aber
> der Decoder konnte es noch einwandfrei decodieren.

Ja, das ist so.

von Helmut L. (helmi1)


Lesenswert?

Hast du auch schon mal damit rumgespielt?

von Werner (Gast)


Lesenswert?

Empfang mit Sound Karten Software.
Ist nicht mein spezielles Interesse, aber das geht wohl ganz gut...
Es schreibt, wenn ich nichts Auffälliges höre.

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

man kann damit auch wobbeln.
( die dots im Bild stammen von meinem Speicherscope,
sieht life besser aus)
Die Rate der Frequenzänderung steckt in r20 ( SPEED )
Die Spanne mache ich durch Neustart in definierten Intervallen.
Die Hardwaretimer und ein Interrupt taugen auch.
Die Frequenzänderung / Zeit ist konstant und in 255 Schritten wählbar.

Grüße Werner

P.S. Wieder 9 Takte wie Jesper aber doppelte Auflösung in zwei 
Dimensionen & eine Funktion extra.
1
SweepLoop:    
2
3
  ; 2.44 Mc sampling rate 
4
  ; 25 Bit resolution on frequency
5
  ; 360/512° resolution on phase
6
  ; 8 Bit resolution on voltage
7
  ; Data tables from $0100 to $03FF in SRAM
8
  ; Sweep starts at selected frequency
9
  ; SPEED controls the rate of change
10
  ; To control the span, restart or stop it after a certain time...
11
12
    cbi  DDRB,1     ; Bit 8 is off
13
    cbi  PORTB,1
14
    cbi  DDRC,0     ; deglitch not needed
15
    cbi  PORTC,0
16
    cbi  DDRC,1     ; addon not wanted
17
    cbi  PORTC,1
18
19
    RestartSweep:
20
21
    clr  r23        ; r23 temporary accumulator for rate of change
22
    clr  r27        ; r27 empty, used to add carry only
23
24
    ; restore adder value
25
    mov r24,r4
26
    mov r25,r5
27
    mov r26,r6
28
    ; reset accumulatar
29
    clr  r28
30
    clr  r29
31
    ser  r30
32
    ldi  r31,3
33
34
    ser  MODE       ; make sweep restartable at any time ( fake OffMode )
35
36
    sbi PORTC,3     ; READY
37
    cbi PORTC,3     ; place a strobe for trigger
38
    sbi PORTC,3
39
40
    SL:             ; cycl.
41
    ld   r0,z       ; 2  
42
    out  PORTD,r0   ; 1  update BIT 0..7
43
    sub  r28,r24    ; 1
44
    sbc  r29,r25    ; 1
45
    sbc  r30,r26    ; 1
46
    sbc  r31,r27    ; 1
47
    ori  r31,0x02   ; 1  limit to 1.5 * table length
48
    ld   r0,z       ; 2
49
    sub  r28,r24    ; 1
50
    out  PORTD,r0   ; 1  update BIT 0..7
51
    sbc  r29,r25    ; 1
52
    sbc  r30,r26    ; 1
53
    sbc  r31,r27    ; 1   
54
    ld   r0,z       ; 2  
55
    
56
;   additional to increment frequency
57
    add  r23,SPEED  ; 1
58
    adc  r24,r27    ; 1
59
    adc  r25,r27    ; 1
60
61
    out  PORTD,r0   ; 1  update BIT 0..7
62
63
;   additional to increment frequency
64
    adc  r26,r27    ; 1
65
66
    sub  r28,r24    ; 1
67
    sbc  r29,r25    ; 1
68
    sbc  r30,r26    ; 1
69
    sbc  r31,r27    ; 1
70
    ori  r31,0x02   ; 1  limit to 1.5 * table length
71
    ld   r0,z       ; 2
72
    out  PORTD,r0   ; 1  update BIT 0..7
73
    sub  r28,r24    ; 1
74
    sbc  r29,r25    ; 1
75
    sbc  r30,r26    ; 1
76
    sbc  r31,r27    ; 1
77
    rjmp SL         ; 2 => 36 / 4 = 9 cycles

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

falls es jemand gebrauchen kann.
Die aktuelle Version meiner Baustelle.

Werner

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Träger 200000 Hz, f(mod)=440 Hz

von chris (Gast)


Lesenswert?

>PSK31 Modems machen das so. Dann braucht man dahinter nichts mehr zu
>filtern.

Beitrag "PSK 31 Modlulation im Mikrocontroller"

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Hi, kein Aprilscherz.

200 kHz, AM, Empfänger KENWOOD TS850

Werner
1
AMLoop:    
2
3
  ; 2 Mc sampling rate 
4
  ; 25 Bit resolution on frequency
5
  ; 360/512° resolution on phase
6
  ; 8 Bit resolution on voltage
7
  ; Data tables from $0100 to $03FF in SRAM
8
  ; ADC is combined with table value for Amplitude Modulation
9
10
    cbi  DDRB,1     ; Bit 8 is off
11
    cbi  PORTB,1
12
    cbi  DDRC,0     ; deglitch not needed
13
    cbi  PORTC,0
14
    cbi  DDRC,1     ; addon not wanted
15
    cbi  PORTC,1
16
17
    clr  r27
18
    ser  r30
19
    ldi  r31,3
20
    lds  r20,ADCH   ; get initial ADC value
21
22
    sbi PORTC,3     ; READY
23
24
    AML:            ; cycl.
25
    ld   r0,z       ; 2  
26
    mul  r0,r20     ; 2  additional for am
27
    sub  r28,r24    ; 1
28
    out  PORTD,r1   ; 1  update BIT 0..7
29
30
    sbc  r29,r25    ; 1
31
    sbc  r30,r26    ; 1
32
    sbc  r31,r27    ; 1
33
    ori  r31,0x02   ; 1  limit to 1.5 * table length
34
    lds  r20,ADCH   ; 2  get new ADC value
35
    ld   r0,z       ; 2
36
    mul  r0,r20     ; 2  additional for am
37
    out  PORTD,r1   ; 1  update BIT 0..7
38
39
    sub  r28,r24    ; 1
40
    sbc  r29,r25    ; 1
41
    sbc  r30,r26    ; 1
42
    sbc  r31,r27    ; 1   
43
    ld   r0,z       ; 2  
44
    mul  r0,r20     ; 2  additional for am
45
    nop             ; 1  additional for am :O( what a waste
46
    sub  r28,r24    ; 1
47
    out  PORTD,r1   ; 1  update BIT 0..7
48
49
    sbc  r29,r25    ; 1
50
    sbc  r30,r26    ; 1
51
    sbc  r31,r27    ; 1
52
    ori  r31,0x02   ; 1  limit to 1.5 * table length
53
    ld   r0,z       ; 2
54
    mul  r0,r20     ; 2  additional for am
55
    nop             ; 1  additional for am :O(
56
    sub  r28,r24    ; 1
57
    out  PORTD,r1   ; 1  update BIT 0..7
58
59
    sbc  r29,r25    ; 1
60
    sbc  r30,r26    ; 1
61
    sbc  r31,r27    ; 1
62
    rjmp AML        ; 2 => 44 / 4 = 11 cycles

von Werner (Gast)


Angehängte Dateien:

Lesenswert?

Ein "Cut and Paste" aus dem alten ZIP auch behoben.
Grüße Werner

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.