; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ; ¤ ¤ ; ¤ 4. TINF Projekt ¤ ; ¤ ¤ ; ¤ Ausgabe: ¤ ; ¤ 16.02.2006 ¤ ; ¤ ¤ ; ¤ SAR ADC ADS7823 ¤ ; ¤ 12 Bit I2C ¤ ; ¤ ¤ ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ; ¤ ¤ ; ¤ Thomas Graser ¤ ; ¤ & ¤ ; ¤ Patrick Schiesser ¤ ; ¤ ¤ ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ ; ¤ ¤ ; ¤ Portbelegung: ¤ ; ¤ p1.6 -> SCL ¤ ; ¤ p1.7 -> SDA ¤ ; ¤ ¤ ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ $include(REG552.INC) ; Code © by Thomas 'GrAzA' Graser 2006 ; V0.X: 17.02.06 - ... ; Hauptrogramm main: scl bit p1.6 ; Port 1 Bit 6 als "SCL" definieren sda bit p1.7 ; Port 1 Bit 7 als "SDA" definieren ; Schreib-Adresse & Kontroll-Byte senden call start mov a,#10010000b ; Slave Adresse zum Schreiben senden call send mov a,#00010101b ; Control Byte senden call send call stop call delay ; Werte auslesen call start mov a,#10010001b ; Slave Adresse zum Lesen senden call send call read ; 1. Datenpaket auslesen ; 0000 XXXX mov b,#00110000b add a,b jnb ti,$ clr ti mov s0buf,a ; und ans Terminal schicken call stop jnb ti,$ mov s0buf,#07h ; Windows-Standart-Ton ausgeben, Programm fertig ende: call 8cb0h ; Monitorrücksprung ; Unterprogramme ; Delay ; ~100µs warten ; 49mal 2 Zyklen á ~1µs ; Zählwert für schnelle I²C Geräte evtl. kleiner delay: mov r7,#09h ; 31h (49d) auf Register 7 schreiben ; #09h minimal für LCD LPH3827 djnz r7,$ ; Register 7 verringern, und warten bis 0 ret ; Wait ; ~500µs warten ; 249mal 2 Zyklen á ~1µs ; Zählwert für schnelle I²C Geräte evtl. kleiner wait: mov r7,#09h ; 0f9h (249d) auf Register 7 schreiben ; #09h minimal für LCD LPH3827 djnz r7,$ ; Register 7 verringern, und warten bis 0 ret ; Startbedingung ; SDA löschen, während SCL gesetzt bleibt, und dann SCL löschen... start: clr sda ; SDA löschen call delay clr scl ; SCL löschen call wait ret ; Stoppbedingung ; SCL setzen, dann SDA setzen während SCL gesetzt bleibt... stop: setb scl ; SCL setzen call delay setb sda ; SDA setzen call wait ret ; 1 Taktimpuls ; warten, SCL setzen, warten, löschen, warten... takt: setb scl ; SCL setzen call delay clr scl ; SCL löschen call wait ret ; Acknowledge einlesen ; warten, SCL setzen, warten, Bit einlesen, warten, SCL löschen, warten... ack: setb sda call wait setb scl ; SCL setzen call wait mov c,sda ; SDA auf CarryFlag schreiben mov a,#12d ; Akku ausräumen rlc a ; CarryFlag aufs LSB vom Akku jnb ti,$ ; Aufs TI-Flag warten clr ti ; dann löschen mov s0buf,a ; 'Blank' -> erfolgreich, Rufzeichen -> nicht erfolgreich! clr scl ; SCL löschen call wait ret ; Daten aus dem Akku senden ; 8 Bit Daten übertragen, 8mal takten und 1mal Acknowledge einlesen send: mov r2,#08h ; 8 hexadezimal ins Register 2 schreiben send2: rlc a ; MSB des Akku in das CarryFlag rotieren mov sda,c ; C auf SDA schreiben call takt ; Bit übertragen djnz r2,send2 ; Nach 8mal senden, weitergehen call ack ; takt bzw. ack ersetzen, falls Acknowledge benötigt wird, ansonsten abtakten ret ; Daten in den Akku lesen read: mov a,#00h mov r2,#08h ; 8 hexadezimal ins Register 2 schreiben read2: setb scl ; Takt setzen call wait mov c,sda ; SDA aufs CarryFlag laden rlc a ; und dieses aufs LSB vom Akku rotieren clr scl ; Takt löschen call wait djnz r2,read2 ; 8mal Schleife durchlaufen mov r6,a ; Akku retten call ack ; takt bzw. ack ersetzen, falls Acknowledge benötigt wird, ansonsten abtakten mov a,r6 ; Akku wiederherstellen ret end