Suche Xmega Sinus Quellcode

OP #2364099
Lesenswert?

Das Problem ist, das ich bisher nur codes gefunden habe, die auf einem 
Wavegenerator basieren.
zb: 
http://www.instructables.com/id/Easy-Atmel-Xmega-Sine-Wave-Generator/?ALLSTEPS#step8

nur hierbei wird die Frequenz über ein Poti eingestellt.

Deswegen Suche ich einen Quellcode in dem über eine Variable die 
Frequenz eingestellt werden kann. Denn je nachdem was für Daten anliegen 
benötige ich eine andere Frequenz. genauer zwei frequenzen. 18 und 
22khz. Des Weiteren wäre es von Vorteil wenn sich Wiederholungen 
einstellen liessen.
#2364152
Lesenswert?

Da wird doch einfach 1 Byte an dem Port-D ausgegeben.
out PORTD, R0



Auszug aus der Interrupt Routine:

        lpm                               ; Funktionswert aus dem 
Speicher lesen
        add z1, change1                   ; Phasenakkumulator
        adc z2, change2
        adc z3, change3
        out PORTD, R0                     ; Wert an den 
Analog-Digital-Wandler ausgeben
        out SREG, sregsave                ; Statusregister 
wiederherstellen
        reti                              ; Interrupt verlassen, zurück 
zum Hauptprogramm
OP #2364208
Lesenswert?

Schonmal danke für deine Hilfe Helmut. Nur ich suche sowas wie in dem 
Link, den ich gepostet habe. Will nämlich auch deswegen einen Xmega 
verwenden um mir den DAC und den Filter zusparen.
Bin auch gerne bereit das Problem irgendwie gemeisam zu lösen(Nachhilfe 
, Dienstleistung etc). Weil alleine werde ich es wahrscheinlich nicht 
hinbekommen.
#2364235
Lesenswert?

Den 8bit D/A-Wandler kannst du mit jedem Controller durch Timer mit PWM 
ersetzen. Einfach auf die Timer-Periode den Interrupt setzen und dann in 
jedem Interrupt einen neuen PWM-Wert laden. Um das Filter am Ausgang 
kommst du aber nicht herum. Im einfachsten Fall ist das ein Widerstand 
und ein Kondensator, wenn deine PWM-Frequenz über 30kHz liegt. Die 
Hauptfilterung erledigt dann dein Lautsprecher und dein Gehör.
#2364280
Lesenswert?

Ich habe keinen XMEGA.


Dein Programmablauf sieht ungefähr so aus.

Haupt-Programm:

Sinustabelle anlegen 1kByte
Variable mit 32 bit für Phase und Frequenz initialisieren.
Timer-Interrupt initialisieren.
Fertig: Endlosschleife, Goto Fertig


PWM-Timer-interrupt:

Obere 10bit von Phase als Zeiger auf das 1KByte RAM nehmen.
Damit 8bit Sinus-Wert aus Tabelle holen.
Wert ins PWM-Register laden.

Phase = Phase+Frequenz

Tasten abfragen

Ende Interrupt
OP #2364307
Lesenswert?

Das habe ich auch schon in einem Beispiel gesehen.
1
#include <stdio.h>
2
#include <avr\io.h>
3
#define F_CPU 32000000UL
4
#include <util\delay.h>
5
#include <math.h>
6

7
void GenerateArbWave12(int *data, int len, unsigned long int freq);
8
void SetWaveFreq(unsigned long int freq);
9
void LoadSineWave(int len);
10
void Config32MHzClock(void);
11

12
volatile int data12[100];
13
volatile int gWaveNumSamp=50;
14

