Pfad: Home => AVR-DE => Anwendungen => Sinusgenerator tn45   This page in english: Flag EN Logo
Sinusgenerator tn45 AVR-Anwendungen

PWM-Sinusgenerator mit ATtiny45


Funktionsschema des tn45-Sinusgenerators

PWM-Sinusgenerator ATtiny45

Ein Sinusgenerator ohne bauteil-aufwändiges R/2R-Netzwerk, mit einem schnellen PWM-Generator in einem ATtiny45. Mit feinfühliger linearer Frequenzeinstellung mittels 10-Gang-Poti. Oberwellenarm durch ein bis zu vierstufiges RC-Netzwerk.

Versuche das gerne mit einem ATtiny25: es geht nicht, weil die lange Tabelle nicht in das Flash passt. Versuche das gerne mit einem ATtiny85: es geht. Versuche das mit jedem anderen ATtiny oder ATmega: es geht nicht, weil die alle keinen sehr schnellen 64-MHz-PWM-Oszillator bieten. Es geht also NUR und ausschließlich mit Attiny45 und ATtiny85.

Das Funktionsschema offenbart es: es geht einzig und alleine NUR mit ATtiny45 oder 85, denn der schnelle PWM-Generator mit 64 MHz gibt es nur in denen. Und die umfangreiche Liste mit den TC0-Vorteilerwerten und den Compare-Werten sowie der Schrittweite hat 1.024 Einträge, ist also alleine schon 3 kB groß und passt daher auch nicht in einen ATtiny25.

Das Schaltbild und die Flussdiagramme gibt es als LibreOffice-Draw-Datei hier, die ausführlichen Berechnungen in der LibreOffice-Calc-Datei hier.

Top Funktionsweise Hardware Aufbau Software Algorithmen

1 Funktionsweise

Frequenzkurve des Sinusgenerators Die hier beschriebene Gerätschaft produziert Sinuswellen zwischen 20 Hz und 20 kHz mit einer sehr schnellen PWM. Der ATtiny45 wird dabei mit einem 20-MHz-Quarz getaktet, damit der Timer TC0 benügend schnell die PWM-Werte an den noch schnelleren PWM-Generator TC1 ausgeben kann.

Der sehr schnelle PWM-Generator im TC1 des ATtiny45 (8 Bit Auflösung mit 250 kHz) produziert ein Rechteck mit einstellbaren Pulsweiten. Die Pulsweite wird vom TC0 des ATtiny45 in regelmäßigen Abständen so verstellt, dass daraus ein Sinus-Signal resultiert.

An einem Ausgang steht ein Rechtecksignal zur Verfügung, an dem ein Frequenzzähler angeschlossen werden kann, um die tatsächlich erzeugte Frequenz selbst dann zu messen, wenn der Analogausgang zu geringe Spannungen hat und die Eingangsstufe des Frequenzzählers nicht mehr zuverlässig misst.

Die Frequenz der Gerätschaft steigt mit den am Eingang ADC1 angeschlossenen Potentiometer exponentiell an. Die Auflösung beträgt dabei 10 Bit oder 1024 Einzelstufen. Verwendet man am ADC1-Eingang ein 10-Gang-Poti, dann lässt sich die Frequenz feinfühlig einstellen.

Bei Frequenzen unter 2,6 kHz gibt TC0 jeden der 256 Einzelwerte der 8-Bit-Sinustabelle an den PWM-Generator aus. Die Frequenz des Sinus wird dabei durch den Vorteiler und den Compare-Wert von TC0 bestimmt. Möglich sind dabei Maximalwerte von 1.024 für den Prescaler und 255 für Compare-A, was zu einer Minimal-Frequenz von
fmin = 20.000.000 / 256 / 1.024 / (255 + 1) = 0,3 Hz

führt.

Frequenzen mit verschiedenen Aufloesungen Bei Frequenzen über 2,6 kHz werden bei jeder PWM-Ausgabe eine oder mehrere Stufen übersprungen. Dadurch nimmt die Auflösung der Sinuskurve ab. Maximal wird bei 20 kHz nur noch jeder achte Sinuswert ausgegeben, so dass 32 Werte der Sinuskurve tatsächlich zum Tragen kommen.

Das Diagramm zeigt die Frequenzen, ab denen die verschiedenen Abstufungen zum Einsatz kommen.

