Forum: Mikrocontroller und Digitale Elektronik ATTiny USI I2C-Master


von Ronald (Gast)


Lesenswert?

Bei USI-Nutzung für I2C wird immer auf AN310 und die Library
von P. Fleury verwiesen. Gilt das erst ab ATMega128?

"Target: any AVR device with hardware TWI"

Bei den üblichen ATTinys hilft es wenig:

Da funktioniert es mit I/O-Registern von USI/TWI, die schwer,
oder garnicht nachzuempfinden sind:

TWCR =? USICR
TWDR =? USIDR
Beim Takt wird es noch schwieriger:
TWSR (Prescaler) und TWBR (Baudrate): Fehlanzeige, da muss ein
externer Clock her, oder mit Timer0-Compare-Match gearbeitet werden.

Mit Bit-Banging werde ich es schon hinbekommen, aber warum soll
die vorhandene USI nicht auch was zu tun bekommen?

von Karl M. (Gast)


Lesenswert?

Hallo,

Glückauf!

ich würde dann eher eine schon vorhandene Veröffentlichung nehmen/ 
versuchen:

https://www.mikrocontroller.net/articles/USI
https://github.com/JDat/AtTiny-I2C-master-slave-USI
https://github.com/puuu/USIWire

Oder doch lieber einen der Neuen, z.B. den Attiny841 usw., oder gleich 
eine Atmega nutzen.

Damit hat man dann noch weniger Probleme!

von Karl B. (gustav)


Lesenswert?

Ronald schrieb:
> Mit Bit-Banging werde ich es schon hinbekommen, aber warum soll
> die vorhandene USI nicht auch was zu tun bekommen?

Hi,
da gab es schon mal einen Thread.

Beitrag "Anfänger Will ATtiny2313 mit Display uber I2C verbinden"

Man bekommt zur Not damit ein mit Portadapter ausgerüstetes LCD 
testweise zum Laufen.
Die Sache hat nur einen Haken:
Beim SPI-Flashen mit STK500 Board zum Beispiel sollten die Anschlüsse 
zum LCD abgezogen werden.


ciao
gustav

: Bearbeitet durch User
von Roland (Gast)


Lesenswert?

Beim ATTiny2313A habe ich die USI dafür mal probeweise verwendet.
Die übernimmt dann aber nur das Herausschieben der 8Bit über die USI 
Register. Den Rest, also das Umschalten der SDA- und SCL- Leitungen 
zwischen Tristate und Ausgang muss man aber trotzdem noch separat 
erledigen. Dann kann man auch gleich die Handvoll Zeilen zusätzlich 
spendieren um 8 SCL Pulse zu erzeugen und das Datenbyte entsprechend am 
SDA ausgeben. Damit kann man dann auch jeden beliebigen Portpin 
verwenden ohne die USI.

Hier zwei Beispiele, um 8Bit über die USI auszugeben und einmal ohne die 
USI auszugeben

•
1
// 8 Datenbits per USI ausgeben
2
USIDR = data; // Datenbyte ans USI Register übergeben
3
USISR = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC);  // USI Flags und Counter löschen
4
    
5
          
6
// solange das Flag "USIOIF" low ist, wird das USCK Pin getoggelt (1 << USITC), bis alle 8 Bit herausgeschoben sind.
7
while (!(USISR & (1 << USIOIF))) USICR = (1 << USIWM1) | (1 << USICS1)| (1 << USICLK) | (1 << USITC);
8
9
10
11
12
13
14
15
16
// 8 Datenbits ohne USI ausgeben (SDA an PORT A1   SCL an PORT A0)
17
for (unsigned char i = 8; i > 0; i--)
18
{
19
  if (data & (1 << 7))    // falls das MSB eine "Eins" ist
20
  DDRA &= ~(1 << DDA1);    // SDA Pin auf Eingang umschalten (ext Pull-Up zieht ihn high)
21
  else        // sonst
22
  DDRA |= (1 << DDA1);    // SDA Pin auf Ausgang umschalten (Port zieht ihn auf low)
23
  data <<= 1;      // einmal linksschieben 
24
    
25
  // Clockpuls
26
  DDRA &= ~(1 << DDA0);    // SCL Pin auf Eingang umschalten (ext Pull-Up zieht ihn high)
27
  DDRA |= (1 << DDA0);    // SCL Pin auf Ausgang umschalten (Port zieht ihn auf low)
28
}