15
int main(void)
16
{
17
  int Reading;
18

19
  Config32MHzClock();
20

21
  CLK.PSCTRL = 0x00; // no division on peripheral clock
22

23
  PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PE7_gc;
24
  PORTE.DIR = (1<<7); // clkout
25
  TCC0.CTRLA = 4;
26

27
// setup DAC output on PORTB:1 as GND reference
28
  PORTB.DIR |= 0x02;
29
  PORTB.OUT &= 0xFD;
30

31
// setup ADC input on PORTA:0-3 (0=hi, 1=hi, 2=samp, 3=gnd)
32
// and power PORTA:1 to create voltage divider
33
  PORTA.DIR = 0xB;
34
  PORTA.OUT = 0x3;
35

36
// setup adc for single ended one shot mode
37
  ADCA.CTRLA |= 0x1;       // enable adc
38
  ADCA.CTRLB = 0x4;        // set 8 bit conversion
39
  ADCA.CH0.CTRL = 0x1;     // single ended
40
  ADCA.CH0.MUXCTRL = 0x10; // PORTA:2
41
  ADCA.REFCTRL = 0x20;     // reference is PORTA:0
42
  ADCA.PRESCALER = 0x5;    // peripheral clk/128
43

44
  LoadSineWave(gWaveNumSamp);
45

46
  // startup in 10kHz
47
  GenerateArbWave12(data12,gWaveNumSamp*2,10000);
48

49
  while(1)
50
  {
51
  // read adc to determine waveform freq
52
    ADCA.CTRLA |= 0x4;               // start conversion ch0
53
    while(!ADCA.CH0.INTFLAGS);       // wait for conversion complete flag
54
    ADCA.CH0.INTFLAGS = 0;           // clear int flags  
55
  Reading = ADCA.CH0RESL;          // read 8 bit value from POT
56
    SetWaveFreq((Reading*Reading)+1); // set freq
57
    _delay_ms(100); 
58
  };
59
  
60
};
61

62
void LoadSineWave(int len)
63
{
64
int i;
65

66
  for(i=0;i<len;i++)
67
  {
68
    data12[i]=((sin((2.0/(float)len)*(float)i*M_PI)*0.5 + 0.5)*4095);
69
  };
70

71
};
72

73
void SetWaveFreq(unsigned long int freq)
74
{
75
    TCD0.PER = F_CPU/freq/gWaveNumSamp/4;
76
};
77

78
void GenerateArbWave12(int *data, int len, unsigned long int freq)
79
{
80

81
EVSYS.CH1MUX = 0xD0;    // CH1 = TCD0 overflow
82
TCD0.CTRLA = 0x03;      // Prescaler: clk/4
83
TCD0.PER   = F_CPU/(len/2)/freq/4;        // 31=1MHz,63=500K,127=250K
84
DACB.CTRLA = 0x05;      // Enable DACB and CH0
85
DACB.CTRLB = 0x01;  // CH0 auto triggered by an event (CH1)
86
DACB.CTRLC = 0x08;  // Use AVCC (3.3V), left adjust
87
DACB.EVCTRL = 0x01; // Event CH1 triggers the DAC Conversion
88
DACB.TIMCTRL = 0x50;// Minimum 32 CLK between conversions
89
DMA.CTRL = 0x80;    // Enable, single buffer, round robin
90
DMA.CH0.ADDRCTRL = 0xD9;// Reload, Increment source
91
DMA.CH0.TRIGSRC= 0x25;  // DACB CH0 is trigger source
92
DMA.CH0.TRFCNT = len;   // Buffer is len bytes
93
DMA.CH0.SRCADDR0  =(((uint32_t)data)>>0*8) & 0xFF;
94
DMA.CH0.SRCADDR1  =(((uint32_t)data)>>1*8) & 0xFF;
95
DMA.CH0.SRCADDR2  =(((uint32_t)data)>>2*8) & 0xFF;
96
DMA.CH0.DESTADDR0 =(((uint32_t)(&DACB.CH0DATA))>>0*8)&0xFF;
97
DMA.CH0.DESTADDR1 =(((uint32_t)(&DACB.CH0DATA))>>1*8)&0xFF;
98
DMA.CH0.DESTADDR2 =(((uint32_t)(&DACB.CH0DATA))>>2*8)&0xFF;
99
DMA.CH0.CTRLA = 0xA5;   // Enable, repeat, 1 byte, single 
100
};
101

102

103

104
void Config32MHzClock(void)
105
{
106
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
107
  // initialize clock source to be 32MHz internal oscillator (no PLL)
108
  OSC.CTRL = OSC_RC32MEN_bm; // enable internal 32MHz oscillator
109
  while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for oscillator ready
110
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
111
  CLK.CTRL = 0x01; //select sysclock 32MHz osc
112
//  CCP = CCP_IOREG_gc;
113
//  CLK.PSCTRL = 0x02; // peripheral clk = sysclk/4, forces sys also /4??
114
};