Konfigurierung der Frequenzen Wer weniger oder mehr an Frequenzen braucht, begibt sich in die LibreOffice-Calc-Datei, dort in das Tabellenblatt "tc0-timer", ändert ein paar Vorgaben und kopiert sich die gelb hinterlegten Zellen in den Quellcode. Man achte darauf, dass der Maximalwert in Zelle G6 nicht mehr als 255 beträgt (kann passieren, wenn man in Zelle B3 weniger als 0,4 Hz einträgt).

Die ersten beiden Zeilen legen den Generator schlafen, wenn das Poti am linken Anschlag ist.

Wer das Programm ausreizen will, kann durch Herabsetzung des Wertes in H6 eine noch schnellere Ausführung erreichen. Aber Obacht: die Interrupt- Service-Routine von TC0 dauert genau 22 Takte, so dass 23 die absolute Untergrenze ist. Da der gelegentlich ebenfalls anstehende ADC-Interrupt zwischen 23 und 27 Takte dauert und beim Schreiben neuer Frequenzwerte noch gelegentlicher für 18 Taktzyklen die Interrupts abgeschaltet werden, kann es bei Werten unter 29 Takten zu gelegentlichen Fehlzeiten bei der Ausgabe kommen (was dann nur durch die gutmütig dimensionierten RC-Filter ausgeglichen wird).

Zu einem anständigen Sinusgenerator auf PWM-Basis gehört auch noch ein ordentliches Oberwellenfilter, z. B. mit RC-Kombinationen. Auch die gibt es hier in großer Auswahl, siehe Hardware und Software.

1.1 Auswahl der Signalform

Auswählbare Sinussignale Wenn Du an den RC-Filter-Ausgang, der die PWM-Signale verschleift, einen Operationsverstärker anschließen willst, dann ist zu beachten, dass Operationsverstärker so ihre eigenen Grenzen haben, wo die Ausgangsspannung noch der Eingangsspannung folgen kann und wo nicht mehr.

Per Software kann die Signalform des Sinusgenerators entweder auf normal (0 bis 5V) oder an die Kennlinien eines nachfolgenden Operationsverstärkers vom Typ 741 oder eines CA3140 angepasst werden. Vor dem Assemblieren die Einstellkonstante "cSineMode" auf 0, 1 oder 2 einstellen, dann nimmt er auch die richtige Kurve. Bitte beachten, dass je nach Frequenz und Einstellung des RC-Filters die Amplitude noch etwas abnimmt. Dafür liegt die Mitte des Ausgangssignals immer in der Mitte des zulässigen Spannungsbereichs, so dass die Aussteuerung mit Verstärkung immer symmetrisch um diese Mitte herum erfolgt und eine Übersteuerung vermieden werden kann.

1.2 Auswahl des RC-Filters

Signal des tn45-Sinusgenerators bei ca. 5 kHz Das gepulste Signal wird in einem zwei- bis vierstufigen RC-Filter gefiltert. So sieht das Signal mit den vier 2n2/2k2-Filtern bei ca. 5 kHz schon aus. Mein Oszi sieht die 128 Zacken jedenfalls nicht, da ist er viel zu analog dafür.

Der Sinusgenerator liefert Frequenzen zwischen 20 und 20.000 Hz. Damit er diese drei Größenordnungen ordentlich verarbeiten kann, braucht er an die Frequenz angepasste RC-Filter.

Die folgenden Kurven sind mit der Normal-Einstellung erstellt, die Varianten für den Operationsverstärker 741 und CA3140 sind hier nicht betrachtet.

Sinusgenerator mit 440 Hz Hier sieht man den Sinusgenerator bei 440 Hz. Wie man sieht, wirkt bei dieser niedrigen Frequenz schon das erste RC-Filter mit R = 2k2 und C = 302nF ausreichend glättend (rote Kurve). Spätestens beim zweiten RC-Filter sind alle Oberwellenanteile verschwunden. Mehr ist da eigentlich gar nicht nötig.

Der etwas schräge Wert für die Kapazität kommt durch die Parallelschaltung mehrerer unterschiedlicher Kondensatoren zustande (hier: 10nF+10nF+15nF+47nF+220nF, aus der frühen Entwicklungszeit dieses Projekts).

Sinusgenerator mit 1kHz Erniedrigt man den Kondensator und verdoppelt die Frequenz auf 1 kHz, dann ergibt sich diese Kurve. Wie man auch hier sieht, braucht man allenfalls zwei RC-Filter (blaue Kurve).

Sinusgenerator mit 5kHz Das ändert sich deutlich, wenn man auf 5 kHz geht: die blaue Kurve weist noch deutliche Zacken auf. Erst die dritte Stufe (gelbe Kurve) ist sauber.

