$TITLE (receiver) $DEBUG $OBJECT ;************************************************************************ ;* * ;* Version 1 * ;************************************************************************ ; Include file for 87LPC764 SFR Definitions ; Philips Semiconductors. Revision 1.0, 04/20/99 ACC data 0E0h ; Accumulator AUXR1 data 0A2h ; Auxiliary Function Register ADCON data 0C0H ; A/D control register ADCS bit ADCON.3 ; A/D start ADCI bit ADCON.4 ; A/D complete B data 0F0h ; B Register CMP1 data 0ACh ; Comparator 1 Control Register CMP2 data 0ADh ; Comparator 2 Control Register DIVM data 095h ; CPU Clock Divide-By-M Control DPL data 082h ; Data Pointer - Low Byte DPH data 083h ; Data Pointer - High Byte DACO data 0C5H ; A/D Result I2CFG data 0C8h ; I2C Configuration Register CT0 bit I2CFG.0 ; Clock Time Select 0 CT1 bit I2CFG.1 ; Clock Time Select 1 TIRUN bit I2CFG.4 ; Timer I Run Enable CLRTI bit I2CFG.5 ; Clear Timer I MASTRQ bit I2CFG.6 ; Master Request SLAVEN bit I2CFG.7 ; Slave Enable I2CON data 0D8h ; I2C Control Register MASTER bit I2CON.1 ; Master Status STP bit I2CON.2 ; Stop Detect Flag STR bit I2CON.3 ; Start Detect Flag ARL bit I2CON.4 ; Arbitration Loss Flag DRDY bit I2CON.5 ; Data Ready Flag ATN bit I2CON.6 ; Attention: I2C Interrupt Flag RDAT bit I2CON.7 ; I2C Read Data I2DAT data 0D9h ; I2C Data Register IEN0 data 0A8h ; Interrupt Enable Register 0 EX0 bit IEN0.0 ; External Interrupt 0 Enable ET0 bit IEN0.1 ; Timer 0 Interrupt Enable EX1 bit IEN0.2 ; External Interrupt 1 Enable ET1 bit IEN0.3 ; Timer 1 Interrupt Enable ES bit IEN0.4 ; Serial Port Interrupt Enable EBO bit IEN0.5 ; Brownout Interrupt Enable EWD bit IEN0.6 ; Watchdog Interrupt Enable EA bit IEN0.7 ; Global Interrupt Enable IEN1 data 0E8h ; Interrupt Enable Register 1 EI2 bit IEN1.0 ; I2C Interrupt Enable EKB bit IEN1.1 ; Keyboard Interrupt Enable EC2 bit IEN1.2 ; Comparator 2 Interrupt Enable EC1 bit IEN1.5 ; Comparator 1 Interrupt Enable ETI bit IEN1.7 ; Timer I Interrupt Enable IP0 data 0B8h ; Interrupt Priority 0 Low Byte PX0 bit IP0.0 ; External Interrupt 0 Priority PT0 bit IP0.1 ; Timer 0 Interrupt Priority PX1 bit IP0.2 ; External Interrupt 1 Priority PT1 bit IP0.3 ; Timer 1 Interrupt Priority PS bit IP0.4 ; Serial Port Interrupt Priority PBO bit IP0.5 ; Brownout Interrupt Priority PWD bit IP0.6 ; Watchdog Interrupt Priority IP0H data 0B7h ; Interrupt Priority 0 High Byte IP1 data 0F8h ; Interrupt Priority 1 Low Byte PI2 bit IP1.0 ; I2C Interrupt Priority PKB bit IP1.1 ; Keyboard Interrupt Priority PC2 bit IP1.2 ; Comparator 2 Interrupt Priority PC1 bit IP1.5 ; Comparator 1 Interrupt Priority PTI bit IP1.7 ; Timer I Interrupt Priority IP1H data 0F7h ; Interrupt Priority 1 High Byte KBI data 086h ; Keyboard Interrupt P0 data 080h ; Port 0 CMP2O bit P0.0 ; P0, bit 0 is also the Comparator 2 Output CIN2B bit P0.1 ; P0, bit 1 is also the Comparator Input B CIN2A bit P0.2 ; P0, bit 2 is also the Comparator Input A CIN1B bit P0.3 ; P0, bit 3 is also the Comparator Input B CIN1A bit P0.4 ; P0, bit 4 is also the Comparator Input A CMPREF bit P0.5 ; P0, bit 5 is also the Comparator Reference Input CMP1O bit P0.6 ; P0, bit 6 is also the Comparator 1 Output T1 bit P0.7 ; P0, bit 7 is also the Timer 1 Count Input/Toggle Output P0M1 data 084h ; P0 Mode Register 1 P0M2 data 085h ; P0 Mode Register 2 P1 data 090h ; Port 1 TxD bit P1.0 ; P1, bit 0 is also the UART Transmitter Output RxD bit P1.1 ; P1, bit 1 is also the UART Receiver Input T0 bit P1.2 ; P1, bit 2 is also the Timer 0 Input/Output SCL bit P1.2 ; P1, bit 2 is also the I2C Bus Clock Line SDA bit P1.3 ; P1, bit 3 is also the I2C Bus Data Line INT0 bit P1.3 ; P1, bit 3 is also External Interrupt 0 INT1 bit P1.4 ; P1, bit 4 is also External Interrupt 1 RST bit P1.5 ; P1, bit 5 is also the Reset Pin ; P1.6 and P1.7 have no alternate function P1M1 data 091h ; P1 Mode Register 1 P1M2 data 092h ; P1 Mode Register 2 P2 data 0A0h ; Port 2 X2 bit P2.0 ; P2, bit 0 is also the X2 Pin CLKOUT bit P2.0 ; P2, bit 0 is also the CLKOUT Pin X1 bit P2.1 ; P2, bit 1 is also the X1 Pin P2M1 data 0A4h ; P2 Mode Register 1 P2M2 data 0A5h ; P2 Mode Register 2 PCON data 087h ; Power Control PSW data 0D0h ; Program Status Word P bit PSW.0 ; Accumulator Parity Flag F1 bit PSW.1 ; Flag 1 OV bit PSW.2 ; Overflow Flag RS0 bit PSW.3 ; Register Bank Select 0 RS1 bit PSW.4 ; Register Bank Select 1 F0 bit PSW.5 ; Flag 0 AC bit PSW.6 ; Auxiliary Carry Flag CY bit PSW.7 ; Carry Flag PT0AD data 0F6h ; Port 0 digital Input Disable SCON data 098h ; Serial Port Control RI bit SCON.0 ; Receive Interrupt Flag TI bit SCON.1 ; Transmit Interrupt Flag RB8 bit SCON.2 ; Receive Bit 8 TB8 bit SCON.3 ; Transmit Bit 8 REN bit SCON.4 ; Receiver Enable SM2 bit SCON.5 ; Serial Mode Control Bit 2 SM1 bit SCON.6 ; Serial Mode Control Bit 1 SM0 bit SCON.7 ; Serial Mode Control Bit 0 SBUF data 099h ; Serial Port Buffer SADDR data 0A9h ; Serial Port Address SADEN data 0B9h ; Serial Port Address Enable SP data 081h ; Stack Pointer TCON data 088h ; Timer Control IT0 bit TCON.0 ; External Interrupt 0 Type IE0 bit TCON.1 ; External Interrupt 0 Edge Flag IT1 bit TCON.2 ; External Interrupt 1 Type IE1 bit TCON.3 ; External Interrupt 1 Edge Flag TR0 bit TCON.4 ; Timer 0 Run Control TF0 bit TCON.5 ; Timer 0 Overflow Flag TR1 bit TCON.6 ; Timer 1 Run Control TF1 bit TCON.7 ; Timer 1 Overflow Flag TH0 data 08Ch ; Timer 0 - High Byte TH1 data 08Dh ; Timer 1 - High Byte TL0 data 08Ah ; Timer 0 - Low Byte TL1 data 08Bh ; Timer 1 - Low Byte TMOD data 089h ; Timer 0 and 1 Mode WDCON data 0A7h ; Watchdog Control Register WDRST data 0A6h ; Watchdog Reset (Feed) Register ;Instruction cycle = 1us (12Mhz Quarz oder 6Mhz bei Teiler :6) ;Pinbelegung: ;P1.7 = Servo ;P1.6 = Servo ;P1.3 = ;P1.2 = Betriebs-LED ;P1.1 = Schaltausgang ;P1.0 = Schaltausgang ;P0.0 = Bremsfet ;P1.5 = 433MHz-Empfänger-Eingang ;P0.3 = Testpin ;P0.1 = Sanftanlaufschalter ;P0.2 = Spannungsüberwachung ;P0.4 = Servo ;P0.5 = Codierung Drehzahlregler ;P0.6 = Infrarot-Empfänger-Eingang ;P0.7 = Codierung Infrarotempfänger ;P1.4 = Servo ;Rambelegung STATUS DATA 020H ; TOGGLE BIT STATUS.0 VOLLGAS BIT STATUS.1 PARITY BIT STATUS.2 TASTER1 BIT STATUS.3 TASTER2 BIT STATUS.4 BATLEER BIT STATUS.5 MOTORAN BIT STATUS.6 INFRAROT BIT STATUS.7 KANAL0LOW DATA 021H KANAL0HIGH DATA 022H KANAL1LOW DATA 023H KANAL1HIGH DATA 024H KANAL2LOW DATA 025H KANAL2HIGH DATA 026H KANAL3LOW DATA 027H KANAL3HIGH DATA 028H BYTE1 DATA 029H BYTE2 DATA 02AH RESETREG DATA 02BH REG1 DATA 02CH SANFTANLAUF BIT REG1.0 RESET BIT REG1.1 REGLER BIT REG1.2 FREIGABE BIT REG1.3 BLINKZAEHLER DATA 02DH ;ASICHER DATA 02EH ACCUSAVE DATA 02FH KANALCOUNT DATA 030H TESTLOW DATA 031H TESTHIGH DATA 032H ADWERT DATA 033H ADRESSE DATA 034H KANALLOW DATA 035H KANALHIGH DATA 036H PULSLOWL DATA 037H PULSLOWH DATA 038H PULSHIGHL DATA 039H PULSHIGHH DATA 03AH SICHERL DATA 03BH SICHERH DATA 03CH ;SFR-Belegung: ; R0 Allgemeine Verwendung in Resetroutine und Hauptprogramm ; R1 Im Wartemodul verwendet ; R2 Hochlaufzähler für Softanlauf ; R3 Zähler in Timer0 Interrupt ; R4 Bitzähler ; R5 Batteriespannungsüberwachung ; R6 Hochlaufzähler für Softanlauf ; R7 Low Bat Zähler ;************************************************ ;* Initialisierung * ;************************************************ ORG 00H ; JMP START ; ORG 0BH ;Timer 0 Interrupt JMP TIMER0 ; ORG 01BH ;Timer 1 Interrupt JMP TIMER1 ; ORG 063H ;Komparator 1 Interrupt ; JMP KOMPINT ; ; ORG 100H ; ; START: CLR P1.0 ;Schaltausgänge auf Low CLR P1.1 ; CLR P0.1 ; CLR P0.0 ; MOV WDCON,#016H ;Watchdog konfigurieren MOV R0,#128 ;Alle 128 Bytes Ram loeschen CLR A ; LOOPCLR: MOV @R0,A ; DJNZ R0,LOOPCLR ; MOV PT0AD,#04H ;Disable digital input bei Komparator 2 ; ANL P0M2,#0FBH ;P02 als Eingang ORL P0M1,#04H ; MOV R7,#10 ;Entprellung der Spannungsüberwachung MOV CMP2,#028H ;Komparator 2 konfigurieren MOV TMOD,#011H ;Timer 0 16bit counter ;Timer 1 16bit counter SETB TR1 ;Timer1 starten SETB ET1 ;Timer1 Interrupt zulassen ORL P1M2,#0DBH ;P1.7, P1.6, P1.3, P1.4 P1.1, P1.0 als Push Pull konfigurieren ORL P0M2,#012H ;P0.1, P0.4 # JB P0.7,START3 ;IF Pin P0.7 = Low SETB INFRAROT ;THEN SBIT Infrarot ;ENDIF START3: JB P0.5,START4 ;IF Pin P0.5 = Low SETB REGLER ;THEN SBIT Regler ;ENDIF START4: MOV KANAL0LOW,#024H ;Defaultwerte für die Servos MOV KANAL0HIGH,#0FAH MOV KANAL1LOW,#024H MOV KANAL1HIGH,#0FAH MOV KANAL2LOW,#024H MOV KANAL2HIGH,#0FAH MOV KANAL3LOW,#024H MOV KANAL3HIGH,#0FAH SETB EA ;Generelle Interruptfreigabe CLR P1.2 ;Betriebs-LED einschalten MOV R1,#0 ;ca. 0.5s Verzögerungszeit, damit Spannung sich stabilisieren kann ACALL WARTE MOV R1,#0 ACALL WARTE ;************************************************ ;* Hauptprogramm * ;************************************************ LOOP: ACALL BATTERIE? ;Betriebsspannung überwachen CLR PARITY ;Paritybit löschen MOV R4,#13 ;Bitzähler MOV BYTE1,#0 ;Kommandobytes löschen MOV BYTE2,#0 ; # LOOP2: CLR P0.3 ;Testpin Low MOV WDRST,#01EH ;Watchdog füttern MOV WDRST,#0E1H ; ACALL BATTERIE? ;Batteriespannung OK? JNB INFRAROT,HIGHBIT ; LJMP INFRA ; HIGHBIT: JNB P1.5,LOOP2 ;Auf Highbit warten MOV R0,#0FFH ; LOW1: JNB P1.5,HIGH1 ; MOV A,#10 ;40us Warteschleife ACALL WAIT ; DJNZ R0,LOW1 ; JMP LOOP2 ; HIGH1: CJNE R0,#230,HIGH2 ;Länge der 1.Highphase > 1.3ms JMP HIGH3 TEST1: SETB P0.3 JMP LOOP2 HIGH2: JNC LOOP2 ; HIGH3: CJNE R0,#190,HIGH4 ;<2.7ms? JMP HIGH5 ; HIGH4: JC TEST1 ; ;Ab jetzt 1.Highphase für gültig erklärt HIGH5: MOV R0,#0FFH ; HIGH6: JB P1.5,HIGH7 ; MOV A,#10 ;40us Warteschleife ACALL WAIT ; DJNZ R0,HIGH6 ; HIGH10: SJMP LOOP ; HIGH7: CJNE R0,#230,HIGH8 ; JMP HIGH9 ; HIGH8: JNC HIGH10 ; HIGH9: CJNE R0,#180,HIGH11 ; JMP HIGH12 ; HIGH11: JC HIGH10 ; ;Ab jetzt ist das Startbit erkannt HIGH12: MOV R0,#0FFH ; HIGH13: JNB P1.5,PULSL ;Ausmessen der Highphase der Bits (0.5ms Soll) DJNZ R0,HIGH13 ; SJMP HIGH10 ; TEST: SETB P0.3 NOP TESE: SJMP HIGH10 PULSL: CJNE R0,#0B0H,PULSL2 ; JMP PULSL1 ; PULSL2: JC PULSL1 MOV A,#25 ACALL WAIT JNB P1.5,TEST MOV A,R0 CLR C SUBB A,#10 MOV R0,A JMP HIGH13 ; PULSL1: CJNE R0,#050H,PULSL3 ; JMP PULSH ; PULSL3: ;JC TEST ; ;Ab jetzt ist die Highphase des Bits erkannt PULSH: MOV R0,#0FFH ; PULSH1: JB P1.5,PULSHCHECK ; ; NOP ; NOP ; DJNZ R0,PULSH1 ; SJMP TEST ; PULSHCHECK: CJNE R0,#0D0H,PU2 ;Überprüfung auf Mindestdauer der Lowphase des Bits (Soll: 0.5ms...1ms) JMP PU1 ; PU2: JC PU1 ; MOV A,#25 ;Unterdrückung von Spikes < 100us wenn Lowphase zu kurz ACALL WAIT ; JB P1.5,TEST ; MOV A,R0 ; CLR C ; SUBB A,#10 ; MOV R0,A ; JMP PULSH1 ; PU1: CJNE R0,#090H,PULSH4 ; JMP EINSBIT ; PULSH4: JNC NULLBIT ; EINSBIT: SETB C ; JMP EINREIH ; NULLBIT: CLR C ; EINREIH: MOV A,BYTE1 ;Bitwert (Carry) in Byte1 und Byte2 durch Rotation einschreiben RRC A ; MOV BYTE1,A ; MOV A,BYTE2 ; RRC A ; MOV BYTE2,A ; DJNZ R4,HIGH12 ;und das nächste Bit einlesen ;Ab jetzt sind alle Informationen eingelesen JNB BYTE1.7,NOPAR ; SETB PARITY ; NOPAR: LJMP PARITYRECHNUNG ;Parity überprüfen ;Ab hier ist das Telegramm für gültig befunden PARIBACK: JB BYTE1.6,TASTE1 ;Schaltausgänge bedienen CLR P1.0 ; JB REGLER,TASTE2 ; ACALL SOFTAUS ; JMP TASTE2 ; TASTE1: SETB P1.0 ; JB REGLER,TASTE2 ; ACALL SOFTAN ; TASTE2: JB BYTE1.5,TASTE2A ; CLR P1.1 ; JMP ADR? ; TASTE2A: SETB P1.1 ; ;Ab jetzt wird die Adresseninfo ausgewertet und den Servos der entspr. Wert zugewiesen ADR?: MOV A,#0 ;Adressbyte zunächst löschen JNB BYTE2.3,ADR1 SETB ACC.0 ADR1: JNB BYTE2.4,ADR2 SETB ACC.1 ADR2: MOV ADRESSE,A MOV R4,#5 ;Servobefehl extrahieren aus Telegramm REIH: CLR C MOV A,BYTE1 RRC A MOV BYTE1,A MOV A,BYTE2 RRC A MOV BYTE2,A DJNZ R4,REIH MOV ADWERT,BYTE2 ACALL UMWANDELN MOV A,ADRESSE CLR ET1 CJNE A,#0,AD1 MOV KANAL0LOW,KANALLOW MOV KANAL0HIGH,KANALHIGH SETB RESETREG.0 JMP ADX AD1: CJNE A,#1,AD2 MOV KANAL1LOW,KANALLOW MOV KANAL1HIGH,KANALHIGH SETB RESETREG.1 JMP ADX AD2: CJNE A,#2,AD3 MOV KANAL2LOW,KANALLOW MOV KANAL2HIGH,KANALHIGH SETB RESETREG.2 JMP ADX AD3: MOV KANAL3LOW,KANALLOW MOV KANAL3HIGH,KANALHIGH SETB RESETREG.3 ADX: SETB ET1 ACALL REGLA ; LJMP LOOP ; ;************************************************ ;* Spannungsüberwachung * ;************************************************ ;Unterspannung muß 10x hintereinander detektiert werden BATTERIE?: MOV A,CMP2 ; JB ACC.1,ACCUE ;IF NOT Bit CO2 (Komparatorergebnis) DJNZ R7,ACCUU SETB BATLEER ;THEN Bit Batleer setzen ;ENDIF ACCUE: MOV R7,#10 ACCUU: RET ;************************************************ ;* Empfangsroutine für Infrarotempfang * ;************************************************ ;Ausgang des Infrarotempfängers ist entgegengesetzt der Polarität des Funkempfängers! ILOOP2: LJMP LOOP2 INFRA: JB P0.6,ILOOP2 ;Auf Highbit warten MOV R0,#0FFH ; ILOW1: JB P0.6,IHIGH1 ; MOV A,#10 ;40us Warteschleife ACALL WAIT ; DJNZ R0,ILOW1 ; JMP ILOOP2 ; IHIGH1: CJNE R0,#230,IHIGH2 ;Länge der 1.Highphase > 1.3ms JMP IHIGH3 IHIGH2: JNC ILOOP2 ; IHIGH3: CJNE R0,#190,IHIGH4 ;<2.7ms? JMP IHIGH5 ; IHIGH4: JC ILOOP2 ; ;Ab jetzt 1.Highphase für gültig erklärt IHIGH5: MOV R0,#0FFH ; IHIGH6: JNB P0.6,IHIGH7 ; MOV A,#10 ;40us Warteschleife ACALL WAIT ; DJNZ R0,IHIGH6 ; IHIGH10: LJMP LOOP ; IHIGH7: CJNE R0,#230,IHIGH8 ; JMP IHIGH9 ; IHIGH8: JNC ITEST ; IHIGH9: CJNE R0,#180,IHIGH11 ; JMP IHIGH12 ; IHIGH11: JC ITEST ; ;Ab jetzt ist das Startbit erkannt IHIGH12: MOV R0,#0FFH ; IHIGH13: JB P0.6,IPULSL ;Ausmessen der Highphase der Bits (0.5ms Soll) DJNZ R0,IHIGH13 ; SJMP IHIGH10 ; ITEST: SETB P0.3 ITESE: SJMP IHIGH10 IPULSL: CJNE R0,#0C0H,IPULSL2 ; JMP IPULSL1 ; IPULSL2: JNC ITEST ; IPULSL1: CJNE R0,#050H,IPULSL3 ; JMP IPULSH ; IPULSL3:; JC ITEST ; ;Ab jetzt ist die Highphase des Bits erkannt IPULSH: MOV R0,#0FFH ; IPULSH1: JNB P0.6,IPULSHCHECK ; NOP ; NOP ; DJNZ R0,IPULSH1 ; SJMP ITEST ; IPULSHCHECK:CJNE R0,#0D0H,IPU2 ;Überprüfung auf Mindestdauer der Lowphase des Bits (Soll: 0.5ms...1ms) JMP IPU1 ; IPU2: JC IPU1 ; MOV A,#25 ;Unterdrückung von Spikes < 100us wenn Lowphase zu kurz ACALL WAIT ; JNB P0.6,ITEST ; MOV A,R0 ; CLR C ; SUBB A,#10 ; MOV R0,A ; JMP IPULSH1 ; IPU1: CJNE R0,#090H,IPULSH4 ; JMP IEINSBIT ; IPULSH4: JNC INULLBIT ; IEINSBIT: SETB C ; JMP IEINREIH ; INULLBIT: CLR C ; IEINREIH: MOV A,BYTE1 ;Bitwert (Carry) in Byte1 und Byte2 durch Rotation einschreiben RRC A ; MOV BYTE1,A ; MOV A,BYTE2 ; RRC A ; MOV BYTE2,A ; DJNZ R4,IHIGH12 ;und das nächste Bit einlesen ;Ab jetzt sind alle Informationen eingelesen JNB BYTE1.7,INOPAR ; SETB PARITY ; INOPAR: SJMP PARITYRECHNUNG ;Parity überprüfen ;Ab hier ist das Telegramm für gültig befunden ;************************************************ ;* Parityberechnung * ;************************************************ ;Das Paritybit ergänzt die Anzahl der Bits zu einer geraden Summe PARITYRECHNUNG: MOV A,#0 JNB BYTE1.6,PA1 ADD A,#1 PA1: JNB BYTE1.5,PA2 ADD A,#1 PA2: JNB BYTE1.4,PA3 ADD A,#1 PA3: JNB BYTE1.3,PA4 ADD A,#1 PA4: JNB BYTE1.2,PA5 ADD A,#1 PA5: JNB BYTE1.1,PA6 ADD A,#1 PA6: JNB BYTE1.0,PA7 ADD A,#1 PA7: JNB BYTE2.7,PA8 ADD A,#1 PA8: JNB BYTE2.6,PA9 ADD A,#1 PA9: JNB BYTE2.5,PA10 ADD A,#1 PA10: JNB BYTE2.4,PA11 ADD A,#1 PA11: JNB BYTE2.3,PA12 ADD A,#1 PA12: JB ACC.0,PARI JB PARITY,PAERROR PARI1: LJMP PARIBACK PARI: JB PARITY,PARI1 PAERROR: LJMP TEST ;Parityfehler ;************************************************ ;* 10ms Warteschleife * ;************************************************ WARTEN10: MOV R1,#10 ;10ms warten WARTE: ; LOOP22: MOV A,#250 ; ACALL WAIT ; DJNZ R1,LOOP22 ; RET ;************************************************ ;* Warteschleife * ;************************************************ ;Zeit = Accu * 4us WAIT: NOP NOP DJNZ ACC,WAIT RET ;************************************************ ;* Umwandeln des AD-Wertes in Timerwert * ;************************************************ ;Formel: Servowert = ADWERT x 4 + 1000(3E8H) UMWANDELN: MOV A,ADWERT MOV B,#4 MUL AB ADD A,#0E8H MOV KANALLOW,A MOV SICHERL,A MOV A,B ADDC A,#3 MOV KANALHIGH,A MOV SICHERH,A MOV A,#0 ; CLR C ; SUBB A,KANALLOW ; MOV KANALLOW,A ; MOV A,#0 ; SUBB A,KANALHIGH ; MOV KANALHIGH,A ; RET ;************************************************ ;* Timer 1 Interrupt * ;************************************************ ;Wird für die PWM-Generierung benötigt ;Die servos werden erst dann angesteuert, wenn ein Befehl für das jeweilige Sevo eingetroffen ist. TIMER1: PUSH PSW ; MOV ACCUSAVE,A ;Akkuinhalt retten CLR TR1 ;Timer stoppen CLR P1.7 ;Servoausgänge abschalten CLR P1.6 ; CLR P0.4 ; CLR P1.4 ; MOV A,KANALCOUNT ;IF Kanalcount = 0 CJNE A,#0,TIM2 ; MOV TL1,KANAL0LOW ;THEN Timerwert einladen MOV TH1,KANAL0HIGH ; JNB RESETREG.0,TIMADD ; SETB P1.7 ; P1.7 = High JMP TIMADD ; TIM2: CJNE A,#1,TIM3 ;ELSE IF Kanalcount = 1 MOV TL1,KANAL1LOW ; THEN Timerwert einladen MOV TH1,KANAL1HIGH ; JNB RESETREG.1,TIMADD ; SETB P1.6 ; P1.6 = High JMP TIMADD ; TIM3: CJNE A,#2,TIM4 ; ELSE IF Kanalcount = 2 MOV TL1,KANAL2LOW ; THEN Timerwert einladen MOV TH1,KANAL2HIGH ; JNB RESETREG.2,TIMADD ; SETB P0.4 ; P0.4 = High JMP TIMADD ; TIM4: CJNE A,#3,TIMADD MOV TL1,KANAL3LOW ; ELSE Timerwert einladen MOV TH1,KANAL3HIGH ; JNB RESETREG.3,TIMADD ; SETB P1.4 ; P1.4 = High JMP TIMADD ; ; ENDIF ; ENDIF ;ENDIF TIMADD: MOV A,KANALCOUNT ;Kanalcount = Kanalcount + 1 ADD A,#1 ; MOV KANALCOUNT,A ; CJNE A,#5,TIME ;IF Kanalcount = 4 MOV KANALCOUNT,#0 ;THEN Kanalcount = 0 MOV TL1,#0BCH ; 18ms Wartephase in Timer einladen MOV TH1,#0B7H ; JNB BATLEER,TIME ; IF Bit Batleer MOV A,BLINKZAEHLER ; THEN Blinkzaehler = Blinkzaehler + 1 ADD A,#1 ; CJNE A,#20,TIM5 ; IF Blinkzaehler = 20 MOV BLINKZAEHLER,#0 ; THEN Blinkzaehler = 0 JNB P1.2,TIM6 ; IF LED = aus CLR P1.2 ; THEN Schalte LED an JMP TIME ; TIM6: SETB P1.2 ; ELSE Schalte LED aus JMP TIME ; ENDIF ; ENDIF TIM5: MOV BLINKZAEHLER,A ; TIME: ;ENDIF SETB TR1 ;Timer anschalten MOV A,ACCUSAVE ; POP PSW RETI ;************************************************ ;* Softanlaufschalter * ;************************************************ SOFTAN: JB SANFTANLAUF,SOFE ;IF NOT Bit Sanftanlauf SETB SANFTANLAUF ;THEN SBIT Sanftanlauf CLR P0.0 ; Bremsfet vorsorglich aus MOV TL0,#06H ; Timer und Reloadregister für 2KHz vorbelegen MOV TH0,#0FFH ; MOV PULSLOWL,#06H ; MOV PULSLOWH,#0FFH ; MOV PULSHIGHL,#06H ; MOV PULSHIGHH,#0FFH ; MOV R2,#100 ; Hochlaufzähler für 1s Hochlaufphase MOV R6,#40 ; SETB ET0 ; Timer 0 Interrupt enable SETB TR0 ; Timer 0 anschalten SETB MOTORAN ; SBIT Motoran JMP SOFE ; ;ENDIF ;************************************************************************* SOFTAUS: JNB MOTORAN,SOFE ;IF Bit Motoran CLR SANFTANLAUF ;THEN RBIT Sanftanlauf CLR ET0 ; Timer 0 Interrupt disable CLR TR0 ; Timer 0 ausschalten CLR P0.1 ; P0.1 = Low CLR MOTORAN ; RBIT Motoran CLR VOLLGAS ; RBIT Vollgas SETB P0.0 ; Bremsfet anschalten SOFE: RET ;ENDIF ;************************************************ ;* Hochlaufphase für Sanftanlauf * ;************************************************ HOCHLAUF: CLR C ;THEN DO UNTIL R2 = 0 MOV A,PULSHIGHL ; Highphase des Pulses verlängern SUBB A,#2 ; MOV PULSHIGHL,A ; MOV A,PULSHIGHH ; SUBB A,#0 ; MOV PULSHIGHH,A ; MOV A,PULSLOWL ; Lowphase des Pulses verkürzen ADD A,#2 ; MOV PULSLOWL,A ; MOV A,PULSLOWH ; ADDC A,#0 ; MOV PULSLOWH,A ; DJNZ R2,HOCHE ; CLR ET0 ; Timer 0 Interrupt disable CLR TR0 ; Timer 0 ausschalten SETB P0.1 ; P0.1 = High HOCHE: RET ; ;************************************************ ;* Timer 0 Interrupt * ;************************************************ TIMER0: PUSH PSW ; MOV ACCUSAVE,A ; CLR TR0 ;Timer 0 anhalten JNB TOGGLE,TIME01 ;IF Bit Toggle(0),Status CLR TOGGLE ;THEN RBIT Toggle(0),Status CLR P0.1 ; Pin P0.1 Low MOV TL0,PULSLOWL ; Lange Lowphase MOV TH0,PULSLOWH ; SJMP TIME0E ; TIME01: SETB TOGGLE ;ELSE SBIT Toggle(0),Status SETB P0.1 ; Pin P0.1 High MOV TL0,PULSHIGHL ; Kurze Highphase MOV TH0,PULSHIGHH ; ;ENDIF TIME0E: SETB TR0 ;Timer 0 anschalten JB REGLER,TM1 ;IF NOT Bit Regler DJNZ R6,TM1 ; MOV R6,#40 ; ACALL HOCHLAUF ;THEN CALL 'Hochlauf' TM1: MOV A,ACCUSAVE ;ENDIF POP PSW ; RETI ; ;************************************************ ;* Codierung = Drehzahlregler * ;************************************************ REGLA: JNB REGLER,REGLA2 ;IF Bit Regler MOV A,ADRESSE ;THEN IF Adresse = 0 CJNE A,#0,REGLA2 ; MOV A,ADWERT ; THEN IF Adwert > 8DH CJNE A,#08DH,REGLA1 ; JMP REGLAGO ; REGLA2: SJMP REGE ; REGLA1: JC REGAUS ; REGLAGO: CJNE A,#0EAH,REGLA3 ; THEN IF Adwert > EAH JMP VOLLGA ; REGLA3: JC REGEIN1 ; VOLLGA: JB VOLLGAS,REGE ; THEN IF NOT Bit Vollgas CLR ET0 ; THEN Timer 0 Interrupt disable CLR P0.0 ; Bremsfet vorsorglich ausschalten CLR TR0 ; Timer 0 ausschalten SETB P0.1 ; P0.1 = High (Vollgas ohne PWM) SETB VOLLGAS ; SBIT Vollgas RET ; ENFIF REGEIN1: MOV A,#0F4H ; ELSE PWM berechnen: CLR C ; Zuerst die Lowphase: SUBB A,SICHERL ; 2036 - Meßwert = Differenz MOV TESTLOW,A ; MOV A,#7 ; SUBB A,SICHERH ; MOV TESTHIGH,A ; CLR ET0 ; (Ab hier muß Timerinterrupt gesperrt werden) ; MOV A,#0 ; 0 - Differenz = Timerwert (Weil Timer hochzählt und beim Überlauf FFFF -> 0 einen Interrupt generiert CLR C ; SUBB A,TESTLOW ; MOV PULSLOWL,A ; MOV A,#0 ; SUBB A,TESTHIGH ; MOV PULSLOWH,A ; ; MOV A,#0F4H ; Jetzt die Highphase: CLR C ; SUBB A,TESTLOW ; 500 - Differenz = PWMHighphase MOV TESTLOW,A ; MOV A,#1 ; SUBB A,TESTHIGH ; MOV TESTHIGH,A ; ; ; MOV A,#032H ; 50 + Differenz = PWMHighphase ; ADD A,TESTLOW ; ; MOV TESTLOW,A ; ; MOV A,TESTHIGH ; ; ADDC A,#0 ; ; MOV TESTHIGH,A ; ; MOV A,#0 ; 0 - PWMHighphase = Timerwert CLR C ; SUBB A,TESTLOW ; MOV PULSHIGHL,A ; MOV A,#0 ; SUBB A,TESTHIGH ; MOV PULSHIGHH,A ; CLR P0.0 ; Bremsfet vorsorglich aus SETB ET0 ; Timer 0 Interrupt enable SETB TR0 ; Timer 0 anschalten SETB MOTORAN ; SBIT Motoran ; ENDIF JMP LEERTEST ; ENDIF REGAUS: CLR ET0 ; ELSE Timer 0 Interrupt disable CLR TR0 ; Timer 0 ausschalten CLR P0.1 ; P0.1 = Low CLR MOTORAN ; RBIT Motoran CJNE A,#060H,BRE1 ; IF Adwert <61H BREMSEAN: SETB P0.0 ; THEN Bremsfet an JMP REGCLEAR ; BRE1: JNC BREMSEAUS ; ELSE Bremsfet aus JMP BREMSEAN ; BREMSEAUS: CLR P0.0 ; ENDIF LEERTEST: ; RBIT Vollgas REGCLEAR: ; CLR VOLLGAS ; ; ENDIF REGE: RET ;ENDIF END