eratellt 14.05.2009
Frequenzgenerato

Frequenzerzeugung mittels Timer , davon besitzt der Atmega 32 gleich drei Stück ,davon sind zwei Timer sogenannte 8 Bit Timer und ein Timer mit einer Auflösung von 10 Bit ,
die völlig unbeeinflusst vom übrigen Programm ihren Dienst vollbringen.

Zum Schaltbild
Taster 1 erhöht und Taster 2 verringert die Frequenzausgabe.
Die Led zeigt die Frequenz an, allerdings ist die kleinste ausgegebene Frequenz immer noch zu groß um ein Blinken zu erreichen, somit erkennen wir nur ein Dauerleuchten der Led.
Einstellbare Frequenz umfasst in etwa 122 Hz bis 12 Khz.
Plan vergrößern
Programmbeschreibung

Led (grün) blinkt nach dem Einschalten mit einer Frequenz von 122 Hz, mit Taste 1 kann die Frequenz erhöht und mit Taste 2 verringert werden .
Die Schrittweite der Änderung für Taste 1 kann in der Variable A voreingestellt werden.
In diesem Fall hab ich beim aufwärtszählen die Schrittweite auf 10 gesetzt, beim abwärtszählen bleibt sie auf 1.
Somit hab ich eine gewisse Möglichkeit der Grob und der Feineinstellung .

Die Frequenz kann im Bereich 120 Hz bis 30 000 Hz variiert werden.
Zuerst wird der verwendete Timer in diesem Fall der Timer 0 mit CONFIG als Timer konfiguriert.
Dann wird die Taktfrequenz ( Quarzfrequenz) 16 Mhz auf einen niedrigeren für uns brauchbaren Wert heruntergeteilt, das wird mit der Anweisung PRESCALE bewerkstelligt.
In unseren Fall ist der Prescale (Vorteiler) Wert= 256 er kann Werte von 1-8-64-256 annehmen ( auch 1024 allerdings nur bei Timer 1).
Bei dem Prescale Wert von 256 wird also die Quarzfrequenz durch den Prescale Wert geteilt. Also 16 Mhz geteilt durch 265 = 62500 Hz.
Der Timer arbeitet also mit einer Frequenz von 62500 Hz und zählt von 0 bis 256 ,beim erreichen des Höchstwertes von 256 fängt er wieder bei Null an ,
gleichzeitig setzt er ein bestimmtes Bit ( Flag) quasi als Erinnerung das er einmal durchgelaufen ist und gibt uns damit die Möglichkeit eine Unterroutine
(ISR Interupt Service Routine) aufzurufen , welche dann abgearbeitet wird um anschließend wieder direkt an dem Programmpunkt zurück zu springen von dem aus es unterbrochen wurde.
In dem vorliegenden Fall zählt der Zähler innerhalb einer Sekunde von 0 bis 62500
Mit dieser Frequenz zählt der Timer0 jetzt bis 255 dann läuft er über und fängt wieder von vorne an zu zählen, und bei jedem Überlauf zählt er meine Variable höher.
Wir teilen als die 62500 durch 256 Schritte und kommen auf das Ergebnis von 244, 1Hz, da der Ausgang bei jedem Überlauf aber umgeschaltet wird ,
als nach dem Ersten Überlauf von 1 auf 0 und bei dem zweiten Überlauf von 0 auf 1, müssen wir die 244 noch einmal durch 2 teilen und kommen somit auf 122 Hz.
Somit haben wir eine feste Ausgangsfrequenz an PortA.0

Um die Frequenz aber auch zu variieren, haben wir die Möglichkeit den 8 Bit Timer nicht wie bisher von 0 bis 255 zählen zu lassen sondern wir geben ihm z.B. einen Wert vor so das er nicht von 0 bis 255 sonder von 100 bis 255 zählt damit erreicht er schneller sinen Überlauf, und damit wird die Ausgangsfrequenz erhöht.
Bascom Programm
Beschreibung
Programm
Beschreibung
 

 

 
Allgemeine Prozessor Konfiguration $regfile "m32def.dat" Definiert den Atmega als Atmega 32
  $crystal = 16000000 Gibt die Quarzfrequenz an in Herz
Variablen definieren Dim Wert1 As Word Word kann Werte bis 65535 aufnehmen
  Dim A As Long Variable für die Schrittweite zum Aufwärts-Zählen
Ein/Ausgänge definieren Ddra = &B00000001 Port A0 als Ausgänge setzen für Led
  Ddrb = &B00000000 Port B komplett als Eingänge setzen für Taster
  Portb = &B00000101 Port B.0 und B.2PullUp aktivieren für Taster
Timer definieren Config Timer0 = Timer , Prescale = 256 Bestimmt das Timer 0 verwendet und teilt den Takt durch 256
  Enable Timer0 Startet Timer 0
  On Timer0 Test Springt bei einem Überlauf nach Unterroutine " Test0"
  Enable Interrupts Generelle Interrupt aktivieren