Sinusgenerator mit 10kHz Bei 10 kHz ändert sich daran auch noch nicht viel. Die blaue Kurve ist jetzt schon recht verzuppelt, die rote Kurve vom ersten RC-Glied hat nicht mehr viel mit einem Sinus zu tun, denn nur noch jeder vierte Wert der Sinuskurven- Vollwelle landet tatsächlich beim PWM-Generator.

Sinusgenerator mit 20kHz Das wird bei 20 kHz dann noch verrückter: jetzt landen nur noch acht Werte der Sinuskurve tatsächlich im Comparator der PWM im TC1. Das dritte Filter (gelbe Kurve) ist schon recht sauber, aber die vierte Stufe reinigt diese nochmals nach.

Hier wirken effektiv nur noch vier Kondensatoren mit je 2n2 filternd.

Dreistufiges RC-Filter Hier der Beleg: ein 3-Stufen-RC-Filter bei 20 kHz: das ist etwas zu wenig, denn an der gelben Kurven gibt es etwas Reste der PWM zu sehen. Also besser noch eine Stufe dran, dann ist es sauberer.

Top Funktionsweise Hardware Aufbau Software Algorithmen

2 Hardware

2.1 Das Generatormodul

Schaltbild des Sinusgenerators mit ATtiny45 Dies hier ist das Schaltbild des Sinusgenerators.

Am ADC1-Eingang des ATtiny45 ist ein Zehngang-Poti angeschlossen, mit dem die Frequenz des Generators linear eingestellt werden kann.

Das Rechtecksignal vom Timer TC1 liegt am PB1-Pin an. Es wird mit einem vierstufigen Filter gefiltert. Wer nur Frequenzen unter 5 kHz erzeugen will oder wer keinen Wert auf Oberwellenarmut legen will, kann auch auf die zwei letzten Stufen des RC-Netzwerks verzichten.

Am Pin PB0 steht das Signal als Rechteck zur Verügung, so dass der Frequenzzähler ohne Analogeingang direkt angeschlossen werden kann (TTL- oder CMOS-Eingang).

Die Taktung erfolgt mit einem 20MHz-Quarz. Wer nur Frequenzen bis 5 kHz erzeugen will, kann auch einen niedriger-frequenten Quarz verwenden.

Mit der ISP6-Schnittstelle kann der Controller in der Schaltung programmiert und seine Fuses auf den Quarztakt umgeschaltet werden.

2.2 Der RC-Filter-Zusatz

Zusatz zur Kapazitaetskontrolle Bei der Schaltung werden je nach eingestelltem Frequenzbereich vier verschieden große Kondensatoren für jedes der vier RC-Filter gebraucht. Wer jetzt nicht nach der mechanischen Lösung mit einem 4 x 4 - Drehschalter greifen will (den es eh nicht zu kaufen gibt), der kann mit vier CMOS-ICs vom Typ 4066 dasselbe auch erreichen: je nachdem, welche der vier Eingänge CTL-A bis CTL-D des 4066 auf High stehen, wird der entsprechende Kondensator dem 2n2-Kondensator im RC-Netzwerk parallel-geschaltet. Das ergibt Kapazitäten von der in der Tabelle "rc-filters" berechneten Größe nimmt.

Im Einzelnen wurden folgende Kondensatorgrößen verwendet, die angegeben Grenzfrequenzen beziehen sich auf einen Widerstand von 2k2:

KondensatorAbkürzungGrenzfrequenz
2n2=FestCfix32,9 kHz
2n2 (+Fest)CA16,44 kHz
10n (+Fest)CB5,93 kHz
47n (+Fest)CC1,47 kHz
330n (+Fest)CD218 Hz


Die Daten der anderen Kombinationen können der Tabelle entnommen werden.

Da bei 20 kHz acht Werte pro Wellenzug ausgegeben werden, beträgt die PWM-Wechsel-Frequenz dort 160 kHz. Demgegenüber sind 32,9 kHz Grenzfrequenz schon eine ordentliche Filterung, allerdings erfährt auch die Nutzfrequenz von 20 kHz schon eine geringe Dämpfung, aber die macht durchaus Sinn.

Im untersten Frequenzbereich werden bei 20 Hz 256 Stützwerte pro Wellenzug ausgegeben, also 5,12 kHz PWM-Wechsel-Frequenz. Hier reicht schon der D-Kondensator von 330 nF mit 218 Hz für eine ordentliche Filterung aus, die anderen drei Kondensatoren wären da nicht unbedingt nötig. Und die Dämpfung der Nutzfrequenz ist auch nicht so arg gravierend. Idealer wäre da noch ein größerer Kondensator, aber das reduziert nur den ohnehin schon sehr geringen Ripple von der PWM noch mehr, merken tut das längst keiner mehr.

