PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C und SAA1046



Dennis Prinz
29.12.2014, 17:14
moin

Ich habe da mal eine Frage. Wir sollen im Rahmen eines Schulprojektes zwei Platinen mittels I2C verbinden. Das eine ist ein sogenanntes KISSBoard mit einem Atmel AT89S52 und das andere ist eine sogenannte I2C-Experimentier Platine auf der 4 7-Segment anzeigen verbaut sind die mittels SAA1064 angesteuert werden sollen. Mein Problem ist das ich immer entweder Anzeige 1 und 3 oder 2 und 4 oder alle 4 ans Leuchten bekomme. Diese Steuer ich über das control byte an. Ich bekomme es aber nicht hin das ich die einzelnen Segmente jeweils eine Zahl oder Zeichen anzeigen lassen kann.

Mein Programm Codes sieht derzeit so aus


while(1)
{
if(TASTER==0)
{

I2C_clock(); //clock
I2C_start(); //start
I2C_write(0b01110000); //address Byte
I2C_ack();
I2C_write(0b00000000); //instruction Byte
I2C_ack();
I2C_write(0b01110111); // control Byte
I2C_ack();
I2C_write(0b10101010); // data digit 1
I2C_ack();
I2C_write(0b01010101); // data digit 2
I2C_ack();
I2C_write(0b01010101); // data digit 3
I2C_ack();
I2C_write(0b10101010); // data digit 4
I2C_ack();
I2C_stop(); //stop
}

das was die einzelnen Segmente anzeigen sollen ist hier gerade nicht logisch da ich das erst einmal zum Testen so eingestellt habe um zu schauen ob überhaupt was passier.

Ich würde mich darüber freuen eine schnelle und Anfänger freundliche Antwort zu bekommen

gruß

Crazy Harry
29.12.2014, 17:56
Du meinst den SAA1064 ? Wie sieht die Initialisierung aus ?

- - - Aktualisiert - - -

Ändere mal dein Control-Byte auf 0b01000111

Dennis Prinz
29.12.2014, 17:59
hey,

ja da ist mir wohl ein Zahlendreher unterlaufen. In welcher art und weise muss ich den was initialisieren weil im Datenblatt vom SAA steht nichts davon drin das der Initialisiert werden muss.

gruß

Crazy Harry
29.12.2014, 18:10
Das Control-Byte ist prinzipiell die Initialisierung. Später muss das nicht mehr gesendet werden, nur noch die Displaydaten.
Gehts jetzt ?

Dennis Prinz
29.12.2014, 18:21
also mit deinem Editierten Control Byte bleiben alle Anzeigen dunkel

Crazy Harry
29.12.2014, 18:36
Gibt es von dieser Platine einen Schaltplan ?

Ich geh davon aus, daß der Syntax und die Verwendung der I2C-Lib so richtig ist. Von Basic (?) hab ich keine Ahnung.

Bin SAA1064 schickst du einmal auf die richtige Adresse, SubAdress 0, ControlByte.
Versuchs mit 0b01110001 oder 0b01110111. Ok letzteres hattest du ja schon ;)

Später reicht es auf Adresse, SubAdress 1 die 4 Bytes zu senden, die angezeigt werden sollen.

Dennis Prinz
29.12.2014, 18:44
Hier ist mal der Schaltplan

29565

Die Syntax ist so richtig und wurde auch so umgesetzt.

Crazy Harry
29.12.2014, 18:53
Ok Standard SAA-Beschaltung.

Wenn du als Controlbyte 0b01001111 nimmst, sollten alle Segmente mit 12 mA leuchten. Das ist der Segmenttest.