Vorgabewerte A = 10 Vorgabewert für Schrittweite bei Aufwärts zählen
H a u p t p r o g r a m m Do Schleifenanfang
  If Pinb.0 = 1 Then Waitms 20 Beim Tastendruck Pause einfügen zum Entprellen
  If Pinb.0 = 1 Then Wert1 = Wert1 + A Beim Tastendruck Vorgabewert in A mit sich selber erhöhen
  If Pinb.2 = 0 Then Waitms 20 Beim Tastendruck Pause einfügen zum Entprellen
  If Pinb.2 = 0 Then Decr Wert1 Hier wird über Taste 2 der Wert um 1 verringert
  Loop Schleifenende
     
Unterroutine " Test0" Test0: Sprungmarke zu der gesprungen wird wenn der Timer einen Überlauf hat
  Timer0 = Wert1 Timer soll ab (Wert aus Wert1) hochzählen
  Toggle Porta.0 Port A.0 bei jeden Überlauf umschalten
  Return Rücksprung zum laufenden Programm
Programm-Ende
     
  Programm als *.bas hier  
 
Projecterweiterung
Hier wird der Frequenzgenerator noch um die Möglichkeit der Anzeige auf ein Display erweitert, und mit einer zusätzlichen Led versehen .
Damit wir die Frequenzhöhe anzeigen können benötigen wir den zusatzlichen Timer1 .
 
Beschreibung
Mit Timer0 erzeugen wir die Frequenz die auch in der Variable B übertragen wird, mit Timer 1 erzeugen wir einen Sekundentakt mit dem wir jeweils nach einer Sekunden
die in Variable B festgehaltene Frequenz wieder auf Null setzen
Im folgenden Listing sind alle Blauen Programmteile hinzugekommen oder geändert worden
Bascom Programm
Beschreibung
Programm
Beschreibung
 

 

 
Allgemeine Prozessor Konfiguration $regfile "m32def.dat" Definiert den Atmega als Atmega 32
  $crystal = 16000000 Gibt die Quarzfrequenz an in Herz
Variablen definieren Dim Wert1 As Word Word kann Werte bis 65535 aufnehmen
  Dim A As Long Variable für die Schrittweite zum Aufwärts-Zählen
  Dim B as Word  
  Dim C as Word  
     
     
Ein/Ausgänge definieren Ddra = &B00000011 Port A0 und A1 als Ausgänge setzen für Leds
  Ddrb = &B00000000 Port B komplett als Eingänge setzen für Taster
  Portb = &B00000101 Port B.0 und B.2PullUp aktivieren für Taster
     
Timer definieren Config Timer0 = Timer , Prescale = 256 Bestimmt das Timer 0 verwendet und teilt den Takt durch 256
  Config Timer1 = Timer , Prescale = 1024 Bestimmt das Timer 1 verwendet und teilt den Takt durch 1024
     
     
  Enable Timer0 Startet Timer 0
  Enable Timer1  
  On Timer0 Test 0 Springt bei einem Überlauf nach Unterroutine " Test0"
  On Timer1 Test1  
Konfiguration Display Config LCD= 16*2  
  Config LCDpin=Pin,Db4=Portc.2 , Db5=Portc.3,Db6=Portc.6,Db7=Portc.7,Rs=Portc.5,E=Portc.4
  Enable Interrupts Generelle Interrupt aktivieren
Vorgabewerte Timer1=54050  
  A = 10 Vorgabewert für Schrittweite bei Aufwärts zählen
  B=Porta.0  
H a u p t p r o g r a m m Do Schleifenanfang
  If Pinb.0 = 1 Then Waitms 20 Beim Tastendruck Pause einfügen zum Entprellen
  If Pinb.0 = 1 Then Wert1 = Wert1 + A Beim Tastendruck Vorgabewert in A mit sich selber erhöhen
  If Pinb.2 = 0 Then Waitms 20 Beim Tastendruck Pause einfügen zum Entprellen
  If Pinb.2 = 0 Then Decr Wert1 Hier wird über Taste 2 der Wert um 1 verringert
  cls Display löschen
  Locate1,1 Ausgabe im Display Zeile 1 Spalte 1
  Lcd "Frequenz=" Textausgabe auf Display
  Locate 2,1 Ausgabe im Display Zeile 2 Spalte 1
  Lcd C Ausgabe der Variable C im Display
  Locate 2,10 Ausgabe im Display Zeile 2Spalte 10
  Lcd "Hz" Textausgabe im Display
  waitms 100 Pause 100 Millisekunden einfügen
  Loop Schleifenende
     
Unterroutine " Test0" Test0: Sprungmarke zu der gesprungen wird wenn der Timer0 einen Überlauf hat
  Timer0 = Wert1 Timer soll ab (Wert aus Wert1) hochzählen
  Toggle Porta.0 Port A.0 bei jeden Überlauf umschalten
  Return Rücksprung zum laufenden Programm
     
Unterroutine " Test1" Test1: Sprungmarke zu der gesprungen wird wenn der Timer1 einen Überlauf hat
  Timer1=54050  
  Toggle Porta.1  
  C=B  
  C=C/2  
  B=0  
  Return Rücksprung zum laufenden Programm
Programm-Ende
     
Programm laden hier
 
Aktualisiert am 13.02.2019
Copyright 2009 by Ms