2.3 Automatisierte Kondensator-Umschaltung mit ATtiny25

Wer die Bedienung automatisieren will, braucht einen zweiten Controller. Dieser kann ein ATtiny25 sein. Es gibt zwei Möglichkeiten, das zu erledigen:
  1. mit zweiter Messung der Spannung des Potentiometers, oder
  2. mit Messung der Ausgabefrequenz.

2.3.1 Mit Messung des Potis

Schaltbild der Kapazitaetskontrolle mit Controller Die Messung erfolgt an ADC2 eines ATtiny25, das die Spannung am Frequenzeinstellungs-Poti misst und an seinen vier Pins PB0 bis PB3 die vier Einstellsignale für den Kapazitätseinsteller betätigt. Nix mehr zu verstellen, alles automatisch.

Einstellungen der Kapazitaetskontrolle mit Controller Auch dafür gibt es eine Einstell-Tabelle, damit Änderungen einfach gehen. Sie kann unter "rc-filters" in der LibreOffice-Calc-Datei dazu verwendet werden, um den gelb hinterlegten Teil der Tabelle in den Quellcode für den ATtiny25 hineinzukopieren und so alles Nötige schnell zur Hand zu haben und in Bits, Bytes und Prozessorworte zu verwandeln.

Bleibt die Frage, wieviele der vier RC-Filterstufen tatsächlich anzubauen sind. Mit allen vier Stufen hat man schon einen ziemlich großen 4066-Park zusammen. Das ist aber gar nicht nötig, weil die vier Stufen nur bei den hohen Frequenzen gebraucht werden. Es reicht also völlig aus, die vier Stufen mit vier kleinen Festkondensatoren zu bestücken und nur die zwei mittleren oder die beiden letzten Stufen mit zuschaltbaren Kondensatoren zu versehen.

2.3.2 Mit Frequenzmessung

Einstellungen der Kapazitaetskontrolle mit Frequenz Das geht im Prinzip genauso, nur wird hier am PB4-Eingang über den PCINT4-Interrupt die Frequenz gemessen. Dazu ist PB4/PCINT4 an den Frequenzausgang des ATtiny45 anzuschließen.

Mit der Tabelle "rc-filters" kann die weitere Konfigurierung des ATtiny25 erfolgen. Dazu müssen folgende Eingaben gemacht werden:
  1. In Zelle V2 kommt die Taktfrequenz des ATtiny25. Defaultmäßig ist das 1 MHz. Man kann den ATtiny25 aber auch höher (mit der CLKDIV8-Fuse oder durch Beschreiben des CLKPR) oder auch niedriger takten lassen (mit CLKPR).
  2. In Zelle V3 trägt man den TC0-Prescaler-Wert ein (1, 8, 64, 256 oder 1.024). Die Clock-Frequenz geteilt durch den Prescaler muss eine Ganzzahl in V4 ergeben, sonst geht es schon mal gar nicht.
  3. In Zelle V5 trägt man den TC0-Compare-A-Wert ein. Die Zahl muss man so wählen, dass die TC0-Frequenz in V6 geradzahlig wird und in V7 eine Ganzzahl herauskommt.
Damit hat man alle Parameter zusammen, die man zum Frequenzmessen so braucht: der Timer TC0 liefert nun mit dem Compare-A-Interrupt und einem 8- oder 16-Bit-Zähler eine Gate-Time von 0,5 Sekunden. Zählt man in dieser Zeit die Impulse bei jedem Pegelwechsel am PCINT4-Eingang, kriegt man direkt die Frequenz in Hz.

Das Umsetzen der gemessenen Frequenz in eine Kondensator-Kombination zwischen 0 und 15 macht die darunter liegende Tabelle ab Zeile 8. Mit der gemessenen Frequenz hangelt man sich durch diese Tabelle und kriegt so den passenden Kondensator heraus, den man nun nur noch in die Portpins PB3..PB0 schreiben muss.

Top Funktionsweise Hardware Aufbau Software Algorithmen

3 Aufbau

