;**************************************************************** ;* * ;* TNC2Q PIC 3A3 1998-07-27 * ;* * ;* PIC16C54-HS zur Steuerung des AFSK-Teils, zur * ;* zur Umschaltung FSK/AFSK und zur Steuerung des * ;* externen Modems. * ;* * ;* Taktfrequenz: 9.8304 MHz * ;* Befehlszyklus: 406.901 ns * ;* * ;**************************************************************** PROCESSOR 16C54 __IDLOCS 0x3A03 ;---------------------------------------------------------------- ; PIC-Register ;---------------------------------------------------------------- ;Register F0 equ 0 ;Indirekter Zugriff RTCC equ 1 ;RTCC, Zähler für externen Takt Status equ 3 ;Statusregister F4 equ 4 ;Adresse für indirekten Zugriff PortA equ 5 ;Adresse Port A PortB equ 6 ;Adresse Port B ;Bits im Statusregister Stat_C equ 0 ;C-Flag Stat_DC equ 1 ;DC-Flag Stat_Z equ 2 ;Z-Flag ;---------------------------------------------------------------- ; I/O-Pins ;---------------------------------------------------------------- ;Datenrichtung der Ports DirA equ 0x0F ;I/O-Maske Port A, Ruhezustand DirB equ 0xB3 ;I/O-Maske Port B, Ruhezustand ;Bits für Port A IO_DATA equ 0 ;Ein-/Ausgangsbit für Daten vom/zum FSK-PIC IO_TXCA equ 1 ;Ein-/Ausgangsbit für TXCA I_EXTERN equ 2 ;Eingangsbit für Auswahl externes Modem IO_DCD equ 3 ;OC-Ausgangsbit für DCD bei externem Modem ;Bits für Port B I_PTT equ 0 ;Eingangsbit für PTT I_TXDA equ 1 ;Eingangsbit für Sendedaten von SIO O_TXDTCM equ 2 ;Ausgangsbit für Sendedaten an TCM3105 O_RXDA equ 3 ;Ausgangsbit für Empfangsdaten an SIO I_CLK equ 4 ;Eingangsbit für Takt vom FSK-PIC I_RXDTCM equ 5 ;Eingangsbit für Empfangsdaten vom TCM3105 O_RXCA equ 6 ;Ausgangsbit für RXCA I_FSKAFSK equ 7 ;Eingangsbit für Schalter FSK/AFSK ;---------------------------------------------------------------- ; Sonstiges ;---------------------------------------------------------------- ;Sonstige Konstanten TioFSKCLK_TX equ 40 ;Timeout für FSK_CLK (TX) TioFSKCLK_RX equ 22 ;Timeout für FSK_CLK (RX) Tio13 equ 7 ;Timeout 13µs ;---------------------------------------------------------------- ; Allgemein verwendete File-Register ;---------------------------------------------------------------- ;Allgemeine Register LastPB equ 0x10 ;Letzter Zustand Port B LastPA equ 0x11 ;Letzter Zustand Port A LastTakt equ 0x12 ;Letzter Zählerstand RTCC AktTakt equ 0x13 ;RX-Takt LastRX equ 0x14 ;Zuletzt eingelesenes RX-Bit Temp equ 0x17 ;Als Zwischenspeicher ;---------------------------------------------------------------- ; AFSK ;---------------------------------------------------------------- ;PLL für Abtastzeitpunkt-Verschiebung AFSK_PLL equ 0x18 ;8 Bytes ;Nachstellwerte für PLL APLL0 equ 0 APLL1 equ 0 APLL2 equ 1 APLL3 equ 2 APLL4 equ 3 APLL5 equ 6 APLL6 equ 7 APLL7 equ 0 ;---------------------------------------------------------------- ; Externes Modem ;---------------------------------------------------------------- DCDCnt equ 0x15 ;DCD-Zähler Flags equ 0x11 ;Flags. ;0: 0=DCD aktiv, 1=DCD inaktiv ;Konstanten für DCD MinDCD equ 20 ;Minimal zulässiger Zählerstand DCD MaxDCD equ 60 ;Maximal zulässiger Zählerstand DCD OnDCD equ 45 ;Schaltschwelle DCD EIN OffDCD equ 25 ;Schaltschwelle DCD AUS DCDINC_0 equ -1 ;Inkrement in Phase 0, keine Flanke DCDINC_1 equ 0 ;Inkrement in Phase 1, keine Flanke DCDINC_2 equ 0 ;Inkrement in Phase 2, keine Flanke DCDINC_3 equ 0 ;Inkrement in Phase 3, keine Flanke DCDINC_4 equ 0 ;Inkrement in Phase 4, keine Flanke DCDINC_5 equ 0 ;Inkrement in Phase 5, keine Flanke DCDINC_6 equ 0 ;Inkrement in Phase 6, keine Flanke DCDINC_7 equ 0 ;Inkrement in Phase 7, keine Flanke DCDINC_0F equ 11 ;Inkrement in Phase 0, mit Flanke DCDINC_1F equ -1 ;Inkrement in Phase 1, mit Flanke DCDINC_2F equ -2 ;Inkrement in Phase 2, mit Flanke DCDINC_3F equ -2 ;Inkrement in Phase 3, mit Flanke DCDINC_4F equ -2 ;Inkrement in Phase 4, mit Flanke DCDINC_5F equ -2 ;Inkrement in Phase 5, mit Flanke DCDINC_6F equ -2 ;Inkrement in Phase 6, mit Flanke DCDINC_7F equ -1 ;Inkrement in Phase 7, mit Flanke ;---------------------------------------------------------------- ; FSK ;---------------------------------------------------------------- ;**************************************************************** ;* Initialisierung nach RESET * ;**************************************************************** Reset: ;Ausgangsregister vorbesetzen movlw B'00000000' movwf PortA movlw B'01000000' movwf PortB ;Port-Pins als Ein- und Ausgang definieren movlw DirA tris PortA movlw DirB tris PortB ;OPTION-Register einstellen movlw 0x28 ;RTCC mit externer 0-1-Flanke takten, ;keinen Vorteiler verwenden option ;**************************************************************** ;* Verzweiger zu Beginn der Hauptschleife * ;**************************************************************** mn_loop ;Unterscheiden ob internes oder externes Modem aktiv ist btfss PortA, I_EXTERN goto StartEXTERN ;Unterscheiden ob FSK- oder AFSK-Betrieb läuft. btfss PortB, I_FSKAFSK goto StartFSK ;**************************************************************** ;* Eintritt in AFSK-Betriebsart, internes Modem * ;**************************************************************** StartAFSK: ;Verzweigen je nach Zustand der PTT btfss PortB, I_PTT goto ATInit ;**************************************************************** ;* AFSK-Empfang, internes Modem * ;**************************************************************** ;---------------------------------------------------------------- ; ARInit ; Initialisierung des AFSK-Empfängers. ;---------------------------------------------------------------- ARInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;PLL initialisieren movlw APLL0 movwf AFSK_PLL+0 movlw APLL1 movwf AFSK_PLL+1 movlw APLL2 movwf AFSK_PLL+2 movlw APLL3 movwf AFSK_PLL+3 movlw APLL4 movwf AFSK_PLL+4 movlw APLL5 movwf AFSK_PLL+5 movlw APLL6 movwf AFSK_PLL+6 movlw APLL7 movwf AFSK_PLL+7 ;Sonstige Initialisierungen movf RTCC,w movwf LastTakt movf PortB,w movwf LastPB clrf AktTakt clrf LastRX ;---------------------------------------------------------------- ; Schleife AFSK-Empfänger ;---------------------------------------------------------------- RX_A0: ;Warten auf nächsten Takt movf RTCC,w movwf Temp xorwf LastTakt,w btfsc Status, Stat_Z goto RX_A0 movf Temp,w movwf LastTakt ;Interner Taktzähler++ incf AktTakt,f ;Flanke am Eingangs-Signal? movf PortB,w movwf Temp xorwf LastPB,w andlw 1 << I_RXDTCM btfsc Status, Stat_Z goto RX_A2 ;Abtastzeitpunkt verschieben movlw 7 andwf AktTakt,f movlw AFSK_PLL addwf AktTakt,w movwf F4 movf F0,w movwf AktTakt RX_A2: movf Temp,w movwf LastPB ;RX-Signal abtasten ? movf AktTakt,w andlw 7 xorlw 4 btfss Status, Stat_Z goto RX_A1 ;RX-Bit lesen und NRZI-NRZ-Wandlung durchführen movf Temp,w xorwf LastRX,f movf PortB,w andlw 0xFF - (1 << O_RXDA) btfss LastRX, I_RXDTCM iorlw 1 << O_RXDA movwf PortB movf Temp,w movwf LastRX RX_A1: ;Taktsignal ausgeben movf PortB,w andlw 0xFF - (1 << O_RXCA) btfss AktTakt,2 iorlw 1 << O_RXCA movwf PortB ;Auch den TX-Takt ausgeben... movlw DirA btfss AktTakt,2 andlw 0xFF - (1 << IO_TXCA) tris PortA ;Watchdog nachtriggern clrwdt ;Weiter solange die Betriebsart AFSK-RX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfss PortB, I_PTT goto mn_loop btfss PortB, I_FSKAFSK goto mn_loop btfss PortA, I_EXTERN goto mn_loop goto RX_A0 ;**************************************************************** ;* AFSK-Sendung, internes Modem * ;**************************************************************** ;---------------------------------------------------------------- ; ATInit ; Initialisierung des AFSK-Senders ;---------------------------------------------------------------- ATInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;---------------------------------------------------------------- ; Schleife AFSK-Sender ;---------------------------------------------------------------- TX_A0: ;Warten auf Takt 0 movlw 7 andwf RTCC,w btfss Status, Stat_Z goto TX_A0 ;Inaktive Flanke an TXCA ausgeben movlw DirA | (1 << IO_TXCA) tris PortA ;Wenn aktuelles TX-Bit == 0, dann Ausgangsbit ;an den TCM invertieren btfsc PortB, I_TXDA goto TX_A1 movf PortB,w xorlw 1 << O_TXDTCM movwf PortB TX_A1: ;Warten auf Takt 4 movlw 7 andwf RTCC,w xorlw 4 btfss Status, Stat_Z goto TX_A1 ;Aktive Flanke an TXCA ausgeben movlw DirA & (0xFF - (1 << IO_TXCA)) tris PortA ;Watchdog nachtriggern clrwdt ;Weiter solange die Betriebsart AFSK-TX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfsc PortB, I_PTT goto mn_loop btfss PortB, I_FSKAFSK goto mn_loop btfss PortA, I_EXTERN goto mn_loop goto TX_A0 ;**************************************************************** ;* Eintritt in Betriebsart externes Modem * ;**************************************************************** StartEXTERN: ;Verzweigen je nach Zustand der PTT btfss PortB, I_PTT goto ETInit ;**************************************************************** ;* Empfang, externes Modem * ;**************************************************************** ;---------------------------------------------------------------- ; ERInit ; Initialisierung des Empfängers. ;---------------------------------------------------------------- ERInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;Sonstige Initialisierungen movf RTCC,w movwf LastTakt movf PortB,w movwf LastPB clrf AktTakt clrf LastRX bsf Flags,0 movlw MinDCD movwf DCDCnt ;---------------------------------------------------------------- ; Schleife externer Empfänger ;---------------------------------------------------------------- ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 0 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E0a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E0a clrf RTCC RX_E0z: ;Inaktive Flanke des Taktsignals ausgeben bsf PortB, O_RXCA ;Inkrement des DCD-Zählers holen ;(für den Fall: Keine Flanke) movlw DCDINC_0 addwf DCDCnt,f ;Flanke am Eingangs-Signal? ;(Nur steigende Flanken auswerten. Dadurch kann die ;fallende Flanke des Signals ruhig etwas von der ;Sollposition abweichen...) movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E0b btfsc LastPB, I_RXDTCM goto RX_E0b ;Flanke erkannt. DCD-Inkrement setzen movlw DCDINC_0F - DCDINC_0 addwf DCDCnt,f RX_E0b: movf Temp,w movwf LastPB ;DCD-Zustand nach außen melden movlw DirA - (1 << IO_DCD) btfsc Flags,0 iorlw 1 << IO_DCD tris PortA ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 1 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E1a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E1a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E1b btfsc LastPB, I_RXDTCM goto RX_E1b ;Korrektur DCD-Zähler movlw DCDINC_1F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt einschieben) RX_E1c: btfss RTCC,0 goto RX_E1c clrf RTCC RX_E1b: movf Temp,w movwf LastPB ;DCD-Zähler nach unten begrenzen movlw MinDCD subwf DCDCnt,w btfss Status, Stat_C subwf DCDCnt,f ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 2 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E2a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E2a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E2b btfsc LastPB, I_RXDTCM goto RX_E2b ;Korrektur DCD-Zähler movlw DCDINC_2F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt einschieben) RX_E2c: btfss RTCC,0 goto RX_E2c clrf RTCC RX_E2b: movf Temp,w movwf LastPB ;DCD-Zähler nach oben begrenzen movlw MaxDCD subwf DCDCnt,w btfsc Status, Stat_C subwf DCDCnt,f ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 3 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E3a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E3a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E3b btfsc LastPB, I_RXDTCM goto RX_E3b ;Korrektur DCD-Zähler movlw DCDINC_3F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt einschieben) RX_E3c: btfss RTCC,0 goto RX_E3c clrf RTCC RX_E3b: movf Temp,w movwf LastPB ;DCD einschalten ? btfss Flags,0 goto RX_E3d movlw OnDCD subwf DCDCnt,w btfsc Status, Stat_C ;DCD aktiv bcf Flags,0 RX_E3d: ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 4 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E4a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E4a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E4b btfsc LastPB, I_RXDTCM goto RX_E4b ;Korrektur DCD-Zähler movlw DCDINC_4F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt einschieben) RX_E4c: btfss RTCC,0 goto RX_E4c clrf RTCC RX_E4b: movf Temp,w movwf LastPB ;RX-Signal abtasten und gewandeltes Signal an SIO ;ausgeben xorwf LastRX,f andlw 0xFF - (1 << O_RXDA) btfss LastRX, I_RXDTCM iorlw 1 << O_RXDA movwf PortB movf Temp,w movwf LastRX ;Aktive Flanke des Taktsignals ausgeben. ;(Ist zwar etwas knapp nach Anlegen des Datenbits, ;aber es reicht. Hat so aber Vorteile, falls der PIC ;nur zur Takt-, nicht aber zur Daten-Rückgewinnung ;verwendet wird.) bcf PortB, O_RXCA ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 5 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E5a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E5a clrf RTCC ;Watchdog nachtriggern clrwdt ;DCD ausschalten ? btfsc Flags,0 goto RX_E5d movlw OffDCD subwf DCDCnt,w btfss Status, Stat_C ;DCD inaktiv bsf Flags,0 RX_E5d: ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E5b btfsc LastPB, I_RXDTCM goto RX_E5b ;Korrektur DCD-Zähler movlw DCDINC_5F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt überspringen) movf Temp,w movwf LastPB goto RX_E7a RX_E5b: movf Temp,w movwf LastPB ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 6 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E6a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E6a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E6b btfsc LastPB, I_RXDTCM goto RX_E6b ;Korrektur DCD-Zähler movlw DCDINC_6F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt überspringen) movf Temp,w movwf LastPB goto RX_E7x RX_E6b: movf Temp,w movwf LastPB ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Phase 7 ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RX_E7a: ;Warten auf nächsten Takt btfss RTCC,0 goto RX_E7a clrf RTCC ;Steigende Flanke am Eingangs-Signal? movf PortB,w movwf Temp btfss Temp, I_RXDTCM goto RX_E7b btfsc LastPB, I_RXDTCM goto RX_E7b ;Korrektur DCD-Zähler movlw DCDINC_7F addwf DCDCnt,f ;Abtastzeitpunkt verschieben (1 Takt überspringen) movf Temp,w movwf LastPB btfss PortB, I_PTT goto mn_loop btfsc PortA, I_EXTERN goto mn_loop goto RX_E0z RX_E7b: movf Temp,w movwf LastPB RX_E7x: ;Weiter solange die Betriebsart AFSK-RX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfss PortB, I_PTT goto mn_loop btfsc PortA, I_EXTERN goto mn_loop goto RX_E0a ;**************************************************************** ;* Sendung, externes Modem * ;**************************************************************** ;---------------------------------------------------------------- ; ETInit ; Initialisierung des Senders ;---------------------------------------------------------------- ETInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;Sonstige Initialisierungen clrf AktTakt movf PortA,w movwf LastPA ;---------------------------------------------------------------- ; Schleife Sender externes Modem ;---------------------------------------------------------------- TX_E0: ;Warten auf die nächste aktive Taktflanke btfsc PortA, IO_TXCA goto TX_E0 ;Taktzähler++ incf AktTakt,f ;Wenn aktuelles TX-Bit == 0, dann Ausgangsbit ;an den TCM invertieren btfsc PortB, I_TXDA goto TX_E1 movf PortB,w xorlw 1 << O_TXDTCM movwf PortB TX_E1: ;Warten auf die inaktive Taktflanke btfss PortA, IO_TXCA goto TX_E1 ;Watchdog nachtriggern clrwdt ;Weiter solange die Betriebsart Extern-TX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfsc PortB, I_PTT goto mn_loop btfsc PortA, I_EXTERN goto mn_loop goto TX_E0 ;**************************************************************** ;* Eintritt in FSK-Betriebsart * ;**************************************************************** StartFSK: btfss PortB, I_PTT goto FTInit ;**************************************************************** ;* FSK-Empfang * ;**************************************************************** ;---------------------------------------------------------------- ; FRInit ; Initialisierung des FSK-Empfängers ;---------------------------------------------------------------- FRInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;---------------------------------------------------------------- ; Schleife FSK-Empfänger ;---------------------------------------------------------------- RX_F0: ;Auf steigende Flanke an FSK_CLK warten btfss PortB, I_CLK goto RX_F0 ;Takt an SIO weiter geben bsf PortB, O_RXCA ;FSK_DATA ist jetzt Eingang, (TXCA = 1) movlw DirA | (1 << IO_DATA) tris PortA ;Auf fallende Flanke an FSK_CLK warten (Timeout, falls keine ;Flanke kommt: FSK-Teil muß nicht bestückt sein!) ;Währenddessen das an FSK_DATA anliegende Signal nach ;RXDA durchschalten movlw TioFSKCLK_RX movwf Temp RX_F1: btfss PortB, I_CLK goto RX_F2 btfss PortA, IO_DATA bcf PortB, O_RXDA btfsc PortA, IO_DATA bsf PortB, O_RXDA decfsz Temp,f goto RX_F1 RX_F2: ;Takt an SIO weiter geben bcf PortB, O_RXCA ;Kurz warten (ca. 13µs nach fallender Flanke) movlw Tio13 movwf Temp RX_F3: decfsz Temp,f goto RX_F3 ;PTT-Zustand auf FSK_DATA ausgeben (PTT ist inaktiv!) ;(auch TXCA = 0 ausgeben) movlw (DirA | (1 << IO_DATA)) - (1 << IO_TXCA) tris PortA ;Watchdog nachtriggern clrwdt ;Weiter solange die Betriebsart FSK-RX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfss PortB, I_PTT goto mn_loop btfsc PortB, I_FSKAFSK goto mn_loop btfss PortA, I_EXTERN goto mn_loop goto RX_F0 ;**************************************************************** ;* FSK-Sendung * ;**************************************************************** ;---------------------------------------------------------------- ; FTInit ; Initialisierung des FSK-Senders ;---------------------------------------------------------------- FTInit: ;Datenrichtung Port A (für I/O-Ports) ;--> DCD inaktiv, FSK-DATA hochohmig (RX), TXCA inaktiv (1) movlw DirA tris PortA ;Ausgangsregister für I/O-Ports (alle 0) clrf PortA ;---------------------------------------------------------------- ; Schleife FSK-Sender ;---------------------------------------------------------------- TX_F0: ;Auf fallende Flanke an FSK_CLK warten btfsc PortB, I_CLK goto TX_F0 ;Takt invertiert an SIO weiter geben. PTT-Zustand an FSK-PIC melden movlw (DirA | (1 << IO_TXCA)) & (0xFF - (1 << IO_DATA)) tris PortA ;Auf steigende Flanke an FSK_CLK warten (Timeout, falls keine ;Flanke kommt: FSK-Teil muß nicht bestückt sein!) movlw TioFSKCLK_TX movwf Temp TX_F1: btfsc PortB, I_CLK goto TX_F2 decfsz Temp,f goto TX_F1 TX_F2: ;Takt invertiert an SIO weiter geben movlw DirA & (0xFF - (1 << IO_TXCA)) tris PortA ;Etwas warten damit SIO das Sendebit ausgeben kann nop nop nop nop ;TXDA-Zustand auf FSK_DATA ausgeben movlw (DirA | (1 << IO_DATA)) & (0xFF - (1 << IO_TXCA)) btfss PortB, I_TXDA andlw 0xFF - (1 << IO_DATA) tris PortA ;Watchdog nachtriggern clrwdt ;Weiter solange die Betriebsart FSK-TX aktiv ist. ;Andernfalls zurück zum Hauptverteiler btfsc PortB, I_PTT goto mn_loop btfsc PortB, I_FSKAFSK goto mn_loop btfss PortA, I_EXTERN goto mn_loop goto TX_F0 goto mn_loop ;**************************************************************** ;* RESET-Einsprung * ;**************************************************************** org 0x1FF goto Reset END