Hallo
Wir benutzen den AT89S52.
Wollen eine I²C Verbindung zu einer Eingabeplatine bestehend aus 8
Schaltern mit dem PCF8574P aufbauen.
Ausgegeben soll der Zustand über 8 LEDs auf dem µC-Board, welche am P0
angeschlossen sind.
Mit dem unten stehenden Code klappt dies auch, einzige Einschränkung
ist, dass wenn wir den achten Schalter betätigen und dann mit P3.2 bzw
P3.3 das Bitmuster auf die LEDs übertragen wollen, diese machen was sie
wollen. Kann es sein das hiermit das Carrybit geschrieben wird? Also ein
Übertrag?
Was müßten wir machen damit dies funktioniert?
#include "8051.h"
#include "I2C_ASM.h"
;
; 8574er Kennung: 0100xxxy
;
SEND000 .equ 01000000b ; ON ON ON
SEND001 .equ 01000010b ; ON ON off
SEND010 .equ 01000100b ; ON off ON
SEND100 .equ 01001000b ; off ON ON
SEND101 .equ 01001010b ; off ON off
;
READ000 .equ 01000001b ; ON ON ON
;
MAIN
LOOP
TASTEN
jnb P3.2, UNDLOS ; Taster KISS-Board
jnb P3.3, UNDLOS ; Taster 8574-Platine
ljmp TASTEN
UNDLOS lcall I2C_START
mov A, #READ000
lcall I2C_WRITE
lcall I2C_READ
lcall I2C_STOPP
mov P0, A
ljmp LOOP
.end
da wird kein Carry geschrieben.
Um den Fehler zu finden brauchen wir schon den Rest von Code.
Carry wird bei math. Operationen geändert und beim schieben über Carry.
Am P0 sind ja die LEDs
Also wenn der achte Schalter ein ist und dann mit den Tastern das Muster
übertragen werden soll, ist mal die achte LED ein, mal nur halb so hell,
mal aus - immer anders.
Anders herum.
auf dem µC-Board sind auch 8 Taster. Wenn ich von hier auf eine
Ausgabeplatine sende, klappt dies und es gibt keinen Fehler.
Dafür benutze ich folgenden Code:
#include "8051.h"
#include "I2C_ASM.h"
;
; 8574er Kennung: 0100xxxy
;
SEND000 .equ 01000000b ; ON ON ON
SEND001 .equ 01000010b ; ON ON off
SEND010 .equ 01000100b ; ON off ON
SEND100 .equ 01001000b ; off ON ON
SEND101 .equ 01001010b ; off ON off
;
READ000 .equ 01000001b ; ON ON ON
;
MAIN
LOOP
TASTEN
jnb P3.2, UNDLOS ; Taster KISS-Board
jnb P3.3, UNDLOS ; Taster 8574-Platine
ljmp TASTEN
UNDLOS lcall I2C_START
nop
nop
nop
nop
mov A, #SEND000
lcall I2C_WRITE
nop
nop
nop
mov A, P2
lcall I2C_WRITE
nop
nop
nop
lcall I2C_STOPP
mov P0, A
ljmp LOOP
.end
Mov F0,x ??
Woher kommt das Bit für F0 ?
Über I²C werden 8 Bits eingelesen.
Wenn es das 8te Bit ist dann eben
Mov F0,A.7
nachdem alle 8 eigelesen wurden.
Man kann auch Mov F0,C schreiben. das letzte Bit bleibt ja im C.
langsam....
Im I²C read Teil wollt ihr die Schleife mit Afrage des F0 beenden.
jbc F0,I2C_READ_ACK ;F0=1 => NACK (SDA=H, s.o.)
Ihr "füttert" F0 aber nicht in der Schleife. !!
Ihr macht: I²C write, Read ohne F0 zu tangieren und dann stop.
Wie bitte wollt Ihr JBC F0 erfüllen ???
im I²C_read_Wait ???
Nicht am Symtom basteln !! Die Ursache finden !!
Ob im PSW oder sonstwo. Flags müssen gesetzt und gelöscht werden !!
Nur sehe ich nichts vom setzen !!
Ralf schrieb:
> F0 ist ein frei verwendbares Flag im PSW, wenn ich's richtig im Kopf> habe.>> Ralf
Jepp, ist richtig. Trotzdem muss es gesetzt werden wenn man mit
JBC F0 arbeiten will.
Das heist ja nur Springe wenn F0 gesetzt nach xy und lösche F0.
Stefan schrieb:
> liegt das also doch am Carry-Bit oder was heißt das für mich?
Das heißt nur das Du F0 als Flag nie benutzt hast.
Du hast es gelesen, aber nie gesetzt !!
Ich hasse I²C wie die Pest und bin daher auch nicht fit damit.
Aber ich denke das Stoppbit sollte nach F0.
Also 8 bit +1 Soppbit lesen. Read Schleifeenzähler mit #9 laden.
Aber nur 8 Mal RLC A machen. Das letzte Bit im c nach F0 laden.
Dann weißt Du das alles gesendet wurde und sendest dann dein ACK.
Vermutlich...
Stefan schrieb:
> Muß ich dieses F0 überhaupt verwenden? Oder kann man das in der> Header-Datei ändern, das dieses überhaupt nicht aufgerufen wird?
Wer soll das beantworten ? DU mußt wissen was Du willst.
Du mußt F0 nicht benutzen. Du kannst auch ein anderes Flag definieren.
Du kannst auch JB c,xy nehmen wenn im Carry Dein Stopbit ist und auf ein
zusätzliches Flag ganz verzichten. Schau Dir andere Routinen im Web an.
Aber nicht einfach nur kopieren, und geht. Dabei lernt man nicht. Diese
Fragen sollte eigentlich Dein PAP beantworten.