Sinusgenerator mit tn45 auf dem Steckbrett Das ist der ATtiny45 mit seinem Netto-RC-Filter (mit vier mal 2k2/2n2) auf dem Steckbrett.
RC-Filter mit zwei 4066 fuer Sinusgenerator auf dem Steckbrett Noch viel ausladender fällt ein zweistufiges Kondensatorfilter mit den beiden 4066 aus. Hier kann man die Kondensatoren mit einem Mäuseklavier manuell ein- und ausschalten.
Aufbau Sinusgenerator plus Filter auf Rasterplatine So können alle Bauteile eines tn45-Generators mit vierstufigem Filter, davon zwei mit Kondensatorsteuerung über einen tn25, auf einer Rasterplatine untergebracht werden.

Top Funktionsweise Hardware Aufbau Software Algorithmen

4 Software

Die Assembler-Software für den Generator und die beiden Versionen der Kapazitätskontrolle gibt es hier zum Download.

4.1 Der ATtiny45-Sinus-Generator

Die Software für den ATtiny45 gibt es im Assembler-Quellcode hier. Sie funktioniert ohne jede Änderung mit den eingestellten Default-Werten (2..20 kHz, 20-MHz-Quarz, 10-Gang-Poti).

Durch die Tabelle mit den 1.024 Poti-Wert-Einstellungen ist die Software sehr lang. Wer nur jeden zweiten Poti-Wert braucht (z. B. mit einem einfachen 270-Grad-Poti), kann die Software entsprechend umstellen und spart dadurch auch Flash-Speicher. Aber erst bei jedem vierten Poti-Wert passt das Ganze auch in einen ATtiny25.

Im Kopf des Quellcodes lassen sich diverse Einstellungen vornehmen, u.a. auch zum Debuggen des Quellcodes. Nach dem Herumspielen aber alles wieder auf Null einstellen, sonst funktioniert es nicht richtig.

Fuses des ATtiny45 im Originalzustand Fuses des ATtiny45 fuer angeschlossenen Quarz Vor oder nach dem Programmieren des ATtiny45 müssen noch dessen Fuses auf den externen Quarz umgestellt werden. Dazu ändert man die CLKDIV8- und die SUT_CKSEL-Fuses in der hier angegebenen Weise. Natürlich muss der Quarz beim Programmieren auch angeschlossen sein, sonst wird es nach dem Umstellen des Quarzes nix. Keine Angst in diesem Fall: einfach einen beliebigen Quarz an den Tiny anschließen und schon geht er wieder.

4.2 Der Kondensatorcontroller ATtiny25 mit ADC-Messung

Den Quellcode für den ATtiny25 als Kapazitätsumschalter für den oder die 4066s gibt es hier. Wird ein 45 oder 85 verwendet, einfach die def.inc-Zeile umstellen.

Die Software ist auf den Default-Takt von 1 MHz eingestellt, deshalb müssen hier keine Fuses geändert werden.

Die Konfigurierung der Software ist mit der LibreOffice-Calc-Datei möglich.

4.3 Der Kondensatorcontroller ATtiny25 mit Frequenzmessung

Den Quellcode für den ATtiny25 als Kapazitätsumschalter für den oder die 4066s gibt es hier. Auch hier kann bequem auf 45 oder 85 einstellen durch Umformulieren der def.inc-Zeile.

Auch diese Software ist auf die Default-Frequenz von 1 MHz eingestellt, so dass keine Fuses geändert werden müssen.

Die Konfigurierung der Software ist hier ebenfalls mit der LibreOffice-Calc-Datei möglich.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5 Algorithmen

Im Folgenden sind einige Algorithmen beschrieben, die in der Software verwendet werden.

5.1 Der TC1-PWM-Generator

Der ATtiny25/45/85 hat einen sehr besonderen PWM-Generator: er kann mit einem intern erzeugten Takt von 64 MHz (oder einem halbierten 32 MHz-Takt) laufen. Das macht es möglich, einen sehr schnellen PWM-Takt zu erreichen, denn 64 MHz / 256 = 250 kHz. Mit einem so hohen Takt kann man es durchaus unternehmen, Sinusse bis 20 kHz erzeugen zu wollen.

Die folgende Instruktionsfolge bringt den TC1 in diesen schnellen PWM-Modus.
  ; Start TC1 as fast PWM
  ldi rmp,0xFF ; 8-bit PWM
  out OCR1C,rmp
  ldi rmp,0x7F ; Output compare to 50% output
  out OCR1A,rmp
  ldi rmp,1<<PLLE ; Enable PLL
  out PLLCSR,rmp
  ldi rmp,30 ; Wait 100 us
WaitPll: ; Wait for PLL synchronization
  dec rmp
  brne WaitPll
