Xmega_Sinus_erzeugen

Gast #2361095
Lesenswert?

Hallo Leute,

Kann mir jemand dabei helfen zu verstehen wie in diesem Quellcode der 
Sinus generiert wird? Als Vorlage hatte ich diesen Quellcode verwendet.

http://www.instructables.com/id/Atmel-Xmega-USBSerial-Arbitrary-Waveform-Generato/?ALLSTEPS



Jedoch benötige ich nur einen Sinus, deswegen habe ich alles entfernt 
was ich nicht brauche. Ich hätte gernen einen 20 khz Sinus,aber ich 
weiss leider nicht an welches Parametern ich drehen muss(z.b. was macht 
die variable len etc.).

Vielleicht könnte Ihr mir weiterhelfen.

Ich hoffe ich hänge den Quellcode richtig an:
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
#define VERSION "0.0.1"
8

9

10
void SetWaveFreq(unsigned long int freq);
11
void SetWaveCount(char count);
12
void LoadSineWave(int len);
13

14
void Config32MHzClock(void);
15

16

17

18

19
void DoSineWave(unsigned int freq);
20

21

22

23
volatile int data12[100]; 
24
volatile int gWaveNumSamp=50;
25
volatile int gWaveCount=0;
26

27

28
int main(void)
29
{
30
  int Reading, index;
31
  char data;
32
  char buffer[100];
33
  
34

35
  Config32MHzClock();
36

37
  CLK.PSCTRL = 0x00; // no division on peripheral clock
38

39
  PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PE7_gc;
40
  PORTE.DIR = (1<<7); // clkout
41
  TCC0.CTRLA = 4;
42

43
// setup DAC output on PORTB:1 as GND reference
44
  PORTB.DIR |= 0x02;
45
  PORTB.OUT &= 0xFD;
46

47

48

49

50
  LoadSineWave(gWaveNumSamp);
51

52

53
  
54
  while(1)
55
  {
56

57
};
58

59
}
60

61

62
void DoDAC(unsigned int ch, unsigned int value, unsigned int ref)
63
{
64
  if(ref<4)
65
    DACB.CTRLC = (ref << 3);           // select reference 
66
  else return; // early return for bad parameter
67

68
  DACB.CTRLB = DAC_CHSEL_DUAL_gc;      // select dual output DAC
69
  if(ch==0)
70
  {
71
    DACB.CTRLA = (1<<2) | (1<<0);    // enable DACB, CH0
72
    DACB.CH0DATA = value;
73
  }
74
  if(ch==1)
75
  {
76
      DACB.CTRLA |= (1<<3) | (1<<0);   // enable DACB, CH1
77
      DACB.CH1DATA = value;
78
  };
79

80
};
81

82
void DoSineWave(unsigned int freq)
83
{
84
  gWaveNumSamp=50;
85

86
  LoadSineWave(gWaveNumSamp);
87
  
88
  SetWaveFreq(freq);
89
};
90

91

92

93

94
void DoNCycles(char num)
95
{
96
  SetWaveCount(num);
97
};
98

99
void DoOutputOff()
100
{
101
  DMA.CTRL = 0x00; // stop dma
102
  DoDAC(0,0,1);    // drive DAC to 0
103
};
104

105

106

107
void LoadSineWave(int len)
108
{
109
int i;
110

111
  for(i=0;i<len;i++)
112
  {
113
    data12[i]=((sin((2.0/(float)len)*(float)i*M_PI)*0.5 + 0.5)*4095);
114
  };
115

116
};
117

118

119

120

121

122
void SetWaveFreq(unsigned long int freq)
123
{
124
  if(freq > 10000)
125
  {
126
    TCD0.CTRLA = 0x1;
127
    TCD0.PER = (int) ((F_CPU/freq/gWaveNumSamp));
128
  }
129
  else
130
  {
131
    TCD0.CTRLA = 0x2;
132
    TCD0.PER = (int) ((F_CPU/freq/gWaveNumSamp)/2.0);
133

134
  };
135
};
136

137
void SetWaveCount(char count)
138
{
139
  gWaveCount = count; // if count = 0 then repeat count is infinite
140
};
141

142

143

144

145
void Config32MHzClock(void)
146
{
147
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
148
  // initialize clock source to be 32MHz internal oscillator (no PLL)
149
  OSC.CTRL = OSC_RC32MEN_bm; // enable internal 32MHz oscillator
150
  while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for oscillator ready
151
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
152
  CLK.CTRL = 0x01; //select sysclock 32MHz osc
153

154
};
Gast #2361186
Lesenswert?

Also ich hab mich da jetzt nicht reingedacht, aber eigentlich ist es 
gang einfach:
Eine Sinustabelle über den DAC ausgeben, natürlich in einem festen 
Zeitraster. So z.B.:
1
ISR (TIMER_1MS)
2
{
3
  Wert++;
4
  if (Wert > Stützstellen)
5
  {
6
     Wert = 0;
7
  }
8
  "DAC = Sinus(Wert)";
9
}

Ist eigentlich ganz einfach, nur den DAC zu initialisieren ist etwa 
komisch, da der DAC-Wert Left-Adjusted ist standartmäßig, glaub ich...



Knut

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