Hallo Leute
Ich habe einen DS1307 (I2C RTC, Batteriegepuffert) und 7 TLC59116 (I2C
LED Controller) zusammen an einen Mega16 angeschlossen, inklusive den
4,7k Pullups an SDA und SCL.
Im Moment bin ich vom Programm her soweit, dass ich aus dem DS1307 die
Uhrzeit auslesen kann und auch eine andere reinschreiben kann. Die
TLC59116 bleiben bis jetzt noch außen vor und werden erst später in den
Code mit integriert.
Ich nutze als I2C-Code-Basis die Bibliotheken von Peter Fleury. Jetzt
habe ich aber das Problem, dass ab und zu der Controller in folgender
Routine hängen bleibt
1 | unsigned char i2c_write( unsigned char data_byte )
|
2 | {
|
3 | uint8_t twst;
|
4 |
|
5 | // send data to the previously addressed device
|
6 | TWDR = data_byte;
|
7 | TWCR = (1<<TWINT) | (1<<TWEN);
|
8 |
|
9 | // wait until transmission completed
|
10 | while(!(TWCR & (1<<TWINT)));
|
11 |
|
12 | // check value of TWI Status Register. Mask prescaler bits
|
13 | twst = TW_STATUS & 0xF8;
|
14 | if( twst != TW_MT_DATA_ACK) return 1;
|
15 | return 0;
|
16 |
|
17 | }/* i2c_write */
|
Das weiß ich zum Glück dank JTAG so genau :-) Hängen bleibt er genau
hier in dieser Zeile:
1 | while(!(TWCR & (1<<TWINT)));
|
Wie gesagt oft funktionierts aber manchmal eben nicht. Ist euch sowas
bekannt?
Ich hatte mir schon überlegt, die while-Schleife um eine zweite
Abbruch-Bedingung zu erweitern:
1 | // wait until transmission completed or timeout
|
2 | i2c_timeout_flag = 0;
|
3 | while( !(!(TWCR & (1<<TWINT)) || i2c_timeout_flag>3) );
|
Die Variable i2c_timeout_flag sollte dann in einer Timerschleife
hochgezählt werden. Im Simulator funktionierts, zumindest die logisch
Verknüpfung
1 | ( !(!(TWCR & (1<<TWINT)) || i2c_timeout_flag>3) )
|
Aber in real spinnt der Controller dann an einer anderen Stelle, beim
I2C-Stop-Kommando bleibt er hängen:
1 | void i2c_stop(void)
|
2 | {
|
3 | /* send stop condition */
|
4 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
|
5 |
|
6 | // wait until stop condition is executed and bus released
|
7 | while(TWCR & (1<<TWSTO));
|
8 |
|
9 | }
|
Im Moment bin ich echt etwas ratlos :( Habt ihr eine Idee?
Die Signale auf SDA und SCL hab ich mir mit dem Oszi angesehen und sehen
normal aus. Auch ist der Takt sauber bei 100kHz.
Danke schon mal für eure Hilfe.