WaitLock:
  in rmp,PLLCSR ; Wait for PLOCK
  sbrs rmp,PLOCK ; Jump if PLOCK is one
  rjmp WaitLock ; Wait on further until PLOCK is one
  ldi rmp,(1<<PCKE)|(1<<PLLE) ; Enable PCKE
  out PLLCSR,rmp
  ldi rmp,(1<<PWM1A)|(1<<COM1A0)|(1<<CS10) ; PWM mode A, non-inverted PWM, presc=1
  out TCCR1,rmp
Wenn man nun noch den OC1A-Ausgang am PB1 als Ausgang konfiguriert, dann kann man die ca. 250 kHz mit einer Aktivzeit von 50% messen. Schließt man noch ein RC-Netzwerk an (z. B. 4 mal 2k2/2n2), dann wird der letzte Kondensator saubere 2,5V anzeigen (wenn man das Ganze in Full-Range-Aussteuerung betreibt).

Durch Beschreiben des OCR1A-Registers kann man die ON-Zeit der PWM herauf- und heruntersetzen, so dass sie entsprechende analoge Signale liefert.

Bei höheren Sinus-Frequenzen als 1.550 Hz kann man das allerdings nur um den Preis, dass nicht alle 256 einzelnen Werte des Sinus auch ausgegeben werden können, denn das würde eine Ausgabe mit 5,12 MHz verlangen. Das ist selbst mit einem mit 20 MHz getakteten ATtiny45 nicht möglich, da er alleine für eine einzelne LPM-Instruktion schon 3 Takte braucht und für Interrupt und Rückkehr auch noch die eine oder andere zeitfressende Instruktion hinzukommt.

Taktet man die Ausgabe des OCR1A-PWM-Wertes mit dem TC0 im CTC-Modus, kommen auch noch Zeiten für die Auslösung des TC0-Compare-Match-A-Interrupts hinzu. Bei Frequenzen ab 1,575 kHz ist es mit dem 8-Bit breiten TC0 nicht mehr möglich, jede der 256 einzelnen Stufen des Sinusses an das Vergleichsregister OCR1A der PWM auszugeben und es wird nur noch jede zweite, ab 2.575 kHz dann jede dritte Stufe des Sinus ausgegeben, und bei noch höheren Frequenzen noch mehr Stufen. Bei 20 kHz ist es dann nur noch jede Achte. Aber so ein RC-Netzwerk nimmt so was überhaupt nicht krumm.

Abtastung des Sinus bei 20 kHz Bei 20 kHz dauert jedes Schreiben in das OCR1A-Register nur noch 6 µs lang, mit jedem Schreiben wird daher für ca. 1,5 PWM-Zyklen lang mit dem geschriebenen Wert gearbeitet. Immerhin ist das mehr als Eins.

Auch hier stützt sich die Sinusausgabe auf 32 Werte pro Wellenzug, was eine recht gute Auflösung ergibt. Den Rest müssen die RC-Filter dazusteuern, um daraus einen ordentlichen Sinus zu machen.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2 Erzeugung des Sinus

5.2.1 TC0 als OCR1A-Timer

Die Sinuswerte stehen in einer Tabelle im Flash-Memory. Die dort abgelegten Werte sind die Sinuswerte von 0 bis 2 * Π in 256-er Auflösung, zu Eins addiert und mit 128 multipliziert. Es stehen drei Tabellen zur Auswahl:
  1. die normale Tabelle, deren Werte von 0 bis 255 reichen, was einer Amplitude von 5Vpp entspricht,
  2. eine Tabelle für den Anschluss eines CA3140-Operationsverstärkers, die von 0 bis 152 reicht, was einer Amplitude von etwa 3Vpp entspricht, und
  3. eine Tabelle für den Anschluss eines 741-Operationsverstärkers, die von 100 bis 219 reicht, was von 1,95V bis 4,28V reicht und 2,33Vpp entspricht.
Die Auswahl der anzuwendenden Sinustabelle ist in der Software mittels einer definierten Konstante möglich.

In Abhängigkeit von der eingestellten Frequenz taktet der Timer TC0 die Ausgabe der OCR1A-Werte an die freilaufende PWM in TC1. Bei 20 Hz wird alle 195,2 µs ein Wert aus der Tabelle an die PWM ausgegeben, denn 20 Hz entspricht 50 ms und 256 * 195,2 µs = 49,971 ms. Bei einem Controller-Takt von 20 MHz wird dazu der Vorteiler von TC0 auf 64 eingestellt und der OCR0A-Wert auf 60, was 64 * (60 + 1) / 20.000.000 = 195,2 µs entspricht. Der TC0 wird auf den CTC-Modus eingestellt, mit dem TOP-Wert in OCR0A.

