Hallo zusammen,
heute habe ich keine Frage, sondern eine Lösung für ein Problem, dass
mich seit Tagen verfolgt hat.
Ich habe einen ATTiny 24, mit dem ich über das USI - Universal Serial
Interface eine TWI (I^2C) Verbindung zu einem DAC hergestellt habe. Ich
habe die Atmel AppNote AVR310 (Using USI Module as a I^2C master) zu
Hilfe genommen und meinen Code eingearbeitet.
Folgendes Problem kam zu tage: Die Clockleitung (SCL) ging nicht wie
erwartet auf +5V und das Programm hing sich in folgender Subroutine in
der gezeigten Codezeile auf:
1 | unsigned char USI_TWI_Master_Transfer(unsigned char temp)
|
2 | {
|
3 | USISR = temp;
|
4 | ...
|
5 | do
|
6 | {
|
7 | ...
|
8 | while(!(PIN_USI & (1<<PIN_USI_SCL)) ); // hier hing das Programm und SCL blieb Low
|
9 | ...
|
10 | }while(!(USISR & (1<<USIIOIF)) );
|
11 | ...
|
12 | }
|
Nach zig Versuchen und Nachforschungen im Internet und auch hier im
Forum konnte ich keinen Fehler finden.
Ich habe mir dann einen Auszug aus dem Datenblatt ausgedruckt und
intensiv nach überlesenen Informationen gesucht und letztlich auch
gefunden.
Alles hing am fehlenden Pull-Up Widerstand an der SCL und der SDA
Leitung.
Da muss man erstmal darauf kommen, weil im Beispielcode von Atmel steht
bei der Initialisierung ganz am Anfang PullUp Enable:
1 | void USI_TWI_Master_Initialise( void )
|
2 | {
|
3 | PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.
|
4 | PORT_USI |= (1<<PIN_USI_SCL); // Enable pullup on SCL, to set high as released state.
|
5 |
|
6 | DDR_USI |= (1<<PIN_USI_SCL); // Enable SCL as output.
|
7 | DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.
|
8 |
|
9 | USIDR = 0xFF; // Preload dataregister with "released level" data.
|
10 | USICR = (0<<USISIE)|(0<<USIOIE)| // Disable Interrupts.
|
11 | (1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode.
|
12 | (1<<USICS1)|(0<<USICS0)|(1<<USICLK)| // Software stobe as counter clock source
|
13 | (0<<USITC);
|
14 | USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags,
|
15 | (0x0<<USICNT0); // and reset counter.
|
16 |
|
17 | }
|
Doch im Datenblatt des ATTiny24 steht "im Kleingedruckten":
- Kapitel 14 (USI),
- Abschnitt 5 (Register Description)
- 14.5.1 USICR - USI Control Register,
- WireMode Einstellung (USIWM1:0),
in der Tabelle letzter Satz bei USIWM1=1 und USIWM0=0:
"Pull-ups on the SDA and SCL port pin are disabled in Two-wire mode."
Nachdem ich dann externe PullUps eingelötet habe, funktionierte alles
tadellos!
Falls jemand also das Problem hat, bitte mal nachschauen.