busy equ p1.3 ;************************************************************************ rs equ p1.4 ;* FiFi-Radio DARC OV-Lennestadt (O 28) * rw equ p1.5 ;* * enab equ p1.6 ;* Abstimmung, Tunersteuerung * tast equ p1.7 ;* * sda equ p3.0 ;* und RDS-Decoder * scl equ p3.1 ;* * rdcl equ p3.2 ;* * rdda equ p3.3 ;* Stand 12.11.06 * busen equ p3.4 ;* * qual equ p3.7 ;* * taktiv equ 20h.0 ;* (c) DL 1 YEJ * pib equ 20h.1 ;* * rdssync equ 20h.2 ;* * rdsinfo equ 20h.3 ;************************************************************************ * freql equ 30h freqh equ 31h pllh equ 32h plll equ 33h frasc0 equ 34h frasc1 equ 35h frasc2 equ 36h frasc3 equ 37h frasc4 equ 38h piasc_0 equ 39h piasc_1 equ 3ah piasc_2 equ 3bh piasc_3 equ 3ch rdsdat_0 equ 40h rdsdat_1 equ 41h rdsdat_2 equ 42h rdsdat_3 equ 43h bitz equ 44h rdszsp_al equ 50h rdszsp_ah equ 51h rdszsp_bl equ 52h rdszsp_bh equ 53h rdszsp_cl equ 54h rdszsp_ch equ 55h block_al equ 56h block_ah equ 57h block_bl equ 58h block_bh equ 59h block_cl equ 5ah block_ch equ 5bh block_dl equ 5ch block_dh equ 5dh zadr equ 46h zcode equ 47h cseg at 0000h jmp start cseg at 0003h jmp isr start: mov sp,#5fh mov tmod,#11h mov tcon,#01h mov ie,#81h setb rw clr enab clr rs mov freql,#02eh ;Einstellen der Grundfrequenz 87,5 MHz mov freqh,#22h ;(8750(10) -> 222E(16) mov piasc_0,#2dh ;Startanzeige PI-Code "----" mov piasc_1,#2dh mov piasc_2,#2dh mov piasc_3,#2dh clr busen ;I2C-Bus des Tuner-IC's deaktivieren setb tf1 dpy_init: mov tl0,#0a0h ;+++ Initialisierung des Displays +++ mov th0,#15h ;Warteschleife 30ms setb tr0 dpy_init_1: jnb tf0,dpy_init_1 clr tr0 clr tf0 clr rw mov a,p1 anl a,#0f0h orl a,#03h ;Schreiben einer 3xh ins Befehlsregister setb enab clr enab mov tl0,#0e0h ;Warteschleife 10ms mov th0,#0b1h setb tr0 dpy_init_2: jnb tf0,dpy_init_2 clr tr0 clr tf0 setb enab clr enab mov tl0,#70h ;Warteschleife 200µs mov th0,#0feh setb tr0 dpy_init_3: jnb tf0,dpy_init_3 clr tr0 clr tf0 setb enab clr enab call dpybusy clr rw vierbit: mov a,p1 ;Vierbit-Modus einstellen anl a,#0f0h ;(Steuerung des Displays nur über D4 - D7) orl a,#02h mov p1,a setb enab clr enab call dpybusy clr rw systset: mov a,p1 ;Einstellung 4 Displayzeilen anl a,#0f0h orl a,#02h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#0ch mov p1,a setb enab clr enab call dpybusy clr rw clrdpy: mov a,p1 ;Display löschen anl a,#0f0h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#01h mov p1,a setb enab clr enab call dpybusy clr rw csrhome: mov a,p1 ;Cursor auf Zeichenadresse "00" stellen anl a,#0f0h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#03h mov p1,a setb enab clr enab call dpybusy clr rw enmoset: mov a,p1 ;Cursoreinstellungen anl a,#0f0h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#06h mov p1,a setb enab clr enab call dpybusy clr rw dpyonoff: mov a,p1 ;Cursor ausschalten anl a,#0f0h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#0ch mov p1,a setb enab clr enab call dpybusy clr rw dpyshft: mov a,p1 ;Cursor-/Anzeigeeinstellungen anl a,#0f0h orl a,#02h mov p1,a setb enab clr enab mov a,p1 anl a,#0f0h orl a,#0ch mov p1,a setb enab clr enab call dpybusy rxinit: call tune tasten: jb tf1,tasten_1 ;+++ Tastaturabfrage +++ ajmp tastend ;Entprellung tasten_1: clr tast clr tr1 orl p1,#0fh mov a,p1 setb tast anl a,#0fh cjne a,#0fh,sndfnc ;keine Taste gedrückt clr taktiv ajmp tastend sndfnc: cjne a,#0eh,up50k ;Nur "Second function"-Taste gedrückt clr taktiv ajmp tastend up50k: jnb taktiv,up50k_1 ajmp tastend up50k_1: mov tl1,#01h ;Prelltimer setzen mov th1,#00h clr tf1 setb tr1 setb taktiv cjne a,#0bh,dn50k ;Abfrage auf 108 MHz mov a,freqh cjne a,#2ah,up50k_2 mov a,freql cjne a,#30h,up50k_2 ajmp tastend up50k_2: clr c mov a,freql ;50 kHz auf add a,#05h ;Addition des Frequenzdatenwortes um 5 mov freql,a mov a,freqh addc a,#00h mov freqh,a call tune call lo_dpy ajmp tastend dn50k: cjne a,#07h,up1m mov a,freqh ;Abfrage auf 87,5 MHz cjne a,#22h,dn50k_1 mov a,freql cjne a,#2eh,dn50k_1 ajmp tastend dn50k_1: clr c mov a,freql ;50 kHz ab subb a,#05h ;Subtraktion des Frequenzdatenwortes um 5 mov freql,a mov a,freqh subb a,#00h mov freqh,a call tune call lo_dpy ajmp tastend up1m: cjne a,#0ah,dn1m ;1 MHz auf clr c mov a,freql ;Abfrage auf 107 MHz subb a,#0d1h mov a,freqh subb a,#29h jc up1m_1 ajmp tastend up1m_1: clr c mov a,freql add a,#64h ;Addition des Frequenzwortes um 100(10) -> 64(16) mov freql,a mov a,freqh addc a,#00h mov freqh,a call tune call lo_dpy ajmp tastend dn1m: cjne a,#06h,pifreq ;1 MHz ab clr c mov a,freql subb a,#92h ;Abfrage auf 88,5 MHz mov a,freqh subb a,#22h jnc dn1m_1 ajmp tastend dn1m_1: clr c mov a,freql subb a,#64h ;Subtraktion des Frequenzwortes um 100(10) -> 64(16) mov freql,a mov a,freqh subb a,#00h mov freqh,a call tune call lo_dpy ajmp tastend pifreq: cjne a,#0dh,tastend ;Wechsel zwischen Frequenz- und PI-Codeanzeige jb pib,pifreq_1 setb pib call freqanz ajmp tastend pifreq_1: clr pib call pianz ajmp tastend tastend: nop picode: jb rdsinfo,picode_1 ;Abfrage auf aktuelle RDS-Informationen ajmp tasten picode_1: mov a,rdszsp_ah ;Auslesen des PI-Codes anl a,#0f0h swap a mov r0,a call hexasc ;Umrechnung der 4-stelligen Hexadezimalzahl des PI-Codes mov piasc_3,r0 ;in ASCII-Zeichen und Speicherung im PI-ASCII-Speicher mov a,rdszsp_ah anl a,#0fh mov r0,a call hexasc mov piasc_2,r0 mov a,rdszsp_al anl a,#0f0h swap a mov r0,a call hexasc mov piasc_1,a mov a,rdszsp_al anl a,#0fh mov r0,a call hexasc mov piasc_0,a rds_ps: mov a,block_bh ;+++ Anzeige des Stationsnamens +++ anl a,#0f0h ;Abfrage auf Gruppe 0A/0B (Programmservice) jnz rds_rt mov a,block_bl ;Auslesen der Segmentadresse anl a,#03h ;(Position der zwei folgenden Zeichen in Block D) rl a add a,#07h mov zadr,a mov zcode,block_dh ;Auslesen des ersten Zeichens call text inc zadr mov zcode,block_dl ;Auslesen des zweiten Zeichens call text rds_rt: mov a,block_bh ;+++ Anzeige Radiotext +++ anl a,#0f0h cjne a,#20h,rds_end ;Abfrage auf Gruppe 2A/2B (Radiotext) mov a,block_bl anl a,#0fh ;Auslesen der Segmentadresse jnz seg_1 ;(Position der vierr folgenden Zeichen in Block C, D) mov zadr,#10h ;Aufteilung des Displays (Adr. 10(16) - 13(16)) call rt_aus ;Rest erste Zeile ajmp rds_end seg_1: clr c ;Aufteilung des Displays (Adr. 40(16) - 53(16)) subb a,#06h ;Zweite Zeile jnc seg_2 add a,#05h rl a rl a add a,#40h mov zadr,a call rt_aus ajmp rds_end seg_2: subb a,#05h ;Aufteilung des Displays (Adr. 14(16) - 27(16)) jnc seg_3 ;Dritte Zeile add a,#05h rl a rl a add a,#14h mov zadr,a call rt_aus ajmp rds_end seg_3: rl a ;Aufteilung des Displays (Adr. 54(16) - 67(16)) rl a add a,#54h mov zadr,a call rt_aus rds_end: clr rdsinfo ajmp tasten lo_dpy: mov piasc_0,#2dh ;*** Display Löschen *** mov piasc_1,#2dh mov piasc_2,#2dh mov piasc_3,#2dh mov zcode,#20h mov zadr,#07h lo_dpy_1: call text inc zadr mov a,zadr cjne a,#28h,lo_dpy_1 mov zadr,#40h lo_dpy_2: call text inc zadr mov a,zadr cjne a,#68h,lo_dpy_2 ret rt_aus: mov zcode,block_ch ;*** Radiotext-Ausgabe *** call text inc zadr mov zcode,block_cl call text inc zadr mov zcode,block_dh call text inc zadr mov zcode,block_dl call text ret clr rdsinfo ;Ende aktuelle RDS-Information ajmp tasten ;Rücksprung zur Tastenabfrage - Ende Hauptprogramm dpybusy: setb busy ;*** Abfrage des Busyflags für die Displayansteuerung setb rw clr rs setb enab jnb busy,dpybusy_1 clr enab setb enab clr enab jmp dpybusy dpybusy_1: clr enab setb enab clr enab ret tune: clr c ;*** Abstimmung des Empfängers *** mov a,freql ;Multiplikation des Frequenzwortes mit 10000 (2710(16)) mov b,#10h ;/// Multiplikation mit dem Teilfaktor 10(16) /// mul ab mov r2,a mov r3,b mov a,freqh mov b,#10h mul ab mov r4,b add a,r3 mov r3,a mov a,r4 addc a,#00h mov r4,a clr c mov a,freql ;/// Multiplikation mit dem Teilfaktor 27(16) /// mov b,#27h mul ab mov r5,a mov r6,b mov a,freqh mov b,#27h mul ab mov r7,b add a,r6 mov r6,a mov a,r7 addc a,#00h clr c ;/// Zusammenfassung der Teilprodukte /// mov r7,a mov a,r3 add a,r5 mov r3,a mov a,r4 addc a,r6 mov r4,a mov a,r7 addc a,#00h mov r5,a clr c ;Addition der ZF (225000 Hz) 36EE8(16) mov a,r2 add a,#0e8h mov r2,a mov a,r3 addc a,#6eh mov r3,a mov a,r4 addc a,#03h mov r4,a mov a,r5 addc a,#00h mov r5,a mov a,r3 mov a,r5 ;+++ Division des Ergebnisses durch 8192(10) -> 2000(16) +++ rrc a ;Division durch 2 durch Rechtsschieben mov r5,a ;Die restliche Division durch 4096(10) wird durch Ausblenden mov a,r4 ;der vier niedrigen Bits des zweitniedrigsten Registers und durch rrc a ;Nichtauslesen des niedrigsten Registers durchgeführt!) mov r4,a mov a,r3 rrc a anl a,#0f0h ;Ausblenden der hinteren 4 Bis mov r3,a mov a,r4 mov b,#10h ;Das Ergebnis ist der für die eingestellte Frequenz erforderliche div ab ;Teilungsfaktor. Er wird in den Speicherstellen PLLL und PLLH abge- xch a,b ;legt add a,r3 swap a mov r3,a mov r4,b mov a,r5 mov b,#10h div ab xch a,b swap a add a,r4 mov pllh,a mov plll,r3 call freqasc setb busen call i2cstart ;+++ Übergabe der PLL-Daten an das Tuner-IC via I2C-Bus +++ mov r0,#0c0h ;Laden der IC-Adresse call i2cwrite mov r0,pllh ;Laden des H-Bytes der Frequenz call i2cwrite mov r0,plll ;Laden des L-Bytes der Frequenz call i2cwrite mov r0,#0d1h ;Laden der restlichen Konfiguration call i2cwrite ;(s. Datenblatt TEA5768HL) mov r0,#90h call i2cwrite mov r0,#00h call i2cwrite call i2cstop clr busen call freqasc ret freqasc: mov a,freqh ;+++ Umwandlung des Frequenzwortes in ASCII-Code +++ anl a,#0f0h ;Beginn 1. Durchlauf swap a ;Umrechnung des Frequenzwortes hexadezimal -> dezimal durch fortlau- mov b,#0ah ;fende Division durch 10(10) -> 0A(10) div ab swap a mov r3,a xch a,b swap a mov r4,a mov a,freqh anl a,#0fh add a,r4 mov b,#0ah div ab add a,r3 mov r3,a xch a,b swap a mov r4,a mov a,freql anl a,#0f0h swap a add a,r4 mov b,#0ah div ab swap a mov r2,a xch a,b swap a mov r4,a mov a,freql anl a,#0fh add a,r4 mov b,#0ah div ab add a,r2 mov r2,a mov r4,b mov a,r3 ;Beginn 2. Durchlauf mov r6,a anl a,#0f0h swap a mov b,#0ah div ab swap a mov r3,a xch a,b swap a mov r7,a mov a,r6 anl a,#0fh add a,r7 mov b,#0ah div ab add a,r3 mov r3,a xch a,b swap a mov r7,a mov a,r2 mov r6,a anl a,#0f0h swap a add a,r7 mov b,#0ah div ab swap a mov r2,a xch a,b swap a mov r7,a mov a,r6 anl a,#0fh add a,r7 mov b,#0ah div ab add a,r2 mov r2,a xch a,b swap a add a,r4 mov r4,a mov a,r2 ;Beginn 3. Durchlauf mov b,#0ah div ab mov r5,b mov b,#0ah ;Beginn 4. Durchlauf div ab mov r6,a xch a,b swap a add a,r5 mov r5,a bcdasc: mov a,r6 ;+++ Umrechnung BCD-ASCII +++ jnz bcdasc_1 ;Ausblendung der führenden 0 (ASCII-Code 20(16)) wenn das Ergebnis 0 ist mov frasc0,#20h jmp bcdasc_2 bcdasc_1: mov frasc0,#31h bcdasc_2: mov a,r5 anl a,#0f0h ;Addition einer 30(16) zu den einzelnen Stellenwerten zur Bildung swap a ;des ASCII-Codes add a,#30h mov frasc1,a mov a,r5 anl a,#0fh add a,#30h mov frasc2,a mov a,r4 anl a,#0f0h swap a add a,#30h mov frasc3,a mov a,r4 anl a,#0fh jnz bcdasc_3 ;Ausblendung der letzten 0 mov frasc4,#20h jmp freqanz bcdasc_3: mov frasc4,#35h freqanz: mov zadr,#00h ;+++ Ausgabe der Frequenz auf dem Display +++ mov zcode,frasc0 call text inc zadr mov zcode,frasc1 call text inc zadr mov zcode,frasc2 call text inc zadr mov zcode,#2eh ;Schreiben des Dezimalpunktes (ASCII-Code 2E(16)) call text inc zadr mov zcode,frasc3 call text inc zadr mov zcode,frasc4 call text ret ;Ende des Unterprogrammes "Tune" pianz: mov zadr,#00h ;*** Anzeige des PI-Codes im Frequenzfenster *** mov zcode,#20h ;Schreiben eines Leerzeichens am Anfang call text ;Schreiben der 4 Zeichen inc zadr mov zcode,piasc_3 call text inc zadr mov zcode,piasc_2 call text inc zadr mov zcode,piasc_1 call text inc zadr mov zcode,piasc_0 call text inc zadr mov zcode,#20h ;Schreiben eines Leerzeichens am Ende call text ret ;Ende des Unterprogrammes "PIANZ" text: clr rs ;*** Textausgabe auf dem Display *** clr enab clr rw mov a,zadr ;Einstellen der Zeichenadresse anl a,#0f0h swap a orl a,#08h ;Setzen der "1" als höchstes Bit des Adressspeichers mov r2,a ;(s. Infoblatt) mov a,p1 anl a,#0f0h orl a,r2 ;H-Byte der Adresse mov p1,a setb enab clr enab mov a,zadr anl a,#0fh mov r2,a mov a,p1 anl a,#0f0h orl a,r2 ;L-Byte der Adresse mov p1,a setb enab clr enab call dpybusy clr rw setb rs ;Laden des Zeichens mov a,zcode anl a,#0f0h swap a mov r2,a mov a,p1 anl a,#0f0h orl a,r2 ;H-Byte des ASCII-Codes mov p1,a setb enab clr enab mov a,zcode anl a,#0fh mov r2,a mov a,p1 anl a,#0f0h orl a,r2 ;L-Byte des ASCII-Codes mov p1,a setb enab clr enab call dpybusy ret ;Ende des Unterprogrammes "TEXT" i2cstart: clr sda ;*** I2C-Bus Startbedingung *** call i2ctim ;Startbedingung f. I2C-Bus clr scl call i2ctim ret ;Ende des Unterprogrammes "I2CSTART" i2cstop: setb scl ;*** Stopbedingung f. I2C-Bus *** call i2ctim ;Stopbedingung f. I2C-Bus setb sda call i2ctim ret ;Ende des Unterprogrammes "I2CSTOP" i2cwrite: mov r1,#00h ;*** Schreiben eines Bytes im I2C-Bus *** i2cshift: mov a,r0 ;R0: Zu übertragendes Byte rlc a ;R1: Bitzähler mov r0,a ;Ausschieben des Bytes i2c_0: jc i2c_1 clr sda ;Schreiben einer "0" call i2ctim setb scl call i2ctim clr scl call i2ctim jmp i2cbit i2c_1: setb sda ;Schreiben einer "1" call i2ctim setb scl call i2ctim clr scl call i2ctim i2cbit: inc r1 mov a,r1 cjne a,#08h,i2cshift ackn: setb sda ;Platz für Acknowledgebit des Slaves call i2ctim setb scl call i2ctim clr scl call i2ctim ret ;Ende des Unterprogrammes I2CWRITE i2ctim: inc r7 ;*** I2C-Timer *** mov a,r7 ;Anpassung der Datenrate an die I2C-Spezifikation an den cjne a,#0ah,i2ctim ;µC-Takt mov r7,#00h ret ;Ende des Unterprogrammes I2CTIM hexasc: clr c ;*** Umrechnung Hexadezimal -> ASCII mov a,r0 ;Unterscheidung Ziffer (Hexzahl < A) oder Buchstabe subb a,#0ah ;(Hexzahl > 9) durch Subtraktion von A(16) jnc hexasc_1 add a,#3ah ;Ergebnis negativ -> Zahlenbereich 0 - 9 mov r0,a ;Addition von 3A(16) zur Bildung des ASCII-Codes der Ziffern ret ;0 - 9 und Ende des Unterprogrammes "HEXASC" hexasc_1: add a,#41h ;Ergebnis nicht negativ -> Zahlenbereich A(16) - F(16) mov r0,a ;Addition von 41(16) zur Bildung des ASCII-Codes der Zeichen ret ;A - F und Ende des Unterprogrammes "HEXASC" isr: push acc ;*** RDS-Decoder als Interrupt-Routine *** push b push psw setb rs0 ;Umschalten auf Registerbank 1 rds_0: jb rdda,rds_1 ;Lesen des RDS-Bits clr c jmp rdsshft rds_1: setb c rdsshft: mov a,rdsdat_0 ;Schieben der RDS-Information um 1 Bit. Für 26 erforderliche rlc a ;Bits sind die 4 Speicherstellen RDSDAT_0 - RDSDAT_3 erforderlich mov rdsdat_0,a mov a,rdsdat_1 rlc a mov rdsdat_1,a mov a,rdsdat_2 rlc a mov rdsdat_2,a mov a,rdsdat_3 rlc a mov rdsdat_3,a jnb rdssync,matrix ;Abfrage des Sync-Bits mov a,bitz ;Solange der Datenstrom nicht synchronisiert ist, muss nach jedem cjne a,#19h,rdsshft_1 ;eingelaufenen Bit durch Multiplikation des aktuellen 26-Bit-RDS-Wortes mov bitz,#00h ;mit der Check-Matrix erneut die Synchronisation geprüft werden. jmp matrix ;Ist die Synchronisation erreicht, reicht es, 26 Bits abzuzählen und dann rdsshft_1: inc bitz ;erneut zu prüfen und die weitere Sortierung der RDS-Daten kann erfolgen. ajmp isrend matrix: mov r3,#00h ;Matrixmultiplikation zur Synchronisierung und Decodierung mov r4,#00h mov a,rdsdat_3 rlc a mov r2,a jnc bit_24 mov r4,#80h bit_24: mov a,r2 rlc a mov r2,a jnc bit_23 mov a,r4 xrl a,#40h mov r4,a bit_23: mov a,r2 rlc a mov r2,a jnc bit_22 mov a,r4 xrl a,#20h mov r4,a bit_22: mov a,r2 rlc a mov r2,a jnc bit_21 mov a,r4 xrl a,#10h mov r4,a bit_21: mov a,r2 rlc a mov r2,a jnc bit_20 mov a,r4 xrl a,#08h mov r4,a bit_20: mov a,r2 rlc a mov r2,a jnc bit_19 mov a,r4 xrl a,#04h mov r4,a bit_19: mov a,r2 rlc a mov r2,a jnc bit_18 mov a,r4 xrl a,#02h mov r4,a bit_18: mov a,r2 rlc a jnc bit_17 mov a,r4 xrl a,#01h mov r4,a bit_17: mov a,rdsdat_2 rlc a mov r2,a jnc bit_16 mov r3,#80h bit_16: mov a,r2 rlc a mov r2,a jnc bit_15 mov a,r3 xrl a,#40h mov r3,a bit_15: mov a,r2 rlc a mov r2,a jnc bit_14 mov a,r4 xrl a,#0b7h mov r4,a bit_14: mov a,r2 rlc a mov r2,a jnc bit_13 mov a,r4 xrl a,#5bh mov r4,a mov a,r3 xrl a,#80h mov r3,a bit_13: mov a,r2 rlc a mov r2,a jnc bit_12 mov a,r4 xrl a,#2dh mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_12: mov a,r2 rlc a mov r2,a jnc bit_11 mov a,r4 xrl a,#0a1h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_11: mov a,r2 rlc a mov r2,a jnc bit_10 mov a,r4 xrl a,#0e7h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_10: mov a,r2 rlc a jnc bit_9 mov a,r4 xrl a,#0c4h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_9: mov a,rdsdat_1 rlc a mov r2,a jnc bit_8 mov a,r4 xrl a,#0d5h mov r4,a mov a,r3 xrl a,#40h mov r3,a bit_8: mov a,r2 rlc a mov r2,a jnc bit_7 mov a,r4 xrl a,#0ddh mov r4,a mov a,r3 xrl a,#80h mov r3,a bit_7: mov a,r2 rlc a mov r2,a jnc bit_6 mov a,r4 xrl a,#6eh mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_6: mov a,r2 rlc a mov r2,a jnc bit_5 mov a,r4 xrl a,#80h mov r4,a mov a,r3 xrl a,#40h mov r3,a bit_5: mov a,r2 rlc a mov r2,a jnc bit_4 mov a,r4 xrl a,#0f7h mov r4,a bit_4: mov a,r2 rlc a mov r2,a jnc bit_3 mov a,r4 xrl a,#7bh mov r4,a mov a,r3 xrl a,#80h mov r3,a bit_3: mov a,r2 rlc a mov r2,a jnc bit_2 mov a,r4 xrl a,#3dh mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_2: mov a,r2 rlc a jnc bit_1 mov a,r4 xrl a,#0a9h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_1: mov a,rdsdat_0 rlc a mov r2,a jnc bit_0 mov a,r4 xrl a,#0e3h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a bit_0: mov a,r2 rlc a jnc decode mov a,r4 xrl a,#0c6h mov r4,a mov a,r3 xrl a,#0c0h mov r3,a ;Matrixmultiplikation beendet decode: mov a,r3 ;Abfrage des Offsetwortes jz block_a ;Die unteren beiden Bits sind immer 0 ajmp nsync block_a: mov a,r4 ;Abfrage der höchsten 8 Bits cjne a,#0f6h,block_b ;Offsetwort für Block A gefunden setb rdssync ;Datenstrom ist synchron mov rdszsp_al,rdsdat_2 ;Zwischenspeichern der RDS-Daten für Block A mov rdszsp_ah,rdsdat_3 mov r5,#01h ;Reihenfolge-Register um 1 erhöhen ajmp isrend block_b: cjne a,#0f5h,block_c ;Offsetwort für Block B gefunden setb rdssync ;Datenstrom ist synchron mov a,r5 ;Abfrage des Reihenfolge-Registers. Bei nicht Übereinstimmung ist eine cjne a,#01h,block_b_1 ;Störung aufgetreten und die Blöcke gehören nicht zur gleichen Gruppe mov rdszsp_bl,rdsdat_2 ;Zwischenspeichern der RDS-Daten für Block B mov rdszsp_bh,rdsdat_3 inc r5 ajmp isrend block_b_1: mov r5,#00h ;Reihenfolge stimmt nicht - Daten können nicht weiter ausgewertet ajmp isrend ;werden undd werden verworfen block_c: cjne a,#97h,block_ca ;Offsetwort für Block C erkannt setb rdssync ;s. Block B mov a,r5 cjne a,#02h,block_c_1 mov rdszsp_cl,rdsdat_2 mov rdszsp_ch,rdsdat_3 inc r5 ajmp isrend block_c_1: mov r5,#00h ajmp isrend block_ca: cjne a,#0f3h,block_d ;Offsetwort für Block C' erkannt setb rdssync ;s. Block B mov a,r5 cjne a,#02h,block_ca_1 mov rdszsp_cl,rdsdat_2 mov rdszsp_ch,rdsdat_3 inc r5 ajmp isrend block_ca_1: mov r5,#00h ajmp isrend block_d: cjne a,#96h,nsync ;Offsetwort für Block D erkannt setb rdssync ;s. Block B mov a,r5 cjne a,#03h,block_d_1 mov block_al,rdszsp_al ;Eine komplette Gruppe gelesen und übergabe der Zwischenspeicher mov block_ah,rdszsp_ah ;der Blöcke A bis C (C') an den Gruppenspeicher mov block_bl,rdszsp_bl mov block_bh,rdszsp_bh mov block_cl,rdszsp_cl mov block_ch,rdszsp_ch mov block_dl,rdsdat_2 mov block_dh,rdsdat_3 setb rdsinfo ;Neue RDS-Information komplett block_d_1: mov r5,#00h ajmp isrend nsync: mov r5,#00h ;Kein gültiges Offsetwort gefunden -> Datenstrom nicht mov bitz,#00h ;synchron und Löschen aller Steuerbits clr rdssync clr rdsinfo isrend: pop psw ;RDS-Decodierung beendet pop b pop acc reti end