Mit jedem OC0A-Interrupt wird der nachfolgende Wert in der Tabelle ausgegeben, so dass sich der 20Hz-Sinus an der TC1-PWM abbildet. Im Minimalfall, wenn TC0 mit einem Vorteiler von 1.024 und einem Compare-A-Wert von 255 betrieben wird, kriegt man mit 20 MHz Takt die Frequenz bis herunter auf 0,3 Hz, muss dann aber den Kondensator im RC-Netzwerk entsprechend groß machen.

Bei höheren Frequenzen verkürzt sich der CTC-Zeitraum entsprechend. Ab 98 Hz wird der Vorteiler auf 8 herabgesetzt, ab 306 Hz auf 1. Ab 2,587 kHz ist das nicht mehr kurz genug und es wird nur noch jeder zweite Tabellenwert an OCR1A ausgegeben. Ab 5,162 kHz ist es jeder Dritte, ab 7,749 jeder Vierte. Die entsprechende Tabelle ist im Blatt "tc0-timer" einsehbar.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.2 Sinusausgabe in der Interrupt-Service-Routine

Die Sinusausgabe ist sehr zeitsensibel, denn Verzögerungen würden zu einer Verzerrung des Sinus führen. Bei sehr hohen Frequenzen (z. B. 20 kHz) muss die Ausgabe sehr schnell sein, sie darf nicht überfahren werden. Der Minimalwert beträgt bei 20 MHz 30 Takte, dann muss alles passiert sein, weil schon der nächste Interrupt eintrifft. Es lohnt daher, die ISR von TC0 ein wenig zu optimieren.

Das erste Beispiel zeigt, wie man das ohne Optimierung machen würde. Im zweiten Beispiel ist die Ausgabe durch Platzierung der Sinustabelle in einem eigenen 256-er-Feld gezeigt: sie ist um drei Takte schneller.
5.2.2.1 Sinusausgabe mit Sinustabelle an beliebiger Stelle
Interrupt Service Routine von TC0 Das hier wäre der Ausgabealgorithmus, wenn die Sinustabelle an einer beliebigen Stelle im Flash-Memory steht: das MSB der Adresse muss korrekt berücksichtigt werden, da es an beliebiger Stelle der Tabelle wechseln kann.

Das Register rStep liefert die aktuelle Schrittweite, im Register rNull steht eine Null und das Registerpaar Y zeigt auf die erste Stelle hinter der Tabelle (Adresse mal zwei). Bewegt sich der Zeiger Z nach dem Addieren von rStep auf eine Stelle jenseits der Tabelle, wird YH um eins erniedrigt, so dass Z wieder in die Tabelle zeigt. In diesem Fall torkelt auch das Bit 0 am Port B, so dass die halbe Frequenz am PB0-Ausgang für den Frequenzzähler ansteht.
5.2.2.2 Sinusausgabe mit Sinustabelle in eigenem 256-Byte-Feld
Interrupt Service Routine von TC0 mit festem MSB Fixiert man die 256 Werte der Sinustabelle in einem eigenen 256 Byte weiten Feld, das mit der Adresse 0xnn00 beginnt, dann muss man sich um das MSB nicht mehr kümmern, es bleibt immer das gleiche.

Nun muss nur noch die Frequenzausgabe erledigt werden, sofern beim Addieren von rStep ein Carry auftritt. Auch hier wird der Frequenzzähler nur die halbe Frequenz anzeigen.

Das führt zu einer Beschleunigung um drei Takte gegenüber der nicht optimierten Variante.
5.2.2.3 Sinusausgabe mit echter Frequenzausgabe
Bei beiden vorausgehenden Varianten ist der Nachteil, dass die Frequenzausgabe auf dem Pin PB0 nur einmal toggled, wenn der gesamte Sinus-Wellenzug einmal ausgeführt ist. Für eine echte Frequenzanzeige müsste er aber zwei Mal toggeln. Man kann sich nun damit behelfen, indem man einfach zwei OUTs auf den PINB-Port ausführt, was den Zeitbedarf um einen Taktzyklus verlängert. Das ist aber unschön, weil der aktive Impuls dann nur sehr kurz wäre.

