'( Rechteck Frequenzgenerator mit Atmega8 Von 0 , 12 Hz Bis 8 Mhz(mit 16 Mhz Resonator / Quarz) Arne Groh 2009 -10 -08 Fuses: Default: 1101 1001 1110 0001(1 Mhz Intern) Here: 1100 1001 1110 1111(ext. Resonator) Mit Den Beiden Tasten Kann Die Frequenz Erhoeht Oder Vermindert Werden. Bei Laengerem Druecken Erhoeht Sich Die Schrittweite. Wenn Beide Tasten Gleichzeitig Laenger Gedrueckt Werden, Wird Zwischen High Und Low Frequenzen Umgeschaltet. Wenn 10 Sekunden Nichts Veraendert Wird , Werden Die Einstellungen Im Eeprom Gespeichert Und Sind Beim Naechsten Start Wieder Vorhanden. Wenn man beim Start die down-Taste drueckt, gelangt man in den Frequenzzaehler-Modus. Das Messintervall betraegt 2 Sek und muss an Pin PD5 (11) anliegen. ') $regfile = "m8def.dat" $crystal = 16000000 $baud = 9600 $hwstack = 64 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space ' --------- Eeprom aktivieren $eeprom $eepromhex Eeocr1a: Data &HFFFF% Eetccr1bcs12: Data 0 $data ' --------- Display initialisieren 'Fuer Lochrasterplatine - weniger Kreuzungen: Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.0 , E = Portc.3 , Rs = Portc.5 'Wie im Schaltplan: 'Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0 Config Lcd = 16 * 2 Cursor Off '--------- Tasteneingaenge High schalten Portd.2 = 1 Portd.3 = 1 '-------- Vars Dim Overflows As Word Dim Timer0count As Word Dim Flags As Byte Dim Tastcount As Word Dim Frequenz As Single Dim Frequenz2 As Long Dim Calclong As Long Dim Ocr1a As Word Dim Ocr1aold As Word Dim Ocr1aold2 As Word Dim Ocr1hi As Byte Dim Ocr1lo As Byte '-------- Startauswahl --------------------------- Dim Startcount As Byte Modechoice: Debounce Pind.2 , 0 , Mode1 Debounce Pind.3 , 0 , Mode2 Waitms 4 Incr Startcount If Startcount < 254 Then Goto Modechoice 'ca. 1 Sekunde '-------------- Mode0 Frequenzgenerator ------------- Mode0: '--------- Tasten abfragen Config Int0 = Low Level Config Int1 = Low Level Enable Int0 Enable Int1 On Int0 Increase Nosave 'Portd.2 On Int1 Decrease Nosave 'Portd.3 '--------- Timer0 einrichten Config Timer0 = Timer , Prescale = 1024 Enable Timer0 On Timer0 Check_eeprom Start Timer0 '---------- Timer1 manuel als Fast PWM einstellen Tccr1a = &B0100_0011 ' ^^--WGM11 + WGM10 -> Fast PWM |TOP in OCR1A Mode 15 ' ^---------COM1A0 -> Toggle OC1A Tccr1b = &B0001_1001 ' ^--CS10 -> Clk no prescale ' ^-^-----WGM13 + WGM12 -> Fast PWM |TOP in OCR1A Mode 15 Ocr1bh = &B0111_1111 : Ocr1bl = &B1111_1111 'Register fuer Tastverhaeltniss (16 bit Wert 50%) Config Portb.1 = Output 'OC1A : Hier kommt das Signal raus '---------------- Main ---------- 'Letzte Werte aus dem Eeprom holen Readeeprom Ocr1a , Eeocr1a 'Register fuer den TOP-Wert (16 bit) Ocr1aold2 = Ocr1a Readeeprom Flags.0 , Eetccr1bcs12 Tccr1b.cs12 = Flags.0 Enable Interrupts Gosub Printout Do Tastcount = 0 Flags.0 = Tccr1b.cs12 Loop End '-------------- Subs ------- Decrease: Disable Interrupts Ocr1aold = Ocr1a Incr Tastcount Waitms 200 If Pind.2 = 0 Then Gosub Toggle_cs12 Select Case Tastcount Case Is > 30 : Ocr1a = Ocr1a - 500 Case Is > 20 : Ocr1a = Ocr1a - 100 Case Is > 10 : Ocr1a = Ocr1a - 10 Case Else : Decr Ocr1a End Select If Ocr1a > Ocr1aold Then Ocr1a = 0 'bei Ueberlauf Gosub Printout Enable Interrupts Return Increase: Disable Interrupts Ocr1aold = Ocr1a Incr Tastcount Waitms 200 If Pind.3 = 0 Then Gosub Toggle_cs12 Select Case Tastcount Case Is > 30 : Ocr1a = Ocr1a + 500 Case Is > 20 : Ocr1a = Ocr1a + 100 Case Is > 10 : Ocr1a = Ocr1a + 10 Case Else : Incr Ocr1a End Select If Ocr1a < Ocr1aold Then Ocr1a = 65535 'bei Ueberlauf Gosub Printout Enable Interrupts Return Toggle_cs12: If Tastcount > 8 Then Toggle Tccr1b.cs12 'Prescale 1024 ein- und ausschalten Toggle Flags.0 Tastcount = 0 End If Return Printout: Ocr1hi = High(ocr1a) Ocr1lo = Ocr1a 'Bei Word zu Byte bleiben nur die Low-bits erhalten Ocr1ah = Ocr1hi Ocr1al = Ocr1lo Calclong = Ocr1a + 1 Calclong = Calclong * 2 Frequenz = _xtal \ Calclong If Flags.0 = 1 Then Frequenz = Frequenz / 1024 Print "Low "; Else Print "High "; End If Print Ocr1a 'Print Bin(ocr1hi) 'Print Bin(ocr1lo) Print Frequenz ; " Hz" Cls Locate 1 , 1 : Lcd Frequenz Locate 2 , 1 : Lcd "Hz" Locate 2 , 4 If Flags.0 = 1 Then Lcd "Low" Else Lcd "High" Timer0count = 0 Return Check_eeprom: 'Print Timer0count '10 Sekunden = (16.000.000 Clk / 1024 Prescaler / 255 8BitTimer) * 10 Sek If Timer0count > 620 Then If Ocr1aold2 <> Ocr1a Then Print "saving..." Cls Locate 1 , 1 : Lcd "pls wait" Locate 2 , 1 : Lcd "saving.." Writeeeprom Ocr1a , Eeocr1a Writeeeprom Flags.0 , Eetccr1bcs12 Ocr1aold2 = Ocr1a Gosub Printout End If Ocr1aold2 = Ocr1a Timer0count = 0 End If Incr Timer0count Return '------------------ Mode1 Frequenzzaehler ------------------------- Mode1: ' Timer1 als Counter einrichten Config Portd.5 = Input : Portd.5 = 0 Config Timer1 = Counter , Edge = Falling , Prescale = 1 On Counter1 Ueberlauf Nosave Enable Timer1 Do Counter1 = 0 Overflows = 0 Enable Interrupts '2 Sekunden zaehlen Waitms 2002 'finetunig Disable Interrupts Calclong = Overflows * &HFFFF Frequenz2 = Calclong + Counter1 Frequenz2 = Frequenz2 / 2 Print "f= " ; Frequenz2 ; " Hz" Cls Locate 1 , 1 : Lcd Frequenz2 Locate 2 , 1 : Lcd "Hz count" Loop End Ueberlauf: Incr Overflows Return '------------------ Mode2 ------------------------- Mode2: Do Print "Mode 2" Cls Locate 1 , 1 : Lcd "Mode 2" Locate 2 , 1 : Lcd "unused" Wait 2 Loop End