Searcher
29.12.2014, 19:00
while(1)
{
if(TASTER==0)
{

I2C_clock(); //clock
I2C_start(); //start
I2C_write(0b01110000); //address Byte
I2C_ack();
I2C_write(0b00000000); //instruction Byte
I2C_ack();
I2C_write(0b01110111); // control Byte
I2C_ack();
I2C_write(0b10101010); // data digit 1
I2C_ack();
I2C_write(0b01010101); // data digit 2
I2C_ack();
I2C_write(0b01010101); // data digit 3
I2C_ack();
I2C_write(0b10101010); // data digit 4
I2C_ack();
I2C_stop(); //stop
}

das was die einzelnen Segmente anzeigen sollen ist hier gerade nicht logisch da ich das erst einmal zum Testen so eingestellt habe um zu schauen ob überhaupt was passier.


Passiert denn was? Welche Segmente werden denn mit dem Programm angezeigt?

Gruß
Searcher

Crazy Harry
29.12.2014, 19:09
Eigentlich sollten an Stelle 1 und 4 die Segmente b, d, f und Dezimalpunkt leuchten und an Stelle 2 und 3 die Segmente a, c, e und g.

Klebwax
29.12.2014, 19:46
@Dennis

Es ist natürlich schwer, einen Code zu analysieren, der nur aus Calls in eine unbekannte Library besteht.

Einiges kann man ahnen, anderes weniger.

I2C_start() und I2C_stop() dürften die entsprechenden Signale auf den Bus legen und I2C_write(xx) ein Byte senden. Aber was macht I2C_clock()? Die Clock auf einen Wert einstellen kann nicht sein, es gibt ja keinen Parameter und die Clock starten kann auch nicht sein, vor einem Start gibt es bei I2C keine Clock. Und was macht I2C_ack()? Ein ACK senden kann es nicht sein, das ACK kommt immer von dem, der gerade Daten empfangen hat. Und eine Abfrage, ob ein ACK empfangen wurde, kann es eigentlich auch nicht sein, dann würde ja irgendwas wie ein if im Code vorkommen.

Bevor das nicht wirklich geklärt ist, braucht man sich über Bitkombinationen keine Gedanken zu machen.

Hier mal kurz den Anfang einer I2C Übertragung:


Start erzeugen
Adressbyte senden
empfangenes ACK bzw NAK auswerten
wenn NAK
Slave antwortet nicht, Übertragung abbrechen
Stop erzeugen

wenn ACK
weiter senden
.
.

MfG Klebwax

Dennis Prinz
29.12.2014, 20:30
Crazy Harry

mit deinem Controllbyte für den Segment Test leuchten jetzt an Segment 1 a,c,e,g und punkt und an Segment 3 b,e,f und punkt

Irgenwie passt das alles Absolut nicht zu einander wenn ich alle Segmente mit voller Helligkeit und komplett anhaben möchte muss ich beim Controllbyte 0b01111111 angeben das habe ich aber auch nur mit probieren heraus gefunden wenn ich 0b01111011 angebe leuchtet Segment 1/3 voll und bei ob01110111 leuchten Segment 2/4 voll

- - - Aktualisiert - - -

Das ist der Code der die Daten über den I2C Bus sendet



#define SDA T1 /* Set P3.5 = SDA */
#define SCL T0 /* Set P3.4 = SCL */
#define I2C_DELAY 0x0F /* For delay i2c bus */

void I2C_delay(void)
{
unsigned char i;

for(i=0; i<I2C_DELAY; i++);
}

void I2C_clock(void)
{
I2C_delay();

SCL = 1; /* Start clock */

I2C_delay();

SCL = 0; /* Clear SCL */
}

void I2C_start(void)
{
if(SCL)
SCL = 0; /* Clear SCL */

SDA = 1; /* Set SDA */
SCL = 1; /* Set SCL */

I2C_delay();

SDA = 0; /* Clear SDA */

I2C_delay();

SCL = 0; /* Clear SCL */
}

void I2C_stop(void)
{
if(SCL)
SCL = 0; /* Clear SCL */

SDA = 0; /* Clear SDA */
I2C_delay();

SCL = 1; /* Set SCL */

I2C_delay();

SDA = 1; /* Set SDA */
}

bit I2C_write(unsigned char dat)
{
bit data_bit;
unsigned char i;

for(i=0;i<8;i++) /* For loop 8 time(send data 1 byte) */
{
data_bit = dat & 0x80; /* Filter MSB bit keep to data_bit */
SDA = data_bit; /* Send data_bit to SDA */

I2C_clock(); /* Call for send data to i2c bus */

dat = dat<<1;
}

SDA = 1; /* Set SDA */

I2C_delay();

SCL = 1; /* Set SCL */

I2C_delay();

data_bit = SDA; /* Check acknowledge */
SCL = 0; /* Clear SCL */

I2C_delay();

return data_bit; /* If send_bit = 0 i2c is valid */
}

unsigned char I2C_read(void)
{
bit rd_bit;
unsigned char i, dat;

dat = 0x00;

for(i=0;i<8;i++) /* For loop read data 1 byte */
{
I2C_delay();

SCL = 1; /* Set SCL */

I2C_delay();

rd_bit = SDA; /* Keep for check acknowledge */
dat = dat<<1;
dat = dat | rd_bit; /* Keep bit data in dat */

SCL = 0; /* Clear SCL */
}

return dat;
}

void I2C_ack()
{
SDA = 0; /* Clear SDA */

I2C_delay();

I2C_clock(); /* Call for send data to i2c bus */

SDA = 1; /* Set SDA */
}

void I2C_noack()
{
SDA = 1; /* Set SDA */

I2C_delay();

I2C_clock(); /* Call for send data to i2c bus */

SCL = 1; /* Set SCL */
}

Dennis Prinz
30.12.2014, 15:29
So ich habe den Fehler gefunden habe einfach nur das Datenblatt falsch interpretiert es hat bei mir klick gemacht als mir der hinweis gegeben wurde das ja das ACK bit vom Empfänger kommt und nicht vom sender nachdem ich das raus genommen habe funktionieren die Anzeigen wunder bar danke für eure schnelle und gute Hilfe

gruß
Dennis