'****************************************************** 'Projekt: Atmel-Programmierung für Einsteiger ' 'Prozessor: ATMega 8-16 'Bascom-Version: 1.11.8.1 ' 'Auswertung für Graupner Nautic Expert Baustein ' 'Version: 1.0 ' 'Hardware: 'R/C-Kanal an D.2 (INT0) 'Dreh-Codierschalter (4 Bit) an D.4...D.7 ' '18.08.2006 T. Gietenbruch ' '****************************************************** '====================================================== 'System-Einstellungen '====================================================== 'Definition für Mega 8 $regfile "m8def.dat" 'Angabe der Taktfrequenz (8Mhz) $crystal = 4000000 '====================================================== 'Konfigurationen '====================================================== 'Konfiguration der I/O-Ports´s Ddrb = &B11111111 Ddrc = &B11111111 Ddrd = &B00000011 'Timer 1 für R/C-Signal Config Timer1 = Timer , Prescale = 1 'Timer2 für Setup-Blinker Config Timer2 = Timer , Prescale = 1024 'Konfiguration des INT0 'Interrupt bei jedem Flankenwechsel (0->1 und 1->0) Config Int0 = Change '====================================================== 'Deklarationen '====================================================== Dim N As Byte Dim N_old As Byte Dim Signals As Byte Dim Reading As Bit Dim Rc_value(10) As Word Dim Error As Bit Dim Sync_detect As Bit Dim X As Word Dim Switch_up As Byte Dim Switch_dn As Byte Dim Sync_ok As Bit Dim Cycle_done As Bit Dim Switchhold As Byte Dim Number As Byte Dim Watch_dog As Word Dim Code_raw As Byte Dim Code_value As Byte Dim Code_old As Byte Dim Memory_up As Byte Dim Memory_down As Byte Dim Row_up As Bit Dim E_memory_up As Eram Byte Dim E_memory_down As Eram Byte Dim Flash As Bit Dim Flash_delay As Byte Dim Bit_adr As Byte '====================================================== 'Konstanten '====================================================== Const Sync_low = 8000 Const Sync_high = 9000 Const Switch_dn_low = 4000 Const Switch_dn_high = 5500 Const Switch_up_low = 7000 Const Switch_up_high = 7900 '====================================================== 'Initialisierungen '====================================================== 'Zuweisung der Interrupt-Service-Routinen On Timer1 Rc_error On Timer2 Flasher On Int0 Rc_read 'Interrupt-Freigaben Enable Timer1 Stop Timer1 Enable Timer2 Stop Timer2 Enable Int0 'Ports initialisieren Portb = &B00000000 Portc = &B00000000 Portd = &B00000000 'Rücklesen der EEPROM-Variablen Memory_up = E_memory_up Memory_down = E_memory_down 'Freigabe aller Interrupt-Routinen Enable Interrupts 'Etwas warten, falls die Signale den Watchdog auslösen X = 0 While X < 10000 And Error = 0 Incr X Wend If Pind.3 = 0 Then Goto Setup_ende '====================================================== 'Setup-Routine '====================================================== Setup: Disable Int0 'Warten bis Setup-Taster frei Bitwait Pind.3 , Reset Waitms 10 'Schalten auf obere Reihe Set Row_up 'Blinktakt starten Start Timer2 '++++++++++++++++++++++++++++++++++ 'Haupt-Setup-Schleife '++++++++++++++++++++++++++++++++++ Do 'Transfer der vier Bit des Schalters in den Code-Wert Code_raw = Pind If Code_old <> Code_raw Then Code_old = Code_raw Shift Code_raw , Right , 4 Code_value = Code_raw Bit_adr = Code_value - 1 End If 'Blinkanzeige der Setup-Einstellung If Code_value > 0 Then 'Dauerlicht für angewählte Reihe oben If Code_value = 9 And Row_up = 1 Then Portc.0 = 1 Portb.0 = 0 'Dauerlicht für angewählte Reihe unten Elseif Code_value = 9 And Row_up = 0 Then Portc.0 = 0 Portb.0 = 1 'Dauerlicht für angewählter Schalter speichernd oben Elseif Code_value <= 8 And Row_up = 1 And Memory_up.bit_adr = 1 Then Portc.0 = 1 Portb.0 = 0 'Dauerlicht für angewählter Schalter speichernd unten Elseif Code_value <= 8 And Row_up = 0 And Memory_down.bit_adr = 1 Then Portc.0 = 0 Portb.0 = 1 'Blinklicht für angewählter Schalter nicht speichernd oben Elseif Code_value <= 8 And Row_up = 1 And Memory_up.bit_adr = 0 Then Portc.0 = Flash Portb.0 = 0 'Blinklicht für angewählter Schalter nicht speichernd unten Elseif Code_value <= 8 And Row_up = 0 And Memory_down.bit_adr = 0 Then Portc.0 = 0 Portb.0 = Flash End If 'Bei Stellung 0 Wechselblinken Else Portc.0 = Flash Portb.0 = Not Flash End If 'Umstellung des Schalter-Setups If Code_value <> 0 And Pind.3 = 1 Then 'Warten bis Setup-Taster frei Bitwait Pind.3 , Reset Waitms 10 'Anwahl obere/untere Reihe If Code_value = 9 Then Toggle Row_up End If 'Anwahl Schalter obere/untere Reihe If Code_value <> 9 Then If Row_up = 1 Then Toggle Memory_up.bit_adr Elseif Row_up = 0 Then Toggle Memory_down.bit_adr End If End If End If 'Setup verlassen If Code_value = 0 And Pind.3 = 1 Then 'Warten bis Setup-Taster frei Bitwait Pind.3 , Reset Waitms 10 Stop Timer2 'Speichern der EEPROM-Variablen E_memory_up = Memory_up E_memory_down = Memory_down Enable Int0 Enable Interrupts Disable Timer2 Goto Setup_ende End If Loop Setup_ende: 'Konfiguration des internen Watchdogs Config Watchdog = 512 '====================================================== 'Synchronisationsroutine '====================================================== Syncronize: Signals = 1 N = 1 Sync_detect = 0 X = 0 'Rücksetzen aller Schaltersignale For X = 0 To 7 Switch_up.x = 0 Switch_dn.x = 0 Next X 'Rücksetzen der Ports Portb = 0 Portc = 0 'Warten auf ersten Synchronisationswert While Sync_detect = 0 Wend N = 2 Sync_detect = 0 'Warten auf zweiten Synchronisationswert 'Begrenzt durch Zählschleife X = 0 While X < 5000 And Sync_detect = 0 Incr X Wend 'Auswertung des Synchronisationsergebnisses If X < 5000 And Rc_value(1) > Sync_low And Rc_value(2) > Sync_low Then N = 3 Signals = 10 Else Goto Syncronize End If Watch_dog = 0 'Wartezeit, falls Watchdog doch noch zubeisst Waitms 2000 '====================================================== 'Hauptprogramm-Schleife '====================================================== Do 'Auswertung der gelesenen Werte (im Block) If Cycle_done = 1 And Reading = 0 And Error = 0 Then Cycle_done = 0 'Überprüfung der Synchronisationssignale If Rc_value(1) > Sync_low And Rc_value(2) > Sync_low And Error = 0 Then Sync_ok = 1 Else Sync_ok = 0 Goto Syncronize End If 'Aktualisierung der Schaltersignale If Sync_ok = 1 Then For X = 3 To Signals Number = X - 3 'Schalter nach oben betätigt If Rc_value(x) > Switch_up_low And Rc_value(x) < Switch_up_high Then If Switchhold.number = 0 Then Switchhold.number = 1 Toggle Switch_up.number End If 'Schalter nach unten betätigt Elseif Rc_value(x) > Switch_dn_low And Rc_value(x) < Switch_dn_high Then If Switchhold.number = 0 Then Switchhold.number = 1 Toggle Switch_dn.number End If 'Schalter in Mittelstellung Else Switchhold.number = 0 'Schaltersignal rücksetzen, wenn nicht remanent If Memory_up.number = 0 Then Switch_up.number = 0 If Memory_down.number = 0 Then Switch_dn.number = 0 End If Next X 'Zuweisung der Hardwareports Portc.0 = Switch_up.0 Portc.1 = Switch_up.1 Portc.2 = Switch_up.2 Portc.3 = Switch_up.3 Portc.4 = Switch_up.4 Portc.5 = Switch_up.5 Portd.0 = Switch_up.6 Portd.1 = Switch_up.7 Portb.0 = Switch_dn.0 Portb.1 = Switch_dn.1 Portb.2 = Switch_dn.2 Portb.3 = Switch_dn.3 Portb.4 = Switch_dn.4 Portb.5 = Switch_dn.5 Portb.6 = Switch_dn.6 Portb.7 = Switch_dn.7 End If End If 'Soft-Watchdog If N = N_old Then Incr Watch_dog If Watch_dog > 5000 Then Goto Syncronize Else N_old = N Watch_dog = 0 End If 'Ansprung der Setup-Routine bei Taster-Betätigung If Pind.3 = 1 Then Goto Setup Loop 'Programmende (nur formal) End '====================================================== 'ISR für INT0 - Signalfolge lesen '====================================================== Rc_read: 'Den Timer starten mit steigender Flanke If Reading = 0 And Pind.2 = 1 Then Start Timer1 Reading = 1 'Den Timer stoppen mit fallender Flanke Else Stop Timer1 Rc_value(n) = Timer1 Timer1 = 0 Reading = 0 'Validierung des gelesenen Wertes If Rc_value(n) < Switch_dn_low Or Rc_value(n) > Sync_high Then Goto Rc_error 'Prüfung auf Sync-Signal If N < 3 And Rc_value(n) > Sync_low And Rc_value(n) < Sync_high Then Sync_detect = 1 End If '...wenn die Synchronisation fertig ist If Signals > 2 Then Incr N End If If N > Signals Then N = 1 Cycle_done = 1 End If End If 'Error-Bit rücksetzen Error = 0 Return '====================================================== 'ISR für Timer1 - Fehlerhandling '====================================================== Rc_error: 'Error-Bit setzen Error = 1 Reading = 0 Stop Timer1 'Reset erzwingen Disable Interrupts Start Watchdog Waitms 10000 Return '====================================================== 'ISR für Timer2 - Blinkimpuls '====================================================== Flasher: Incr Flash_delay If Flash_delay > 3 Then Toggle Flash Flash_delay = 0 End If Return