Interrupt Service Routine TC0 mit echter Frequenzausgabe Besser ist es, die Frequenzausgabe so wie hier zu machen: das PB0-Bit wird an das Bit 7 von Register ZL angebunden. Das stellt sicher, dass es Null wird, solange die Werte in der unteren Tabelle verwendet werden, und Eins, wenn sie aus dem oberen Teil der Tabelle stammen. Das Ganze kostet nur einen Takt mehr, und der ist gegenüber dem Komfortgewinn beim Frequenzablesen zu verschmerzen. Bei ungeradzahligen Schrittweiten ist das Signal an PB0 natürlich nicht symmetrisch, aber das merkt normalerweise ein Frequenzzähler gar nicht.

Die gleiche Umstellung vom Torkeln mit PINB auf Bit 7 von ZL kann auch in der ersten Variante so realisiert werden. Das macht die Ausgabe an PB0 aber asynchron zur Sinusausgabe, aber das merkt auch kein Frequenzzähler.

In der Software ist die letzte beschriebene Variante realisiert. Die Verwendung der T-Flagge innerhalb der ISR beißt sich nicht mit deren Verwendung als ADC-fertig-Flagge, denn in der ISR wird das Statusregister ja zuerst gesichert und vor dem Abschluss wieder hergestellt, so dass der Flagge im Originalzustand von vor Beginn der ISR erhalten bleibt. Die BST- und BLD-Instruktionen helfen hier, jede Springerei zu vermeiden und das siebte Bit in ZL auf einfachste Weise in das Portbit PB0 zu kopieren.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.3 Die RC-Netzwerke

Die RC-Netzwerke sind in zwei Tabellen der LibreOffice-Calc-Datei verhackstückt:
  1. Die Tabelle "rc-filters" erlaubt es, mit dem festen Widerstand (in Zelle I3) und mit dem Festkondensator CFixed in Zelle G5 sowie, in den Tabellenzellen C5 bis F5, mit den zuschaltbaren Kondensatoren CD bis CA zu spielen. In der Spalte I der Tabelle sieht man die Grenzfrequenz der RC-Filter im Grundzustand mit Cfix und beim sukzessiven Zuschalten der vier Parallelkondensatoren.
  2. In der Tabelle "waves" kann man für einzugebende Frequenzen in Zelle E3 die jeweils passende Filterkombination (in Zelle G4) ermitteln lassen. Mittels Eingabe von Nullen und Einsen in den Zellenbereichen H7 bis K7 kann man den Netzwerken RC1 bis RC4 so viele 4066s zuschalten, wie man mag. Im Diagramm rechts sieht man dann den Filter-Response für RC1 bis RC4.
RC1 bis RC4 bei 20 kHz Hier sieht man das Ganze bei 20 kHz. Am RC1 (in rot) sieht man noch ein ziemliches Gezackere der PWM, aber das sieht schon einem Sinus recht ähnlich. Die blaue Kurve mit RC2 ist dagegen schon recht sauber und hat nur wenige Zacken im obersten und untersten Amplitudenbereich. RC3 und RC4 sind dann schön saubere Sinusse.

RC1 bis RC4 bei 20 kHz fuer CA3140 Stellt man die Zelle B7 auf den CA3140 um, kriegt man diese Kurve: sie bleibt jetzt durchgängig unter 2,5V Amplitude und reicht bis 0,5V herunter.

RC1 bis RC4 bei 20 kHz fuer 741 Selbiges für einen 741. Jetzt liegt die Amplitude höher und der Bereich unter 2,0V, bei dem der 741 nicht mehr linear arbeitet, wird gemieden.

RC1 bis RC4 bei 15 kHz Das hier ist die Kurve bei 15 kHz. Hier sind den beiden mittleren RC (RC2 und RC3) Kondensatoren von 2n2 zugeschaltet, so dass die blaue und die gelbe Kurve stärker gedämpft sind. Ehrlich gesagt ist RC4 hier eigentlich überflüssig und man käme mit einem drestufigen RC-Filter hin.

RC1 bis RC4 bei 5 kHz Bei niedrigeren Frequenzen, wie hier bei 5 kHz, werden noch weitere Kondensatoren zugeschaltet (hier 10nF und 2n2). Auch hier wirkt sich RC4 praktisch nur noch homöopatisch aus.

RC1 bis RC4 bei 100 Hz So sieht das Ganze bei 100 Hz aus. Die PWM an RC1 hat jetzt einiges zu tun. Die gelbe Kurve verschwindet hinter der grünen, weil das bisschen RC4 nun rein gar nichts mehr ausmacht.

Top Funktionsweise Hardware Aufbau Software Algorithmen


Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte per Email an mich (info und die Web-URL-Adresse), ich freue mich über alle Arten von Rückmeldungen.

©2023 by http://www.avr-asm-tutorial.net