Nur wird hier die Frequenzeinstellung über ein Poti erreicht. Dafür 
hätte ich gerne zwei Variablen in dem Quelltext. Ist es überhaupt 
möglich das ohne Poti zu realisieren?Dabei bräuchte ich dringend hilfe. 
Derjenige der mir helfen kann/will kann mir auch eine Email schreiben, 
um gegebenfalls üder die Bezahlung zu sprechen.
Gast #2364366
Lesenswert?

Daniel M. schrieb:
> Nur wird hier die Frequenzeinstellung über ein Poti erreicht. Dafür
> hätte ich gerne zwei Variablen in dem Quelltext. Ist es überhaupt
> möglich das ohne Poti zu realisieren?Dabei bräuchte ich dringend hilfe.
> Derjenige der mir helfen kann/will kann mir auch eine Email schreiben,
> um gegebenfalls üder die Bezahlung zu sprechen.

Mal ne doofe Frage: Wie hast Du das Problem eigentlich für einen 
normalen ATMega gelöst? Es gab hier genügend Verweise auf Sourcecode für 
den DAC, mit ohne ohne DMA, mit oder ohne externer Frequenzeinstellung.
Gast #2364367
Lesenswert?

Hallo Helmut,
wo nimmst du eigentlich deine Geduld her?
Der Kerl hat überhaupt kein Interesse irgendwas selbst zu programmieren 
und dabei zu lernen. Bei dem besteht "porgrammieren" nur aus Zeug im 
Internet zusammanzukopieren und irgendwie zum laufen zu bringen. Wenns 
nicht läuft findet man schon einen Dummen ders für einen richtet.
Das ist echt unerträglich.
#2364403
Lesenswert?

Daniel M. schrieb:


> Nur wird hier die Frequenzeinstellung über ein Poti erreicht. Dafür
> hätte ich gerne zwei Variablen in dem Quelltext. Ist es überhaupt
> möglich das ohne Poti zu realisieren?

Das ist jetzt aber nicht dein Ernst, oder?

Nach 10 Sekunden den Code überfliegen, fällt mir diese Funktion hier auf
1
void SetWaveFreq(unsigned long int freq)
2
{
3
    TCD0.PER = F_CPU/freq/gWaveNumSamp/4;
4
};
Was denkst du wohl was diese Funktion, dem Namen nach machen wird?


Hast du dir den Code JEMALS auch nur IRGENDWIE angesehen?
Normalerweise sollte man das ausdrucken und dir um die Ohren pfeffern 
bis nur noch Konfetti übrig sind.

> weil die Frequenz wird in folgender Methode übergeben.
> GenerateArbWave12(data12,gWaveNumSamp*2,10000) zb. für 10khz

Genau.
Drum wird das auch in der Hauptschleife nach dem Auslesen das ADC 
aufgerufen.
1
  while(1)
2
  {
3
  // read adc to determine waveform freq
4
    ADCA.CTRLA |= 0x4;               // start conversion ch0
5
    while(!ADCA.CH0.INTFLAGS);       // wait for conversion complete flag
6
    ADCA.CH0.INTFLAGS = 0;           // clear int flags  
7
  Reading = ADCA.CH0RESL;          // read 8 bit value from POT
8
    SetWaveFreq((Reading*Reading)+1); // set freq
9
    _delay_ms(100); 
10
  };

Wo war nochmal genau der Aufruf von GenerateArbWave12? Und warum 
erinnert mich GenerateArbWave12 so ungemein an "Generate Arbitrary 
Wave", also das Erzeugen einer Wavetable.
OP #2364442
Lesenswert?

Der Aufruf ist vor der Hauptschleife. Wenn ich den Code verstanden hätte 
und ändern könnte würde ich es ja machen und nicht hier nach Hilfe 
ringen.
Also müsste reading auf einen festen Wert setzen werden , weil damit die 
Frequenz gesetzt wird. Und danach wird erst die Werte Tabelle der 
jeweiligen frequenz angelegt oder?
#2364446
Lesenswert?