von Ronald (Gast)


Lesenswert?

Erst mal schönen Dank für die schnellen Antworten.

Den Eindruck, dass die USI nicht viel Arbeit abnimmt, habe ich beim
Betrachten des Codes von der github-Seite auch gewonnen.
Besonders doof ist, dass es wohl kein Hardware-Timing, wie bei
einer USART gibt.

- Naja, habe ich Beschäftigung für graue Novemberabende. ;-)

von M. K. (sylaina)


Lesenswert?

USI ist halt so eine eierlegende Wollmilchsau. Nen wenig nimmt es Arbeit 
ab aber etwas mehr Arbeit als bei UART/I2C/SPI muss man auch 
reinstecken. Eigentlich recht kniffig das Modul wenn man mal 
durchgestiegen ist.

von c-hater (Gast)


Lesenswert?

Ronald schrieb:

> Den Eindruck, dass die USI nicht viel Arbeit abnimmt, habe ich beim
> Betrachten des Codes von der github-Seite auch gewonnen.

Du hättest besser das Datenblatt betrachten sollen...

> Besonders doof ist, dass es wohl kein Hardware-Timing, wie bei
> einer USART gibt.

...dann wüsstest du z.B., das man das USI mit Timer0 als Taktquelle 
betreiben kann.

von Ronald (Gast)


Lesenswert?

Oha,  c-hater  weiß mehr?

Dann zeig doch bitte nur mal so ein paar Anregungen.

Ja, Timer/Counter0 Compare Match könnte die Ausgabe eines
Bytes, oder den Empfang eines Bytes unterstützen. Ist aber
auch zu-Fuß-codiert keine Herausforderung...

Das kompliziertere Timing für START, STOP, ACK, NAK etc.
muss ich weiter bit-bangen.

Oder hast du dazu hilfreiche Tipps???
.asm ist für mich kein Problem.

von c-hater (Gast)


Lesenswert?

Ronald schrieb:

> Ja, Timer/Counter0 Compare Match könnte die Ausgabe eines
> Bytes, oder den Empfang eines Bytes unterstützen. Ist aber
> auch zu-Fuß-codiert keine Herausforderung...

Es geht nicht darum, ob es eine Herausforderung ist oder nicht, sondern 
es geht darum, dass man so die ganze Zeit, die die Ein- oder Ausgabe 
eines Bytes dauert, zur Verfügung hat, um andere Sachen zu tun, z.B. das 
zuvor empfangene Byte zu verarbeiten oder das nächste zu versendende 
Byte bereitzustellen. Das I2C-Zeugs ist ja kein Selbstzweck, sondern 
dient letztlich nur dazu, Daten zu transportieren, die irgendwo 
hergeholt oder verarbeitet werden müssen. Da wäre es doch vollkommen 
unsinnig, die gesamte wertvolle Rechenzeit damit zu verschwenden, einen 
Pumpenschwengel zu bewegen, um den Datentransport am Laufen zu halten. 
Genau darin, das eben nicht zwingend tun zu müssen, besteht der 
wesentliche Nutzen des USI.

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> unsinnig, die gesamte wertvolle Rechenzeit damit zu verschwenden, einen
> Pumpenschwengel zu bewegen, um den Datentransport am Laufen zu halten.
> Genau darin, das eben nicht zwingend tun zu müssen, besteht der
> wesentliche Nutzen des USI.

Ergänzend: Die Sache mit der "handbetätigten Pumpe" ist im Wesentlichen 
nur als Erleichterung für C-only-Dumbsters zu verstehen. Ein 
Assmblerprogrammierer braucht sowas normalerweise nicht, der kann 
busy-loops auch ohne Hardware-Unterstützung taktgenau implementieren. 
Nur für extrem hohe Bitraten ist es auch in Asm manchmal nützlich, 
diesen "manuellen Pumpenschwengel" zu haben, der sich mit einem einzigen 
Takt betätigen läßt. Er erleichtert es, den Rest der Chose zu 
implementieren.

Diese Möglichkeiten sind allerdings für I2C-Anwendungen des USI eher 
irrelevant, für SPI hingegen können sie schon durchaus attraktiv sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.