;************************************************************************************************ ;* DCC s-bahn Lokdekoder mit AT90S2313 (tiny2313) * ;* * ;* * ;* RESET = 1 20 = VCC * ;* PD0 = 2 19 = PB7 * ;* PD1 = 3 18 = PB6 * ;* XTAL2 = 4 17 = PB5 Licht rückwärts * ;* XTAL1 = 5 16 = PB4 Licht vorwärts * ;* DCC Eingang PD2 = 6 15 = PB3 Ausgang Motor PWM * ;* PD3 = 7 14 = PB2 Ausgang Vorwärts/Rückwärts * ;* PD4 = 8 13 = PB1 Licht Klingel * ;* PD5 = 9 12 = PB0 Licht innen * ;* GND = 10 11 = PD6 Klingelton * ;* * ;************************************************************************************************ .device at90s2313 .INCLUDE "2313def.inc" ;******************************** ;* FUSE info(tiny2313): * ;* * ;* SPMEN: * ;* DWEN: * ;* EESAVE: * ;* WDTON: * ;* BODLEVEL2: * ;* BODLEVEL1: * ;* BODLEVEL0: * ;* CKDIV8: * ;* CKOUT: * ;* SUT1: * ;* SUT0: * ;* CKSEL3: * ;* CKSEL2: * ;* CKSEL1: * ;* CKSEL0: * ;******************************** ;******************************** ;* Konstantendef. * ;******************************** ;.equ EEOSCCAL = 63 ; Speicherplatz OSCCAL im EEPROM .equ EEAdresse = 1 ; Speicherplatz eigene Adresse im EEPROM .equ EEStart = 2 ; Speicherplatz Start-Speed im EEPROM .equ EEIncWert = 3 ; Speicherplatz Beschleunigungskonstante im EEPROM .equ EEDecWert = 4 ; Speicherplatz Verzögerungskonstante im EEPROM .equ EEV_max = 5 ; Speicherplatz Höchstgeschwindigkeit im EEPROM .equ EEFL_PWM = 6 ; Speicherplatz Licht PWM im EEPROM .equ EEad_V_ist = 7 ; Speicherplatz EEPROM Adresse mit V_ist im EEPROM bit0 mit Richtung überschrieben! .equ EEPWM_Peri = 9 ; Speicherplatz Motor PWM Periode .equ EEcv29 = 29 ; Speicherplatz Konfigurationsregister ;Flagregister .equ resetbit = 0 ; ist nach dec reset gesetzt .equ progsw1 = 1 .equ progsw2 = 2 ; progschalter 2 .equ Vmerken = 3 .equ bit = 4 .equ neuesbit = 5 .equ messen = 6 .equ keinDCC = 7 ;DCCregister .equ F1 = 0 .equ F2 = 1 .equ F3 = 2 .equ F4 = 3 .equ FL = 4 .equ Richtung = 5 .equ Richtung_inv= 6 .equ Fahrstufen = 7 ;******************************** ;* Registerdef. * ;******************************** .def Adresse = r0 ; eigene Adresse .def V_IST = r1 ; momentane Geschwindigkeit .def V_SOLL = r2 ; Soll Geschwindigkeit .def IncWert = r3 ; Beschleunigungsvariable .def DecWert = r4 ; Bremsvariable .def IncCnt = r5 ; Beschleunigungszähler/Bremszähler 1 .def GrundCnt = r6 ; Zähler für Grundverzögerung .def FL_PWM = r7 ; Licht PWM in % 0=100 .def V_start = r8 ; Startspannung .def PROGTEST = R9 ; Testbyte für CV Schreiben .def byteA = r10 ; Empfangsbytespeicher .def byteB = r11 .def byteC = r12 .def byteD = r13 .def byteE = r14 .def byteF = r15 .def temp = r16 ; temp register .def null = r17 ; register mit wert null .def PWM_aus = r18 ; TCCR1 PWM Ausgang getrennt .def PWM_an = r19 ; TCCR1 PWM ein .def fktsreg = r20 ; sreg sicherungsregister in FKTset Routine .def inttemp = r21 ; interrupt tempregister .def intsreg = r22 ; sreg sicherungsregister .def flag = r23 ; Flagregister ; Bit0 = 1 -> resetbit ; Bit1 = 1 -> CV29bit6=1 zur Progumschaltung Licht PWM für RocoMaus ; Bit2 = 1 -> CV29bit5=1 zur Progumschaltung Motor PWM für RocoMaus ; Bit3 = 1 -> Vsoll im EEProm merken ; Bit4 -> das neue bit ; Bit5 = 1 -> neues bit da ; Bit6 = 1 -> bitzeit messen aktiv ; Bit7 = 1 -> länger als 10000us keine bits eingetroffen .def bitzaehler = r24 ; Bitzaehler beim Empfang .def eead = r25 ; eepromaddresse .def DCCReg = r26 ; DCC Register für Funktionen und Fahrtrichtung ; Bit7 = 1 -> 28 Fahrstufen (0 = 14 Fahrstufen) ; Bit6 = 1 -> Fahrtrichtung reversiert ; Bit5 Fahrtrichtung 1=vorwärts, 0=rückwärts ; Bit4 FL Licht ein/aus ; Bit3 F4 ; Bit2 F3 ; Bit1 F2 ; Bit0 F1 .def V_max = r27 ; Begrenzung v_max auf 50/62,5%/75/88,5%/100% .def PWMzaehler = r28 ; Zaehler für Licht PWM .def EEV_ist = r29 ; EE Adresse in der Vist im EEPROM gespeichert wird .def NFtemp = r30 ; Temp für NF routine .def NFtemp1 = r31 ; Temp1 für NF routine ;************************************************************************************************ ;* ab hier Programmcode * ;************************************************************************************************ .CSEG .ORG $0000 ;******************************************** ;* Reset- und Interrupt-Vektoren 90S2313 * ;******************************************** rjmp RESET ; Reset Einsprung rjmp EXT_INT0 ; Sprung zum Eingangsinterrupt0 reti ;EXT_INT1 ; Sprung zum Eingangsinterrupt1 reti ;TIM1_CAPT ; Timer1 Capture Handler reti ;TIM1_COMP ; Timer1 Compare Handler reti ;TIM1_OVF ; Timer1 overflow Einsprung rjmp TIM0_OVF ; Timer0 overflow Einsprung reti ;UART_RXC ; UART RX Complete Handler reti ;UART_DRE ; UDR Empty Handler reti ;UART_TXC ; UART TX Complete Handler reti ;ANA_COMP ; Analog Comparator Handler ;************************************************************************************************ ;* Interruptserviceroutinen * ;************************************************************************************************ ;************************************ ;* Eingangsinterrupt * ;************************************ ; wird bei jeder fallenden Flanke an int0/d2 ausgelöst ; timer0 auf 78us vor überlauf setzen ( Highbit nind. 52us+50% ) ; dazu teiler auf 8 (1us) und zähler auf 255-(78/1 = 78) ; zur sicherheit überlaufintbit von timer0 noch löschen ; könnte ja inzwischen gesetzt sein EXT_INT0: in intsreg,sreg ;sreg sichern clr inttemp ;timer anhalten out tccr0,inttemp ldi inttemp,179 ;Zähler setzen ((255-78)+2 (16takte)die beim timerneustart schon verganngen sind) out tcnt0,inttemp in inttemp,tifr ;überlauf timer0 löschen cbr inttemp,0b00000010 out tifr,inttemp sbr flag,(1< SOLL breq lichtset ; wenn Wert gleich weiter mit lichtset brsh DEC_V ; wenn Wert größer gleich brlo INC_V ; wenn Wert kleiner INC_V: inc IncCNT cp IncCNT,IncWert ; vergleiche Beschleunigungszähler brne lichtset ; wenn ungleich weiter mit lichtset clr IncCNT ; lösche Beschleunigungszähler inc V_IST ; erhöhe Speed rjmp PWMset ; weiter DEC_V: inc IncCNT cp IncCNT,DECWert ; vergleiche Beschleunigungszähler brne lichtset ; wenn ungleich weiter mit lichtset clr IncCNT ; lösche Beschleunigungszähler dec V_IST ; verringere Speed PWMset: tst V_IST ; ist Speed 0 brne PWMout ; wenn nicht weiter mit... ; ansonsten Timer/Counter1 PWM vom out TCCR1A,PWM_aus ; Ausgang trennen rjmp lichtset PWMout: out OCR1AH,null ; Wert für Speed nach Timer 1 Compare out OCR1AL,V_IST ; out TCCR1A,PWM_an ; Timer/Counter1 PWM Ausgang ein Richtung_setzen: sbrs DCCReg,Richtung ; wenn Fahrtrichtung vorwärts 1x springen rjmp REVout ; sonst gehe zu rückwärts sbi PORTB,PB2 ; setze Ausgang auf vorwärts rjmp lichtset REVout: cbi PORTB,PB2 ; setze Ausgang auf rückwärts Lichtset: ; Licht und FktAusgänge setzen sbrc DCCReg,FL ; wenn Licht aus 1x springen rjmp Lichtan ; wenn an gehe zu... cbi portb,4 ; lösche lichtausgänge cbi portb,5 rjmp FAset ; gleich weiter mit... Lichtan: inc PWMzaehler ; Zälher erhöhen cpi PWMzaehler,100 ; wenn 100 dann wieder auf 0 setzen brne PC+2 clr PWMzaehler cbi portb,5 ; Licht Rückwärts aus cbi portb,4 ; Licht Vorwärts aus cp PWMzaehler,FL_PWM ; Vergleich mit PWM Wert brlo FAset ; wenn Zaehler kleiner überspringen sbrs DCCReg,richtung ; 1x springen bei vorwärts rjmp Lichtrueckwaerts Lichtvorwaerts: sbi portb,4 ; Licht Vorwärts an rjmp FAset ; weiter mit... Lichtrueckwaerts: sbi portb,5 ; Licht Rückwärts an FAset: ; Funktionsausgänge setzen ; sbrc DCCReg,F1 ; wenn F1 gesetz: ; sbi portb,4 ; PB4 einschalten ; sbrs DCCReg,F1 ; wenn F1 aus ; cbi portb,4 ; PB4 ausschalten sbrc DCCReg,F2 ; wenn F2 gesetz: sbi portb,0 ; PB0 einschalten sbrs DCCReg,F2 ; wenn F2 aus cbi portb,0 ; PB0 ausschalten sbrc DCCReg,F3 ; wenn F3 gesetz: sbi portb,6 ; PB6 einschalten sbrs DCCReg,F3 ; wenn F3 aus cbi portb,6 ; PB6 ausschalten sbrc DCCReg,F4 ; wenn F4 gesetz: sbi portb,7 ; PB7 einschalten sbrs DCCReg,F4 ; wenn F4 aus cbi portb,7 ; PB7 ausschalten out sreg,fktsreg ; sreg wiederherstellen ret ; Rücksprung ;************************************ ;* Klingelton * ;************************************ ; wenn F1 an wird bei jedem losfahren klingelleuchte an PB4 gesetzt und an PD6 ein dreiton abgespielt ; dazu Timer1 kurz auf teiler 1024 ohne PWM umprogrammiert ; am Ende PWM Teiler wiederherstellen, klingelleuchte aus und zum losfahren zurückkehren Klingel: tst V_ist ; ist V_ist gleich Null breq PC+2 ; wenn ja V_soll auf losfahren testen ret ; wenn nicht gleichzurück tst V_soll ; soll losgefahren werden? brne klingeln ; wenn ja gehe zu.. ret ; sonst zurück klingeln: cli ; alle Interrupts ausschalten sbi portb,1 ; Klingelleuchte an out TCCR1A,null ; PWM mode aus ldi NFtemp,245 ; tonlänge in 30msek 0,3sek=10 -> 255-10=245 out TCNT1H,NFtemp ; lade den Timer/Counter1 out TCNT1L,null ; setze Zeit für Acknowlege in NFtemp1,TCCR1B ; MotorPWM Teiler sichern ldi NFtemp,0b00000101 ; 1 0 1 CK/1024 out TCCR1B,NFtemp in NFtemp,tcnt1l sbrc NFtemp,4 ; Tonfreq. 1ca 4kHz, 2ca 2kHz, 3ca 1kHz, 4ca 500Hz... sbi portd,6 sbrs NFtemp,4 cbi portd,6 in NFtemp,TIFR ; hole Timer Interuptflag sbrs NFtemp,TOV1 ; wenn Ackzeit abgelaufen rjmp PC-7 ; Schleife ldi NFtemp,0b10000000 ; lösche Timer Interupts out TIFR,NFtemp ldi NFtemp,248 out TCNT1H,NFtemp ; lade den Timer/Counter1 out TCNT1L,null ; setze Zeit für Acknowlege ldi NFtemp,0b00000101 ; 1 0 1 CK/1024 out TCCR1B,NFtemp in NFtemp,tcnt1l sbrc NFtemp,3 sbi portd,6 sbrs NFtemp,3 cbi portd,6 in NFtemp,TIFR ; hole Timer Interuptflag sbrs NFtemp,TOV1 ; wenn Ackzeit abgelaufen rjmp PC-7 ; Schleife ldi NFtemp,0b10000000 ; lösche Timer Interupts out TIFR,NFtemp ldi NFtemp,245 out TCNT1H,NFtemp ; lade den Timer/Counter1 out TCNT1L,null ; setze Zeit für Acknowlege ldi NFtemp,0b00000101 ; 1 0 1 CK/1024 out TCCR1B,NFtemp in NFtemp,tcnt1l sbrc NFtemp,4 sbi portd,6 sbrs NFtemp,4 cbi portd,6 in NFtemp,TIFR ; hole Timer Interuptflag sbrs NFtemp,TOV1 ; wenn Ackzeit abgelaufen rjmp PC-7 ; Schleife ldi NFtemp,0b10000000 ; lösche Timer Interupts out TIFR,NFtemp cbi portb,1 ; Klingelleuchte wieder aus out TCCR1B,NFtemp1 ; MotorPWM Teiler wiederherstellen inc V_ist sei ; interrups wieder ein ret ; und fertig ;************************************************************************************************ ;* Hauptprogramm * ;************************************************************************************************ Reset: ; Programm Kaltstart cli ; alle Interrupts ausschalten ldi temp,low(RAMEND) ; Stackpointer setzen out SPL,temp ldi temp,0b11111111 ; PB als Ausgang out DDRB,temp clr null ; alles auf low out portb,null ldi temp,0b01000000 ; PD0-5 als Eingang PD6 als Ausgang out DDRD,temp out portd,null ; alles auf low PullUp aus ldi TEMP,0b00000011 ; Bit0/1 ISC01 ISC00 Interupt Sense Control 0 out MCUCR,TEMP ; 0 0 Low Level of INT0 generate Interrupt ; 0 1 jeder Wechsel of INT0 ; 1 0 die fallende Flanke of INT0 ; 1 1 die steigende Flanke von INT0 erzeugt Interrupt ; Bit2/3 ISC11 ISC10 Interupt Sense Control 1 ; wie Bit0/1 ; Bit4 SM Sleep Modes ; Bit5 SE Sleep Enable ; Bit6/7 Reserve ldi TEMP,0b01000000 ; Bit0/5 Reserve out GIMSK,TEMP ; Bit6 INT0 Interrupt enable ; Bit7 INT1 Interrupt enable ldi TEMP,0b00000010 ; Bit0 Reserve out TIMSK,TEMP ; Bit1 TOIE0 Timer/Counter0 Overflow Interrupt Enable ; Bit2 Reserve ; Bit3 TICIE1 Timer/Counter1 Input Capture Interrupt Enable ; Bit4/5 Reserve ; Bit6 OCIE1A Timer/Counter1 Output Compare Match Interrupt Enable ; Bit7 TOIE1 Timer/Counter1 Overflow Interrupt Enable out OCR1AH,null ; Timer/Counter1 PWM ldi TEMP,0b11111000 ; OCR1A mit 248 (5x1und unten3x0 eingeschoben=11111000=V_max_wert) out OCR1AL,TEMP ; h byte löschen/ l byte setzen ;TCCR1B ; Bits 2,1,0 CS12, CS11, CS10: Clock Select1, Bits 2, 1 and 0 ; 0 0 0 Stop, the Timer/Counter1 is stopped. ; 0 0 1 CK PWM 32kHz ; 0 1 0 CK/8 PWM 4kHz ; 0 1 1 CK/64 PWM 500Hz ; 1 0 0 CK/256 PWM 125Hz ; 1 0 1 CK/1024 PWM 30Hz ; 1 1 0 External Pin T1, falling edge ; 1 1 1 External Pin T1, rising edge ; Bit 3 CTC1: Clear Timer/Counter1 on Compare Match ; Bits 5, 4 Res: Reserved Bits ; Bit 6 ICES1: Input Capture1 Edge Select ; Bit 7 ICNC1: Input Capture1 Noise Canceler (4 CKs) ;TCCR1A ; Bits 1, 0 PWM11, PWM10: Pulse Width Modulator Select Bits ; 0 0 PWM operation of Timer/Counter1 is disabled ; 0 1 Timer/Counter1 is an 8-bit PWM ; 1 0 Timer/Counter1 is a 9-bit PWM ; 1 1 Timer/Counter1 is a 10-bit PWM ; Bits 5..2 Res: Reserved Bits ; Bits 7, 6 COM1A1, COM1A0: Compare Output Mode1 ; 0 0 Not connected ; 0 1 Not connected ; 1 0 Cleared on compare match, upcounting. Set on compare match, down-counting (non-inverted PWM). ; 1 1 Cleared on compare match, downcounting. Set on compare match, up-counting (inverted PWM). ldi eead,EEPWM_Peri ; PWM Teiler für Motor laden rcall eepromlesen cbr temp,0b11111100 ; zur Sicherheit nichtgebrauchte Bits löschen (EEPROM Fehlprogrammierung) tst temp ; teste auf null brne pc+2 ; wenn ungleich 1x springen inc temp ; wenn Null auf 1 erhöhen inc temp ; jetzt immer um 1 erhöhen(wert ist jetzt zw 2 und 4) out TCCR1B,temp ; PWM Teiler setzen (2=CK/8=4kHz,3=CK/64=500Hz,4=CK/256=125Hz) ; setze PWM aus/an Werte ldi PWM_aus,0b00000001 ; für tccr1a 8-bit PWM aber Ausgang nicht verbunden ldi PWM_an,0b10000001 ; PWM_an Variable setzen ; 8-bit PWM an (nicht invertiertes signal) ausgang verbunden out TCCR1A,PWM_aus ; setze PWM Teiler und trenne Ausgang ab out TCNT1H,null ; lösche Timer 1 out TCNT1L,null ldi TEMP,0b01000000 ; lösche externen Interupt 0 out GIFR,TEMP ldi TEMP,0b00000010 ; lösche Timer0 Interupt out TIFR,TEMP ; ldi eead,EEOSCCAL ; hole Oszillator Calibrierung ; rcall eepromlesen ; out OSCCAL,temp ldi eead,EEAdresse ; hole Adresse rcall eepromlesen mov Adresse,Temp ldi eead,EEStart ; hole Startspannung rcall eepromlesen mov V_start,Temp ldi eead,EEIncWert ; hole Beschleunigung rcall eepromlesen mov IncWert,Temp inc IncWert ; 0=aus auf 1 setzten( kleinster wert ist 1 im Programmablauf) ldi eead,EEDecWert ; hole Verzögerung rcall eepromlesen mov DecWert,Temp inc DecWert ; wie incwert ldi eead,EEV_max ; hole Höchstgeschwindigkeit rcall eepromlesen mov V_max,Temp ldi eead,EEFL_PWM ; hole Licht PWM Wert rcall eepromlesen mov FL_PWM,Temp ldi eead,EEcv29 ; Konfig bits holen rcall eepromlesen bst Temp,1 ; 14/28 Fahrstufen bld DCCReg,Fahrstufen bst Temp,0 ; Reversierbetrieb bld DCCReg,Richtung_inv bst Temp,6 ; CV29 bit6 holen und kurz in T bit merken clr flag ; flag setzen erst löschen sbr Flag,(1< verwerfen und zurück rjmp hauptschleife ; Endlosschleife zu_dcc_reset: rjmp reset ; Dec reset machen zu_Fgruppe1: rjmp Fgruppe1 V_Calc: ; V Berechnung 14 und 28 Fahrstufen rcall FKTset ; hier erst nocheinmal Funktionen setzen ; zuerst Richtung schreiben mov TEMP,byteB ; Daten sichern tst V_IST ; ist V ungleich 0 ? brne V_set ; wenn ja gehe zu Fahrstufen setzen sbrc DCCReg,richtung_inv ; wenn Fahrrichtung nicht reversiert 1x springen com byteB ; ansonsten wird Byte gedreht bst byteB,5 ; hole Richtungsbit bld DCCReg,richtung ; nach DCC Register V_set: ; Fahrstufen setzen sbrc DCCReg,fahrstufen ; 0=14 Fahrstufen 1x springen rjmp V_28set ; wenn 28 gehe zu bst temp,4 ; Lichtbit holen bld DCCReg,FL ; und in FL ablegen cbr temp,0b11110000 ; bits für kennung, richtung und licht löschen V_28set: ; ab hier für 14 und 28 Fahrstufen gleich rcall FKTset ; hier erst nocheinmal Funktionen setzen bst temp,4 ; bit0 für 28 Fahrstufen sichern cbr temp,0b11110000 ; bits für kennung und richtung löschen cpi temp,0b00000001 ; auf notstop testen breq Notstop ; wenn gleich gehe zu rol temp ; 1x nachlinks verschieben bld temp,0 ; und bit0 wieder einfügen mov byteB,temp ; V_max begrenzung auf 50/62,5%/75/88,5%/100% add temp,byteB ; V auf 37,5% add temp,byteB cpi V_max,4 breq V50set cpi V_max,3 breq V625set cpi V_max,2 breq V75set cpi V_max,1 breq V885set rcall FKTset ; hier erst nocheinmal Funktionen setzen V100set:add temp,byteB V885set:add temp,byteB V75set: add temp,byteB V625set:add temp,byteB V50set: add temp,byteB Vstartset: cpi temp,0 ; bei stop überspringen breq Vsollset cp temp,V_start ; Startgeschw setzen brsh Vsollset ; wenn neue V kleiner V_start mov temp,V_start Vsollset: cp V_soll,temp ; neuen V wert empfangen? brne PC+2 ; wenn ja 1x springen rjmp Hauptschleife ; wenn kein neuer wert gehe zurück rcall FKTset ; hier erst nocheinmal Funktionen setzen mov V_soll,temp ; neue soll geschw. ablegen sbrs flag,Vmerken ; wenn V merken an 1x springen rjmp Hauptschleife ; sonst gehe gleich zu.. ldi PWMzaehler,99 ; vor EEprom schreiben Licht bei PWM Betrieb aus (blitzt sonst auf) rcall FKTset ; hier erst nocheinmal Funktionen setzen bst DCCreg,richtung ; Richtungsbit holen bld temp,0 ; und bit0 von Vsoll in Temp überschreiben mov eead,EEV_ist ; V wert im EEprom merken rcall eepromschreiben rjmp hauptschleife ; Endlosschleife Notstop: clr V_SOLL ; Notstop machen clr V_IST ; ; Timer/Counter1 PWM vom out TCCR1A,PWM_aus ; Ausgang trennen cbi PortB,2 ; alles auf Null rjmp hauptschleife ; Endlosschleife Fgruppe1: ; Befehle für FG1 einlesen rcall FKTset ; hier erst nocheinmal Funktionen setzen bst byteB,F1 ; F1 bis F4 sichern bld dccreg,F1 bst byteB,F2 bld dccreg,F2 bst byteB,F3 bld dccreg,F3 bst byteB,F4 bld dccreg,F4 sbrs DCCReg,fahrstufen ; 1=28 Fahrstufen 1x springen rjmp hauptschleife ; bei 14 fertig Endlosschleife bst byteB,FL ; bei 28 noch Lichtbit sichern bld dccreg,FL rjmp hauptschleife ; und dann zurück progmode: mov TEMP,byteA ; Daten sichern cpi temp,0b00000000 ; Vergleich auf dcc reset breq noch_dcc_reset ; dec reset beatbeiten cpi TEMP,0b01111100 ; prüfe Funktionscode auf CV Write Byte Schreiben breq progbyte ; cbr flag,(1< abbrechen sbrs flag,ProgSw1 ; wenn 0 rjmp progsw2_test ; gehe zu ... ldi eead,EEcv29 ; progschalter wieder auf normal schalten rcall eepromlesen ; es wird genau 1x schreiben in FL PWM erlaubt cbr Temp,0b01000000 ; rcall eepromschreiben ; ldi temp,(EEFL_PWM-1) ; sonst setzte auf FL PWM Byte mov ByteB,temp rjmp prognormal progSw2_test: sbrs flag,ProgSw2 ; wenn 0 rjmp prognormal ; gehe zu ... ldi eead,EEcv29 ; progschalter wieder auf normal schalten rcall eepromlesen ; es wird genau 1x schreiben in Motor PWM erlaubt cbr Temp,0b00100000 ; rcall eepromschreiben ; ldi temp,(EEPWM_Peri-1) ; sonst setzte auf FL PWM Byte mov ByteB,temp prognormal: mov eead,ByteB ; setzte Schreib-Adresse inc eead ; weil im eeprom zelle0 unbenutzt bleibt (alles 1x nach obenverschoben) mov TEMP,ByteC ; hole Daten rcall eepromschreiben ; und schreibe ins EEPROM sbi PortB,PB3 ; setze einen Motorausgang PROGBeschtaetigung: ; Acknowledge cli ; alle Interrupts ausschalten out TCCR1A,null ; PWM mode aus ldi temp,220 out TCNT1H,temp ; lade den Timer/Counter1 out TCNT1L,null ; setze Zeit für Acknowlege ldi TEMP,0b00000101 ; 1 0 1 CK/1024 für Resetzeit und ACK out TCCR1B,TEMP ; in TEMP,TIFR ; hole Timer Interuptflag sbrs TEMP,TOV1 ; wenn Ackzeit abgelaufen rjmp PC-2 ; Schleife ldi TEMP,0b10000000 ; lösche Timer Interupts out TIFR,TEMP out PortB,null ; lösche Motorausgang rjmp Reset ; und neustart PROGWRACK: mov PROGTEST,ByteD ; Datencheck rjmp Hauptschleife ; Endlosschleife .ESEG ;CV Register im eeprom vom tiny15 Lokdec .db $ff .db 0b00000001 ;CVregister 1 = Dekoderaddresse .db $1 ;CVregister 2 = Startspannung 0-255 0 funktion aus 255 immer V_max .db 50 ;CVregister 3 = Beschleunigungsrate ca 0-255 zeitstufen sind ungleichmäßig .db $0 ;CVregister 4 = Verzögerungsrate ca 0-255 zeitstufen sind ungleichmäßig .db $0 ;CVregister 5 = V_max Begrenzung 4=50% 3=62,5% 2=75% 1=88,5% 0=100% .db 70 ;CVregister 6 = Licht PWM aus Zeit in % (0 immer an 99 = 99% aus) .db 32 ;CVregister 7 = Zeiger auf Vist Speicherplatz Standart ist 32 .db $ff .db 2 ;CVregister 9 = Motor PWM Periode (0und1=4kHz 2=500Hz 3=125Hz) .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db $ff .db 0b00010010 ;CVregister 29 Konfigurationsregister (zum Licht PWM programmieren+64=82 Motor PWM+32=50) ;Funktionen: bit0=1 Richtungstausch ;(18) bit1=0 14/ =1 28 Fahrstufen ; bit4=1 Vsoll in EEprom merken ; bit5=1 nächster ProgBefehl Motor PWM ; bit6=1 nächster ProgBefehl Licht PWM .db $ff .db $ff .db $0 ;bit1-7 Vist bit0 Richtung wenn in CV 29 gefordert .db $FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF .db $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$70 ;Osccal byte (nicht bei 2313)