Import-Script
13.03.2003, 22:15
Moin Peter, <BR> <BR>rein zufällig habe ich gerade gesehen das eine Beispiel-Routine die der Batronix-Software beiliegt eigentlich von mir ist. Das ist ja auch nicht schlimm, aber wenn Du schon meine Sachen verteilst könntest Du wenigstens Deine eigenen Kommentare dazu schreiben. Vor einiger Zeit hatte ich Dir mal eben genau mein Programm und die Erklärung zu seriellen EEPROM's gemailt. Deine Fragen von damals stehen im Forum Archiv. Schön wie sich alles wiederfindet. Ich bin stolz auf Dich... <BR> <BR>Gruß Winnie <BR> <BR>Hier beide Versionen: <BR>1. Deine <BR>2. meine <BR> <BR>; 24C16 Ansteuerung von Peter Max, bei Fragen u. Verbesserungsvorschlägen, <BR>; bitte eine email an <a href="mailto:sirpete@web.de">sirpete@web.de</a> <BR>; Diese INCLUDE-Datei, steuert den I²C-Bus. Optimiert für den 24C16, <BR>; lässt sich aber einfach auf alle beliebigen I²C-Bausteine übertragen. <BR>; <BR>; <BR>; Wichtig!! <BR>; <BR>; Der 24C16 hat eine 11Bit Adressierung, die folgendermaßen aussieht: <BR>; Device-Address | Word-Address | Data | <BR>; 1 0 1 0 P2 P1 P0 R/-W | A7 A6 A5 A4 A3 A2 A1 A0 | B7 B6 B5 B4 B3 B2 B1 B0 | <BR>; ^ ^ ^ | ^ | ^ | <BR>; Device Page Modus | Addresse in der Page | Zu schreibendes Byte | <BR>; <BR>; <BR>; Benötigte Daten: <BR>; SDA - > BIT - Portpin für SDA-Leitung. <BR>; SCL - > BIT - Portpin für SCL-Leitung. <BR>; I2C_befehl - > Wert einer Speicherstelle die ein Baustein Adressiert. <BR>; Adresse - > Wert einer Speicherstelle, die die WordAdresse enthält. <BR>; Wert - > Wert einer Speicherstelle, die die zu schreibenden Daten enthält. <BR>; <BR>; Die Befehle der INCLUDE-Datei: <BR>; wert_lesen - > Schreibt Inhalt von "Wert" im Adressierte Baustein u. an die in "Adresse" Stehendestelle <BR>; wert_schreiben - > Liest Inhalt vom Adressierten Baustein und Adresse in den Akku <BR>; <BR>; Unabhängig von den vorhergehenden Befehlen: <BR>; Startbedingung_erzeugen - > Sendet Startsingnal am I²C-Bus <BR>; Stopbedingung_erzeugen - > Sendet Stopsignal am I²C-Bus <BR>; Acknowledge - > Sendet Acknowledge am I²C-Bus <BR>; No_Acknoeledge - > Sendet NoAcknowledge am I²C-Bus <BR> <BR>Startbedingung_erzeugen: <BR> SETB SDA 'Vorbereitung zur Startbedingung' <BR> SETB SCL <BR> JNB SDA,Bus_belegt 'Ist der Datenbus frei?' <BR> JNB SCL,Bus_belegt 'Ist der Datenbus frei?' <BR> NOP <BR> NOP <BR> CLR SDA 'SCL high / SDA geht auf low' <BR> CALL 5µs <BR> CLR SCL <BR> CLR C <BR> JMP I2C_zurück <BR>Bus_belegt: <BR> SETB C 'Setze Carry BIT wenn Datenbus besetzt.' <BR> 'Wird aber in diesem Programm nicht abgefragt,' <BR> 'da nur ein I2C Baustein angeschlossen.' <BR>I2C_zurück: <BR>RET <BR> <BR>Acknowledge: 'BIT vom I2C-Baustein (hier EEPROM)' <BR> CLR SDA 'zur Bestätigung, dass das' <BR> NOP 'Datenwort korrekt angekommen ist. <BR> NOP <BR> SETB SCL <BR> CALL 5µs <BR> CLR SCL <BR>RET <BR> <BR>No_Acknowledge: 'siehe oben, nur diametral' <BR> SETB SDA <BR> NOP <BR> NOP <BR> SETB SCL <BR> CALL 5µs <BR> CLR SCL <BR>RET <BR> <BR>Stopbedingung_erzeugen: <BR> CLR SDA 'Vorbereitung zur Stopbedingung' <BR> NOP <BR> NOP <BR> SETB SCL 'SCL high / SDA geht auf high' <BR> CALL 5µs <BR> SETB SDA <BR>RET <BR> <BR> <BR>8_Bits_senden: 'Daten sind im AKKU' <BR> PUSH B 'Rette Inhalt von B auf den Stack.' <BR> MOV B,#8 'Wird in diesem Programm eigentlich' <BR> 'nicht benötigt, nur zum "Angewöhnen"' <BR>8_Bits: 'für später :-)' <BR> RLC A 'Schiebe den Akkuinhalt nach links' <BR> MOV SDA,C 'durch das Carry Flag um ihn Bitweise' <BR> NOP 'zu senden.' <BR> SETB SCL <BR> CALL 5µs <BR> CLR SCL <BR> DJNZ B,8_Bits <BR>'Hole Acknowledge BIT vom Slave (9. BIT, Empfangsbestätigung)' <BR> SETB SDA <BR> RLC A 'Stellt Ausgangs Wert von Akku und C wieder her <BR> NOP <BR> SETB SCL <BR> CALL 5µs <BR> MOV C,SDA <BR> CLR SCL <BR> POP B 'Stelle B wieder her (vom Stack holen)' <BR>RET <BR> <BR>8_Bits_lesen: 'Daten in den Akku lesen' <BR> SETB SDA <BR> PUSH B 'siehe oben' <BR> MOV B,#8 <BR>8_Bits_1: <BR> NOP <BR> NOP <BR> NOP <BR> SETB SCL <BR> NOP <BR> NOP <BR> NOP 'Die Daten aus dem I2C-Baustein werden' <BR> MOV C,SDA 'in das Carry Flag geschrieben und' <BR> RLC A 'nach links in den Akku geschoben.' <BR> CLR SCL <BR> DJNZ B,8_Bits_1 <BR> POP B 'siehe oben' <BR>RET <BR> <BR>wert_lesen: <BR>'"Dummy write" siehe Datenblatt.' <BR> CALL startbedingung_erzeugen <BR> MOV A,I2C_Befehl <BR> DEC A <BR> CALL 8_Bits_senden <BR> MOV A,Adresse <BR> CALL 8_Bits_senden <BR>'Speicher auslesen ab Adresse (hier Adresse 00 siehe oben)' <BR> CALL startbedingung_erzeugen <BR> MOV A,I2C_Befehl <BR> CALL 8_Bits_senden <BR> CALL 8_Bits_lesen <BR> CALL No_Acknowledge <BR> CALL stopbedingung_erzeugen <BR>RET <BR> <BR>wert_speichern: <BR> CALL Startbedingung_erzeugen <BR> MOV A,I2C_Befehl <BR> CALL 8_Bits_senden <BR> CALL 5µs <BR> MOV A,Adresse <BR> CALL 8_Bits_senden <BR> CALL 5µs <BR> MOV A,Wert <BR> CALL 8_Bits_senden <BR> CALL 5µs <BR> CALL Stopbedingung_erzeugen <BR>RET <BR> <BR>5µs: 'Zeitverzögerung von ca. 5µs incl. CALL u. RET' <BR> NOP <BR> NOP <BR>RET <BR> <BR>****************************************** <BR> <BR>'Belichtungs - Timer für Platinenbelichtungsgerät' <BR>'Auch als Küchen - Timer zu benutzen.' <BR>'Speichert eingestellte Zeit und zeigt sie beim erneuten' <BR>'Starten bzw. Zeitablauf (00.00) sofort an.' <BR>'Countdown - Zeiten zwischen 59 Minuten und 59 Sekunden' <BR>'bis 1 Sekunde in 1er Sekundenschritten einstellbar.' <BR>'Nach Zeitablauf wird wieder die gespeicherte Zeit für' <BR>'erneuten Start eingestellt.' <BR>'Vier Tasten: Minuten minus, Sekunden minus, Start und Stop.' <BR>'Vierstellige 7-Segment-Anzeige.' <BR>'Mein erstes Mikrocontroller Projekt.' <BR>'(C) Wilfried Brozio Mai / Juni 2001' <BR> <BR>INCLUDE 89C2051.mc <BR> <BR>LJMP Initialisierung'Überspringe feste Sprungadressen.' <BR>'50ms Zeitbasis für Timer / Sekunden genaue Zeit' <BR>(000Bh): 'Einsprungadresse Interrupt Timer 0' <BR> MOV A,TL0 'Grundeinstellung Timer 0 Low Byte' <BR> ADD A,#B3h 'A = TL0 = Zeit seit Überlauf + Grundeinstellung B0+3' <BR> MOV TL0,A 'Akkuinhalt in Timer 0 low Byte (TL0)' <BR> MOV TH0,#3Ch 'Grundeinstellung Timer 0 High Byte' <BR>'Routine zum Countdown der Uhrzeit' <BR> DJNZ R6,stop1 'R6 = R6 - 1, wenn nicht 0 dann springe.' <BR> MOV R6,#%20'Interruptzähler (20*50ms = 1000ms = 1Sekunde)' <BR> DEC R3 'R3 = R3 - 1' <BR> IF R3 = #FFh THEN 'R3 übergelaufen?' <BR> MOV R3,#09 'dann R3 = 09' <BR> DEC R2 'R2 = R2 - 1' <BR> END IF <BR> IF R2 = #FFh THEN 'R2 übergelaufen?' <BR> MOV R2,#05 'dann R2 = 05' <BR> DEC R1 'R1 = R1 - 1' <BR> END IF <BR> IF R1 = #FFh THEN 'R1 übergelaufen?' <BR> MOV R1,#09 'R1 = 09' <BR> DEC R0 'R0 = R0 - 1' <BR> END IF <BR> CJNE R0,#00,stop1 'R0 = 10er Minute' <BR> CJNE R1,#00,stop1 'R1 = 1er Minute' <BR> CJNE R2,#00,stop1 'R2 = 10er Sekunden' <BR> CJNE R3,#00,stop1 'R3 = 1er Sekunden' <BR> SETB D5h 'Setze Flag BIT D5h im PSW' <BR> RETI <BR> <BR>Ende: <BR> CLR TR0 'Timer 0 aus' <BR> SETB P3.7 'Relais aus' <BR> LCALL speicher_lesen 'Hole Zeit aus dem Speicher.' <BR> LJMP Tasten <BR> <BR>stop1: <BR> RETI <BR> <BR>Initialisierung: <BR> MOV Port1,#FFh 'Setze Port 1 auf 1111 1111.' <BR> MOV Port3,#%240 'Setze Port 3 auf 1111 0000.' <BR> MOV R6,#%20 'R6 = Interruptzähler' <BR> MOV SP,#20h 'Stack hochsetzen. In diesem Programm' <BR>'eigentlich nicht nötig, DA nur Register Bank 0 benutzt wird.' <BR>'Timer Grundeinstellung' <BR>MOV TMOD,#01h 'Timer 0 Modus = 1 <BR>MOV TH0,#3Ch 'High Byte von Timer 0 setzen <BR>MOV TL0,#B0h 'Low Byte von Timer 0 setzen <BR>SETB EA 'Interruptbehandlung aktivieren <BR>SETB ET0 'Interrupt für Timer 0 aktivieren <BR> <BR>'Zum Speichern' <BR> lesen EQU !10100001'Basisadresse 1010 EEPROM, 0001 lesen' <BR> schreiben EQU !10100000'1010 Basis EEPROM, 0000 schreiben' <BR> Adresse EQU 00h 'Startadresse 00h im EEPROM' <BR> SDA EQU P1.7 'Portpin P1.7 wird SDA zugewiesen' <BR> SCL EQU P1.6 'Portpin P1.6 wird SCL zugewiesen' <BR> <BR>'I2C-Bus initialisieren' <BR> SETB SCL 'Setzte Daten und Clock Leitung' <BR> SETB SDA 'auf high' <BR> LCALL speicher_lesen 'lies den aktuellen Speicherinhalt' <BR> LJMP Tasten 'Frage Tasten ab' <BR> <BR>speicher_lesen: <BR>'auszulesende Adresse schreiben' <BR> SETB SCL <BR> SETB SDA <BR>'"Dummy write" Weil nur ein 24C16 EEPROM vorhanden war, sonst' <BR>'bei z. B. 24C01 EEPROM's enfällt, siehe Datenblatt.' <BR> LCALL startbedingung_erzeugen <BR> MOV A,#schreiben <BR> LCALL 8_Bits_senden <BR> MOV A,#Adresse <BR> LCALL 8_Bits_senden <BR>'Speicher auslesen ab Adresse (hier Adresse 00 siehe oben)' <BR> LCALL startbedingung_erzeugen <BR> MOV A,#lesen <BR> LCALL 8_Bits_senden <BR> LCALL 8_Bits_lesen <BR> MOV R0,A <BR> LCALL Acknowledge <BR> LCALL 8_Bits_lesen <BR> MOV R1,A <BR> LCALL Acknowledge <BR> LCALL 8_Bits_lesen <BR> MOV R2,A <BR> LCALL Acknowledge <BR> LCALL 8_Bits_lesen <BR> MOV R3,A <BR> LCALL No_Acknowledge <BR> LCALL stopbedingung_erzeugen <BR> RET <BR> <BR>Start: <BR> LCALL Zeit_speichern 'eingestellte Zeit speichern' <BR> SETB TR0 'Timer 0 start' <BR> CLR P3.7 'Relais ein' <BR> CLR D1h 'Lösche Verzögerungs BIT im PSW' <BR> LJMP Countdown 'Zähle rückwärts' <BR> <BR> <BR>'Routine zum Minuten einstellen' <BR>Minuten: <BR> CLR P1.4 'Lösche Taster-BIT zur Entprellung' <BR> DEC R1 'R1 = R1 - 1' <BR> LCALL Refresh <BR> IF R1 = #FFh THEN 'Ist R1 übergelaufen?' <BR> MOV R1,#09 'Dann setze R1 auf 09. <BR> DEC R0 'R0 = R0 - 1' <BR> LCALL Refresh <BR> END IF <BR> IF R0 = #FFh THEN 'Ist R0 übergelaufen?' <BR> MOV R0,#05 'Dann setze R0 auf 05. <BR> LCALL Refresh <BR> END IF <BR> SETB P1.4 'Setze wieder Taster-Bit' <BR> JB D1h,Tasten 'Ist BIT D1 gesetzt? Dann schnell zählen.' <BR> PUSH B 'Rette B auf den Stack.' <BR> MOV B,#03h 'Schreibe 03 ins B Register' <BR> <BR>'Warte ob Taste etwas länger gedrückt wird, dann zähle' <BR>'schneller rückwärts.' <BR>warte_1: <BR> LCALL Refresh <BR> MOV R7,#05 'Schreibe 05 in Register R7.' <BR> <BR>warte_2: <BR> LCALL Refresh <BR> DJNZ R7,warte_2 'Springe zu warte_2 bis R7 = 0.' <BR> DJNZ B,warte_1 'Springe zu warte_1 bis B = 0.' <BR> SETB D1h 'Setze BIT D1h zum schnell zählen.' <BR> POP B 'Stelle B wieder her.' <BR> LJMP Tasten <BR> <BR>Tasten: <BR> LCALL Refresh 'Anzeige auffrischen, aktualisieren' <BR> JNB P1.4,Minuten 'Minuten einstellen' <BR> LCALL Refresh <BR> JNB P1.5,Sekunden 'Sekunden einstellen' <BR> LCALL Refresh <BR> JNB P3.4,Start 'Start des Timers' <BR>IF BIT P1.4 THEN CLR D1h'Lösche BIT D1h im PSW, wenn P1.4 high' <BR>IF BIT P1.5 THEN CLR D1h'Lösche BIT D1h im PSW, wenn P1.5 high' <BR> LJMP Tasten <BR> <BR>'Routine zum Sekunden einstellen' <BR>Sekunden: <BR> CLR P1.5 'Lösche Taster-BIT zur Entprellung' <BR> DEC R3 'R3 = R3 - 1' <BR> LCALL Refresh <BR> IF R3 = #FFh THEN 'Ist R3 übergelaufen?' <BR> MOV R3,#09 'Dann setze R3 auf 09. <BR> DEC R2 'R2 = R2 - 1' <BR> LCALL Refresh <BR> END IF <BR> IF R2 = #FFh THEN 'Ist R2 übergelaufen?' <BR> MOV R2,#05 'Dann setze R2 auf 05. <BR> LCALL Refresh <BR> END IF <BR> SETB P1.5 'Setze wieder Taster-BIT.' <BR> JB D1h,Tasten 'Ist BIT D1 gesetzt? Dann schnell zählen.' <BR> PUSH B 'Rette B auf den Stack.' <BR> MOV B,#03h 'Schreibe 03 ins B Register' <BR> <BR>'Warte ob Taste etwas länger gedrückt wird, dann zähle' <BR>'schneller rückwärts.' <BR>warte_3: <BR> LCALL Refresh <BR> MOV R7,#05 'Schreibe 05 in Register R7.' <BR> <BR>warte_4: <BR> LCALL Refresh <BR> DJNZ R7,warte_4 'Springe zu warte_4 bis R7 = 0.' <BR> DJNZ B,warte_3 'Springe zu warte_3 bis B = 0.' <BR> SETB D1h 'Setze BIT D1h zum schnell zählen.' <BR> POP B 'Stelle B wieder her' <BR> LJMP Tasten <BR> <BR>'Vorzeitiges Anhalten des Timers und Rücksprung auf' <BR>'voreingestellte Zeit "Clocktus Interruptus":-)' <BR>stop: <BR> CLR TR0 'Timer 0 aus' <BR> SETB P3.7 'Relais aus' <BR> CLR D5h 'Flag D5h löschen' <BR> LCALL speicher_lesen 'Zeit auf Start stellen' <BR> LJMP Tasten <BR> <BR>'Zähle rückwärts' <BR>Countdown: <BR> LCALL Refresh <BR> JB D5h,STOP 'Ist Flag BIT D5h gesetzt, dann Stop' <BR> JNB P3.5,STOP 'Timer Countdown Abbruch' <BR> LJMP Countdown'Springe zu Countdown, bis D5h = 1, oder P3.5 = 0.' <BR> <BR>'Eingestellte Zeit speichern ab Adresse 00 (siehe oben)' <BR>Zeit_speichern: <BR> LCALL Startbedingung_erzeugen <BR> MOV A,#schreiben <BR> LCALL 8_Bits_senden <BR> MOV A,#Adresse <BR> LCALL 8_Bits_senden <BR> MOV A,R0 <BR> LCALL 8_Bits_senden <BR> MOV A,R1 <BR> LCALL 8_Bits_senden <BR> MOV A,R2 <BR> LCALL 8_Bits_senden <BR> MOV A,R3 <BR> LCALL 8_Bits_senden <BR> LCALL Stopbedingung_erzeugen <BR> RET <BR> <BR>'Routinen zum Anzeigen und aktualisieren der Zeit' <BR>Refresh: <BR> MOV A,R0 'Schreibe Wert von R0 in den Akku' <BR> LCALL Schiebe 'und zeige ihn in "Anzeige 1 an.' <BR> LCALL Anzeige_1 <BR> MOV A,R1 'Schreibe Wert von R1 in den Akku' <BR> LCALL Schiebe 'und zeige ihn in "Anzeige 2 an.' <BR> LCALL Anzeige_2 <BR> MOV A,R2 'Schreibe Wert von R2 in den Akku' <BR> LCALL Schiebe 'und zeige ihn in "Anzeige 3 an.' <BR> LCALL Anzeige_3 <BR> MOV A,R3 'Schreibe Wert von R3 in den Akku' <BR> LCALL Schiebe 'und zeige ihn in "Anzeige 4 an.' <BR> LCALL Anzeige_4 <BR> RET <BR> <BR>Schiebe: <BR> RRC A 'Schiebe den Akkuinhalt um eine Stelle' <BR> MOV P3.0,C 'nach rechts ins Carry Flag und schreibe' <BR> RRC A 'den Inhalt des Carry Flag in BIT P3.0' <BR> MOV P3.1,C 'bis BIT P3.3 des Port 3.' <BR> RRC A 'Hierdurch steht die Binäre 4 BIT' <BR> MOV P3.2,C 'Information an den Eingängen des IC 4511' <BR> RRC A 'und kann durch den BCD / 7-Segment-' <BR> MOV P3.3,C 'Dekoder (4511) zur Anzeige gebracht' <BR> RET 'werden.' <BR> <BR>Anzeige_1: 'Lösche BIT P1.0 in Port 1 und schalte' <BR> CLR P1.0 'dadurch den Transistor (für ca. 5ms,' <BR> LCALL 1ms 'nicht genau) der ersten Anzeige durch.' <BR> SETB P1.0 'Dann setze das BIT wieder und sperre' <BR> RET 'damit den Transistor.' <BR>Anzeige_2: 'wie bei Anzeige_1, aber BIT P1.1' <BR> CLR P1.1 <BR> LCALL 1ms <BR> SETB P1.1 <BR> RET <BR>Anzeige_3: 'wie bei Anzeige_1, aber BIT P1.2' <BR> CLR P1.2 <BR> LCALL 1ms <BR> SETB P1.2 <BR> RET <BR>Anzeige_4: 'wie bei Anzeige_1, aber BIT P1.3' <BR> CLR P1.3 <BR> LCALL 1ms <BR> SETB P1.3 <BR> RET <BR> <BR>'Verzögerungs Routine für Anzeige' <BR>'Zeitverzögerung entspricht ungefähr 5ms' <BR>1ms: <BR> MOV R4,#%10 'Schreibe 10 in Register R4.' <BR>eins: <BR> MOV R5,#%250 'Schreibe 250 in Register R5.' <BR>zwei: <BR> DJNZ R5,zwei 'Springe zu zwei bis R5 = 0.' <BR> DJNZ R4,eins 'Springe zu eins bis R4 = 0.' <BR> NOP <BR> RET <BR> <BR>'Routinen zum speichern und lesen der Zeit,' <BR>'sowie Routinen zur Steuerung des I2C Busses.' <BR>Startbedingung_erzeugen: <BR> SETB SDA 'Vorbereitung zur Startbedingung' <BR> SETB SCL <BR> JNB SDA,Bus_frei 'Ist der Datenbus frei?' <BR> JNB SCL,Bus_frei 'Ist der Datenbus frei?' <BR> NOP <BR> CLR SDA 'SCL high / SDA geht auf low' <BR> LCALL 5µs <BR> CLR SCL <BR> CLR C <BR> JMP I2C_zurück <BR> <BR>Bus_frei: <BR> SETB C 'Setze Carry BIT wenn Datenbus besetzt.' <BR> 'Wird aber in diesem Programm nicht abgefragt,' <BR> 'da nur ein I2C Baustein angeschlossen.' <BR>I2C_zurück: <BR> RET <BR> <BR>Stopbedingung_erzeugen: <BR> CLR SDA 'Vorbereitung zur Stopbedingung' <BR> NOP <BR> NOP <BR> SETB SCL 'SCL high / SDA geht auf high' <BR> LCALL 5µs <BR> SETB SDA <BR> RET <BR> <BR>Acknowledge: 'BIT vom I2C-Baustein (hier EEPROM)' <BR> CLR SDA 'zur Bestätigung, dass das' <BR> NOP 'Datenwort korrekt angekommen ist. <BR> NOP <BR> SETB SCL <BR> LCALL 5µs <BR> CLR SCL <BR> RET <BR> <BR>No_Acknowledge: 'siehe oben, nur diametral' <BR> SETB SDA <BR> NOP <BR> NOP <BR> SETB SCL <BR> LCALL 5µs <BR> CLR SCL <BR> RET <BR> <BR>'Daten sind im AKKU' <BR>8_Bits_senden: <BR> PUSH B 'Rette Inhalt von B auf den Stack.' <BR> MOV B,#8 'Wird in diesem Programm eigentlich' <BR> 'nicht benötigt, nur zum "Angewöhnen"' <BR>8_Bits: 'für später :-)' <BR> RLC A 'Schiebe den Akkuinhalt nach links' <BR> MOV SDA,C 'durch das Carry Flag um ihn Bitweise' <BR> NOP 'zu senden.' <BR> SETB SCL <BR> LCALL 5µs <BR> CLR SCL <BR> DJNZ B,8_Bits <BR>'Hole Acknowledge BIT vom Slave (9. BIT, Empfangsbestätigung)' <BR> SETB SDA <BR> NOP <BR> NOP <BR> SETB SCL <BR> LCALL 5µs <BR> MOV C,SDA <BR> CLR SCL <BR> POP B 'Stelle B wieder her (vom Stack holen)' <BR> RET <BR> <BR>'Daten in den Akku lesen' <BR>8_Bits_lesen: <BR> SETB SDA <BR> PUSH B 'siehe oben' <BR> MOV B,#8 <BR> <BR>8_Bits_1: <BR> NOP <BR> NOP <BR> NOP <BR> SETB SCL <BR> NOP <BR> NOP 'Die Daten aus dem I2C-Baustein werden' <BR> MOV C,SDA 'in das Carry Flag geschrieben und' <BR> RLC A 'nach links in den Akku geschoben.' <BR> CLR SCL <BR> DJNZ B,8_Bits_1 <BR> POP B 'siehe oben' <BR> RET <BR> <BR>'Zeitverzögerung von ca. 5µs.' <BR>5µs: <BR> NOP <BR> NOP <BR> NOP <BR> NOP <BR> NOP <BR> RET <BR>