> Hallo Helmut,
> wo nimmst du eigentlich deine Geduld her?

Na ja, irgendwie muss man sein Wissen ja los werden. :-)
Das Wichtigste ist jetzt eigentlich gesagt werden. Der Rest ist 
Implementierung.
OK, das ganze Bedienungskonzept muss der Fragesteller natürlich auch 
noch definieren und implementieren.

Immerhin bietet er ein paar Euro wenn ihm jemand hilft. Ich kann ihm da 
allerdings nicht weiterhelfen, da ch keinen XMEGA habe.
#2364449
Lesenswert?

UR Schmitt schrieb:
> Hallo Helmut,
> wo nimmst du eigentlich deine Geduld her?
> Der Kerl hat überhaupt kein Interesse irgendwas selbst zu programmieren
> und dabei zu lernen. Bei dem besteht "porgrammieren" nur aus Zeug im
> Internet zusammanzukopieren und irgendwie zum laufen zu bringen. Wenns
> nicht läuft findet man schon einen Dummen ders für einen richtet.
> Das ist echt unerträglich.

Leider zu spät gelesen.
Offenbar ist dir Daniel M schon öfter aufgefallen.
Den Namen werd ich mir merken.
#2364454
Lesenswert?

Daniel M. schrieb:
> Der Aufruf ist vor der Hauptschleife. Wenn ich den Code verstanden hätte
> und ändern könnte würde ich es ja machen und nicht hier nach Hilfe
> ringen.

Wenn du nicht programmieren kannst und auch keine Anstalten zeigst es zu 
lernen, wozu dann der Aufwand. Kauf dir Manpower ein und gut ists.

Du bist genau von der Sorte, bei der man absolut die Lust verliert zu 
helfen und sich fragt, wozu man eigentlich Jahre investiert hat um 
dorthin zu kommen wo man ist.
OP #2364490
Lesenswert?

Ich denke schon,dass ich Anstalten mache es zu verstehen. Zu mindest im 
Rahmen meiner Möglichkeiten, die wohl eher begrenzt sind. Aber ich muss 
dieses Problem ja irgendwie lösen.

Ich bin ja auf der Suche nach Manpower,weil ich es selber nicht 
hinbekomme.
Dann habe ich den Tipp bekommen es mal hier zu versuchen und Ich sehe 
das sich einige mit der Materie auskennen.

Nur egal ob Nachhilfe Lehrer oder in diversen Informatiker Foren habe 
ich bisher noch keine Hilfe finden können. Deswegen sagte ich ja , wer 
mir Helfen kann , muss dies auch nicht Umsonst tuen. Wenn ich hier 
niemanden finde, wüsste ich nicht mehr wo ich suchen sollte.
#2364510
Lesenswert?

Daniel M. schrieb:
> Hallo liebes Forum,
> ich suche einen Quellcode für einen Xmega der einen Sinus erzeugt.
> Am besten wäre ein Quellcode , in dem die Frequenz eingestellt werden
> kann. Also nicht von aussen über ein Poti oder so.
>
> Hoffe das Ihr mir weiterhelfen könnt.

genügt das? Kann man sicher auf xmega portieren.
http://elektronik-labor.de/AVR/DDSGenerator.htm
#2364535
Lesenswert?

Daniel M. schrieb:
> Ich denke schon,dass ich Anstalten mache es zu verstehen.

Sorry. Aber da werd ich pampig.
Wenn im Code eh schon alles da ist und sogar die Funktionsnamen so sind, 
dass man das rein durch lesen schon fast im Klartext lesen kann, dann 
KANNST du dir das Programm nicht angesehen haben.
Du hast einfach nur den Code von irgendwo geklaut und HILFE gerufen.

Ich kann auch keinen XMEGA programmieren und 90% der ganze Zuweisungen 
zu den Registern sagen mir überhaupt nichts. Aber ich erkenne eine 
Funktion, wenn ich eine sehe und ich schau mir ihren Namen an und denk 
mir: Was will mir wohl der Autor mit diesem Funktionsnamen sagen.

Und genau das gleiche kann jeder machen, der auch nur die banalsten 
Grundlagen von C ein wenig studiert hat.

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