Hallo,
ich möchte mit einen ATMega644 ( mit Bascom Basic) einen Sinusgenerator
programmieren, den ich im Bereich von 1 KHz - 20 KHz in 10 Hz schritten
stellen kann.
Hier mein Programm ohne Sinustabelle :
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare_a_pwm = Clear_up
Config Timer0 = Timer , Prescale = 1
On Ovf0 Sinusgenerator
Enable Int0
enable INTERRUPTS
Dim Sinus(128) As Word
Dim E As Byte
Dim Pwm As Word
Dim K As Byte
Do
Timer0 = K
If Pina.0 = 0 Then
K = K + 1
Waitms 50
End If
If K = 255 Then K = 1
Pwm1a = Sinus(e)
Loop
Sinusgenerator:
E = E + 1
Return
End
Am PWM1a Ausgang habe ich noch einen Filter(RC-Glied) mit 1K.Ohm und
1nF.
Das Problem was ich habe ich komme nicht über eine Frequenz von ca
900Hz.
Und 2. befürchte ich dass, das mit den 10Hz schritten so nicht hinhaut.
tobi schrieb:> Das Problem was ich habe ich komme nicht über eine Frequenz von ca.> 900Hz.
Die Sinus(e) ist wahrscheinlich zu langsam, bein ATMega kannst nicht
genau sagen, aber auf einem PIC18 @64MHz dauert eine Sinusberechnung ca.
1ms. Nimm besser eine Lookup Table
Scheinbar arbeitet er ja mit Lookup-Tabelle, die vorher berechnet wird.
Jetzt fehlt nur noch die Interrupt-Routine und die Timereinstellung für
1,00 - 20,00 kHz in 0,01 kHz-Schritten (x 128 natürlich) .
Wie man einen Kontroller zum DDS-IC macht, ist vor einiger Zeit
gründlich hier im Forum durch diskutiert worden. Bemüh mal die
Suchfunktion Sinusgenerator DDS
Da mit C, Bascom oder einer andren "Hochsprache" dranzugehen hat keinen
Sinn.
Erst ein Assemblerprogramm (asm-inlay) oder ein sehr gut optimierender
Kompiler bringt ausreichend schnellen Code.
Mit dem einfachen hochzählen der Sinustabelle kommt man nicht gut auf
höhere Frequenzen. Für die Höheren Frequenzen muss man in der Regel
schon einige der Werte der Sinustabelle auslassen. Der Verfahren dazu
nennt sich DDS. Damit gibt es reichlich Beispiele für den AVR -
allerdings fast alle in ASM. Für die noch nicht so hohen 20 kHz könnte
es ggf. noch gerade so in BASIC gehen, auch wenn BASCOM gerade bei den
Interrupts ziehmlich langsam ist.
Bei der Umsetzung sollte man für die Sinus-Tabelle Byte Werte nutzen,
und für den PWM und Interrupt den selben Timer - so wird sichergestellt
das jeder Wert genau einmal ausgegeben wird.
Für ein 20 kHz Signal sollte die PWM Frequenz bei mindestens 60 kHz
liegen - wegen dem einfachen Filter sogar besser noch deutlich höher.
Mit 20 MHz Takt und 8 Bit PWM käme man auf 78 kHz - das ist schon sehr
knapp und gibt wohl eine eine deutlich reduzierte Amplitude bei 20 KHz.
Ob der AVR den Code in den 256 Zykeln in Basic schafft, kann ich nicht
sagen - ich fürchte das wird sehr knapp. ggf. müsste man auf ASM
ausweichen.
Lurchi schrieb:> Für ein 20 kHz Signal sollte die PWM Frequenz bei mindestens 60 kHz> liegen
Ein 20kHz Signal mit 60kHz PWM zu erzeugen, geht soetwas von schief. Da
ist eine deutlich schnellere, kurze ASM-Routine mit Analogausgabe
angesagt, wenn das irgendwie nach Sinus aussehen soll.
Guck dir mal den miniDDS Generator von Jesper an
http://www.myplace.nu/avr/minidds/index.htm
Falls ein anderer Controller auch denkbar ist: wie wäre es mit einem
ATtiny861 (bzw. 261 oder 461), bei diesem ist ein 64 MHz-PWM-Takt
möglich, der sich per OSCCAL wohl auch noch zuverlässig in den Bereich
von 75 MHz bringen lässt. Da der Takt aber aus dem internen
RC-Oszillator erzeugt wird, ist die Frequenzgenauigkeit eher schlecht.
ich habe mal einen DDS Generator für niedrige Frequenzen gebastelt.
Es ging darum 2 Kanäle Phasengleich zu generieren.
Zu diesem Zweck waren dann 2 Stück DAC 8 an Port-B angeschlossen.
Damit die Daten der beiden Kanäle zeitgleich an den DAC08 ankamen
hatte ich noch eine Latch-kaskade a la ls374 (oder so) angebracht.
Im Grundprinzip war es so, das im Eprom eine Sinustabelle lag, die bei
Anforderung ins S-Ram kopiert wurde.
Das Teil konnte dann über Terminal gesteuert werden.
Wenn du im Terminal ein ? sendest bekommst eine Liste der möglichen
Befehle.
Es ist lange her und ich weis nicht so genau was ich da fabriziert
hatte.
Allerdings weis ich noch, das in dem Inline-Assembler die Nutzung der
Indexregister des ATmega sehr wichtig war.
Vielleicht kannst du aus dem Quelltext (eigentlich "for my eyes only")
irgendwelche Erkenntnisse extrahieren.
Gruss Klaus de Lisson
Das Tolle an so einem Projekt ist, dass man sich nachher einfacher von
ein paar euros trennen kann fuer einen Chip, der das alles viel besser
bereits beinhaltet.
Siebzehn mal Fuenfzehn schrieb:> Das Tolle an so einem Projekt ist, dass man sich nachher einfacher von> ein paar euros trennen kann fuer einen Chip, der das alles viel besser> bereits beinhaltet.
Naserümpf.... was meinst du nun genau ?
k.
ps,
Was hat das mit Beinen zu tun ?
Du schreibst ja "bein" "haltet"
tobi schrieb:> Das Problem was ich habe ich komme nicht über eine Frequenz von ca> 900Hz.> Und 2. befürchte ich dass, das mit den 10Hz schritten so nicht hinhaut
Wenn 8 Bit Auflösung reichen, dann ist das nachbausicher. Ist schon
lange her, als ich dieses Projekt realisierte. Kann 0,1 Hz Auflösung
bis über max. 100 kHz
https://www.elektronik-labor.de/AVR/DDSGenerator.htm
>>Siebzehn mal Fuenfzehn schrieb:>> Das Tolle an so einem Projekt ist, dass man sich nachher einfacher von>> ein paar euros trennen kann fuer einen Chip, der das alles viel besser>> bereits beinhaltet.>>Naserümpf.... was meinst du nun genau ?
Allenfalls in einen Chip wie den AD9854 oder aehnlich investieren. Es
gibt welche die koennen Quadratur, wenn sie 2 Kanaele haben.