<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Linux+80</id>
		<title>RN-Wissen.de - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Linux+80"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Linux_80"/>
		<updated>2026-04-11T14:46:21Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28418</id>
		<title>TWI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28418"/>
				<updated>2020-02-15T01:04:19Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: neues Achtung zum prescaler&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWI ('''T'''wo-'''w'''ire Serial '''I'''nterface) ist eine Bezeichnung von [[Atmel|Atmel]] für die auf vielen [[AVR|AVR]] Megas vorhandene  [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Hardware.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll nur auf Besonderheiten der [[AVR]]-[[Microcontroller]] eingegangen werden, Einzelheiten zu [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Merkmale =&lt;br /&gt;
&lt;br /&gt;
* Master- und Slavemodus&lt;br /&gt;
* Multimaster&lt;br /&gt;
* 7-Bit Adressierung (als Master auch 10-Bit Adressierung möglich)&lt;br /&gt;
* Übertragungsrate von bis zu 400kBit/s&lt;br /&gt;
&lt;br /&gt;
= TWI verwenden =&lt;br /&gt;
Um TWI mit dem [[AVR]] verwenden zu können sind einige Einstellungen nötig, die hier in Abhängigkeit der Anwendung aufgezeigt werden.&lt;br /&gt;
&lt;br /&gt;
== TWI-Register ==&lt;br /&gt;
Hier eine kurze Beschreibung der für den TWI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== TWBR ====&lt;br /&gt;
:Bit Rate Register, alle 8 bit&lt;br /&gt;
:dient zum einstellen des Bus-Taktes als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWCR ====&lt;br /&gt;
:Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWINT|TWEA|TWSTA|TWSTO|TWWC|TWEN|&amp;amp;ndash;|TWIE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:die Hauptschaltstelle befindet sich hier,&lt;br /&gt;
:*'''TWINT''' TWI Interrupt Flag&lt;br /&gt;
::Nach Abarbeitung der letzten Aktion wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''TWIE'' gesetzt ist.&lt;br /&gt;
::Es sollte anschliessend das Datenregister und das Statusregister ausgelesen werden und darauf entsprechend reagiert werden.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
::Mit dem zurücksetzen (löschen) von ''TWINT'' wird die nächste Aktion ausgelöst, es müssen deshalb vorher alle notwendigen Flags und Register (zB. ''TWDR'') entsprechend gesetzt werden.&lt;br /&gt;
:*'''TWEA''' TWI Enable Acknowledge Bit&lt;br /&gt;
::Sendet ein ACK nach einer Übertragung wenn&lt;br /&gt;
:::*als Slave die eigene Slaveadresse (''TWAR'') erkannt wurde,&lt;br /&gt;
:::*ein General Call erkannt wurde und das ''TWGCE''-Flag in ''TWAR'' gesetzt ist,&lt;br /&gt;
:::*ein ganz normales Byte als Slave oder als Master empfangen wurde.&lt;br /&gt;
:*'''TWSTA''' TWI Start Sequenz senden&lt;br /&gt;
::Die TWI-Hardware überprüft ob der Bus frei ist, und gibt die Startsequenz aus.&lt;br /&gt;
::Ist der Bus nicht frei, wartet das TWI-Modul bis eine Stopsequenz erkannt wurde und sendet die Startsequenz erneut.&lt;br /&gt;
::Dieses Flag muss per Software wieder gelöscht werden.&lt;br /&gt;
:*'''TWSTO''' TWI Stop Sequenz senden&lt;br /&gt;
::Als Master wird durch setzen eine Stopsequenz ausgegeben. Ist die Stopsequenz gesendet wird das Flag automatisch gelöscht.&lt;br /&gt;
::Als Slave kann dieses Flag zum zurücksetzen nach einem Fehler verwendet werden. Es wird keine Stopsequenz ausgegeben, aber das Modul beeinflusst anschliessend nicht mehr die Leitungen SCL oder SDA, das TWI-Modul befindet sich in einem definierten unadressierten Zustand.&lt;br /&gt;
:*'''TWWC''' TWI Write Collision Flag&lt;br /&gt;
::In das Datenregister ''TWDR'' sollte man nur schreiben, wenn ''TWINT'' High ist, ist ''TWINT'' Low, wird dieses Flag gesetzt und zeigt einen Fehler an.&lt;br /&gt;
:*'''TWEN''' TWI Enable&lt;br /&gt;
::Aktivieren des TWI-Moduls. Das TWI-Modul übernimmt u.a. die Steuerung über die Leitungen SCL und SDA.&lt;br /&gt;
:*'''TWIE''' TWI Interrupt Anforderung erlauben&lt;br /&gt;
::Interruptanforderung aktivieren, wenn eine Aktion durchgeführt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==== TWSR ====&lt;br /&gt;
:Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWS7|TWS6|TWS5|TWS4|TWS3|&amp;amp;ndash;|TWPS1|TWPS0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWSx''' TWI Status&lt;br /&gt;
::die oberen 5 Bit geben den Status der letzten Aktion wieder&lt;br /&gt;
:*'''TWPSx''' TWI Prescaler&lt;br /&gt;
::die zwei niederwertigen Bit zum einstellen des Prescaler als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWDR ====&lt;br /&gt;
:Data Register, alle 8 bit&lt;br /&gt;
:Beim Senden: nächstes Byte, das auf den Bus ausgegeben werden soll&lt;br /&gt;
:Beim Empfangen: letztes Byte, das über den Bus gekommen ist&lt;br /&gt;
:Die Daten sind gültig, solange das Bit ''TWINT'' in ''TWCR'' gesetzt ist&lt;br /&gt;
&lt;br /&gt;
==== TWAR ====&lt;br /&gt;
:Slave Address Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWA6|TWA5|TWA4|TWA3|TWA2|TWA1|TWA0|TWGCE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWAx''' Slave Adresse&lt;br /&gt;
::Wird der [[AVR]] als Slave eingesetzt, wird in den oberen 7 Bit die Adresse eingetragen, auf die reagiert werden soll.&lt;br /&gt;
:*'''TWGCE''' General Call Enable&lt;br /&gt;
::Setzt man Bit0, kann zusätzlich auf einen ''General Call'' reagiert werden.&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
==== TWAMR ====&lt;br /&gt;
:Slave Address Mask Register&lt;br /&gt;
:Zus&amp;amp;auml;tzlich zu den schon geannten Registern, kann es bei einigen ATMegas, wie dem [[ATMega168]], dieses Register geben, in der Regel hat es aber den Standardwert von $00, wobei sich das TWI-Modul verh&amp;amp;auml;lt wie bei den anderen ATMegas.&lt;br /&gt;
:Mit dem setzen von einzelnen Bits werden beim vergleich der Slaveadresse (die vom Master gesendet wurde) mit ''TWAR'' diese Bits ausmaskiert, dH. treffen immer zu, was bedeutet, dass der ATMega auf mehr als nur einer bestimmten Slaveadresse (''TWAR'') angesprochen werden kann.&lt;br /&gt;
:Werden zB. alle Bits gesetzt, fühlt sich der [[AVR]] immer angesprochen, egal welche Slaveadresse über den Bus gesendet wurde.&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWAM6|TWAM5|TWAM4|TWAM3|TWAM2|TWAM1|TWAM0|&amp;amp;ndash;}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Wird der [[AVR]] als Slave eingesetzt, kann in den oberen 7 Bit die Adressmaske eingetragen werden,&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
== Übertragungsarten ==&lt;br /&gt;
Bei TWI gibt es diese Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
== Master ==&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''Bit Rate Generator'' zuständig.&lt;br /&gt;
&lt;br /&gt;
=== Bit Rate Generator ===&lt;br /&gt;
Zur Übertragung gibt es die Bitraten ''Standard'', mit bis zu 100kBit/s, und ''FastMode'', mit bis zu 400kBit/s.&lt;br /&gt;
Der Master muss immer den Takt erzeugen, der bei Bedarf auf der Leitung SCL angelegt wird.&lt;br /&gt;
Der SCL-Takt ist beim AVR abhängig von der CPU-Frequenz.&lt;br /&gt;
Da [[I2C]], im Gegensatz zu [[RS232]], ein synchrones Protokoll ist, das mit dem Taktsignal SCL arbeitet, muss man nicht exakt auf eine Frequenz von 100kHz bzw. 400kHz kommen.&lt;br /&gt;
&lt;br /&gt;
Im TWI-Modul des AVR gibt es zwei Stellen, an denen man die Teilung der Frequenz einstellen kann:&lt;br /&gt;
* die ''Prescaler Bits'' (TWPS), diese 2 Bits befinden sich im ''TWI Status Register'' (TWSR)&lt;br /&gt;
* für die genauere Einstellung das ''TWI Bit Rate Register'' (TWBR)&lt;br /&gt;
&lt;br /&gt;
'''Formel zur Berechnung der SCL-Frequenz:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{SCL{-}Frequenz =  \frac{CPU{-}Frequenz}{16 + 2 \cdot TWBR \cdot 4^{TWPS} } }&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ein AVR zur Zeit max. mit 20MHz getaktet werden kann, ist es nicht nötig, den Prescaler zu benutzen, bzw. er wird auf den Teiler 1 gestellt, was keiner Teilung entspricht. Mit diesem Teiler können alle CPU-Frequenzen und TWI-Takte abgedeckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ '''Mögliche&amp;amp;nbsp;Prescaler-Werte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bit-Wert || Teiler&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 ||1&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 ||4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 ||16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 ||64&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die Werte von TWBR gehen von theoretisch 0 bis 255. Laut [[Atmel]] soll der Wert aber mind. 10 Betragen, da es sonst zu Problemen bei der Übertragung kommen kann.&lt;br /&gt;
&lt;br /&gt;
'''Es Ergibt sich somit folgende Formel zum Berechnen von TWBR:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{TWBR = \frac{ \frac {CPU{-}Frequenz}{SCL{-}Frequenz} - 16}{2 \cdot 4^{TWPS} }}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Achtung!''' In der Formel bei TWPS den Bitwert 0..3 einsetzen!&lt;br /&gt;
&lt;br /&gt;
Kommt ein Wert kleiner 10 heraus, kann ein höherer CPU-Takt gewählt werden, oder falls das nicht möglich ist, wird der Bus mit einem geringeren Takt betrieben, was trotzdem innerhalb der Spezifikation liegt. Wird eine krumme CPU-Frequenz verwendet, die kein ganzzahliges Ergebnis zur Folge hat, kann man mit der ersten Formel überprüfen, ob der Wert auf- oder abgerundet wird. Auf der sicheren Seite ist man, wenn der Wert aufgerundet wird. Das entspricht einer grösseren Teilung, also eine geringfügig kleinere Bitrate und liegt deshalb im Standard.&lt;br /&gt;
&lt;br /&gt;
== Slave ==&lt;br /&gt;
Um den AVR als Slave zu konfigurieren sind nur diese wenigen Schritte notwendig:&lt;br /&gt;
*gewünschte Slaveadresse im ''Address Register'' (TWAR) setzen&lt;br /&gt;
*im ''Control Register'' (TWCR)&lt;br /&gt;
**mit TWEN das TWI Modul aktivieren&lt;br /&gt;
**mit TWEA das Senden des Bestätigungsbits (ACK) zulassen&lt;br /&gt;
&lt;br /&gt;
anschliessend als Slave&lt;br /&gt;
*warten, bis im ''Control Register'' (TWCR) das Bit TWINT gesetzt ist, welches anzeigt, daß auf dem Bus was los ist&lt;br /&gt;
*das ''Status Register'' (TWSR) abfragen und entsprechend darauf reagieren&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung zur CPU-Frequenz ===&lt;br /&gt;
&lt;br /&gt;
Da der Master den Takt vorgibt, muss der Slave nur mit dessen Takt am Bus mitlauschen. Um zu gewährleisten, daß der Slave dem Takt folgen kann sollte laut [[Atmel]] die CPU-Frequenz eines ATMega-Slave mind. das 16-fache der Bus-Frequenz betragen.&lt;br /&gt;
&lt;br /&gt;
das ergibt folgende Werte :&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bus-Frequenz || minimale CPU-Frequenz&lt;br /&gt;
|-&lt;br /&gt;
|100 kHz || 1,6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|400 kHz || 6,4 MHz&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[RS232]] - serielle Schnittstelle&lt;br /&gt;
* [[RS485]] - serieller (asynchroner) Bus&lt;br /&gt;
* [[TWI Praxis]] - Programmbeispiele&lt;br /&gt;
* [[TWI_Slave_mit_avr-gcc|TWI-Slave mit avr-gcc]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 00:52, 6. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28417</id>
		<title>TWI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28417"/>
				<updated>2020-02-14T17:32:26Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Achtung weg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWI ('''T'''wo-'''w'''ire Serial '''I'''nterface) ist eine Bezeichnung von [[Atmel|Atmel]] für die auf vielen [[AVR|AVR]] Megas vorhandene  [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Hardware.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll nur auf Besonderheiten der [[AVR]]-[[Microcontroller]] eingegangen werden, Einzelheiten zu [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Merkmale =&lt;br /&gt;
&lt;br /&gt;
* Master- und Slavemodus&lt;br /&gt;
* Multimaster&lt;br /&gt;
* 7-Bit Adressierung (als Master auch 10-Bit Adressierung möglich)&lt;br /&gt;
* Übertragungsrate von bis zu 400kBit/s&lt;br /&gt;
&lt;br /&gt;
= TWI verwenden =&lt;br /&gt;
Um TWI mit dem [[AVR]] verwenden zu können sind einige Einstellungen nötig, die hier in Abhängigkeit der Anwendung aufgezeigt werden.&lt;br /&gt;
&lt;br /&gt;
== TWI-Register ==&lt;br /&gt;
Hier eine kurze Beschreibung der für den TWI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== TWBR ====&lt;br /&gt;
:Bit Rate Register, alle 8 bit&lt;br /&gt;
:dient zum einstellen des Bus-Taktes als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWCR ====&lt;br /&gt;
:Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWINT|TWEA|TWSTA|TWSTO|TWWC|TWEN|&amp;amp;ndash;|TWIE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:die Hauptschaltstelle befindet sich hier,&lt;br /&gt;
:*'''TWINT''' TWI Interrupt Flag&lt;br /&gt;
::Nach Abarbeitung der letzten Aktion wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''TWIE'' gesetzt ist.&lt;br /&gt;
::Es sollte anschliessend das Datenregister und das Statusregister ausgelesen werden und darauf entsprechend reagiert werden.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
::Mit dem zurücksetzen (löschen) von ''TWINT'' wird die nächste Aktion ausgelöst, es müssen deshalb vorher alle notwendigen Flags und Register (zB. ''TWDR'') entsprechend gesetzt werden.&lt;br /&gt;
:*'''TWEA''' TWI Enable Acknowledge Bit&lt;br /&gt;
::Sendet ein ACK nach einer Übertragung wenn&lt;br /&gt;
:::*als Slave die eigene Slaveadresse (''TWAR'') erkannt wurde,&lt;br /&gt;
:::*ein General Call erkannt wurde und das ''TWGCE''-Flag in ''TWAR'' gesetzt ist,&lt;br /&gt;
:::*ein ganz normales Byte als Slave oder als Master empfangen wurde.&lt;br /&gt;
:*'''TWSTA''' TWI Start Sequenz senden&lt;br /&gt;
::Die TWI-Hardware überprüft ob der Bus frei ist, und gibt die Startsequenz aus.&lt;br /&gt;
::Ist der Bus nicht frei, wartet das TWI-Modul bis eine Stopsequenz erkannt wurde und sendet die Startsequenz erneut.&lt;br /&gt;
::Dieses Flag muss per Software wieder gelöscht werden.&lt;br /&gt;
:*'''TWSTO''' TWI Stop Sequenz senden&lt;br /&gt;
::Als Master wird durch setzen eine Stopsequenz ausgegeben. Ist die Stopsequenz gesendet wird das Flag automatisch gelöscht.&lt;br /&gt;
::Als Slave kann dieses Flag zum zurücksetzen nach einem Fehler verwendet werden. Es wird keine Stopsequenz ausgegeben, aber das Modul beeinflusst anschliessend nicht mehr die Leitungen SCL oder SDA, das TWI-Modul befindet sich in einem definierten unadressierten Zustand.&lt;br /&gt;
:*'''TWWC''' TWI Write Collision Flag&lt;br /&gt;
::In das Datenregister ''TWDR'' sollte man nur schreiben, wenn ''TWINT'' High ist, ist ''TWINT'' Low, wird dieses Flag gesetzt und zeigt einen Fehler an.&lt;br /&gt;
:*'''TWEN''' TWI Enable&lt;br /&gt;
::Aktivieren des TWI-Moduls. Das TWI-Modul übernimmt u.a. die Steuerung über die Leitungen SCL und SDA.&lt;br /&gt;
:*'''TWIE''' TWI Interrupt Anforderung erlauben&lt;br /&gt;
::Interruptanforderung aktivieren, wenn eine Aktion durchgeführt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==== TWSR ====&lt;br /&gt;
:Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWS7|TWS6|TWS5|TWS4|TWS3|&amp;amp;ndash;|TWPS1|TWPS0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWSx''' TWI Status&lt;br /&gt;
::die oberen 5 Bit geben den Status der letzten Aktion wieder&lt;br /&gt;
:*'''TWPSx''' TWI Prescaler&lt;br /&gt;
::die zwei niederwertigen Bit zum einstellen des Prescaler als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWDR ====&lt;br /&gt;
:Data Register, alle 8 bit&lt;br /&gt;
:Beim Senden: nächstes Byte, das auf den Bus ausgegeben werden soll&lt;br /&gt;
:Beim Empfangen: letztes Byte, das über den Bus gekommen ist&lt;br /&gt;
:Die Daten sind gültig, solange das Bit ''TWINT'' in ''TWCR'' gesetzt ist&lt;br /&gt;
&lt;br /&gt;
==== TWAR ====&lt;br /&gt;
:Slave Address Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWA6|TWA5|TWA4|TWA3|TWA2|TWA1|TWA0|TWGCE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWAx''' Slave Adresse&lt;br /&gt;
::Wird der [[AVR]] als Slave eingesetzt, wird in den oberen 7 Bit die Adresse eingetragen, auf die reagiert werden soll.&lt;br /&gt;
:*'''TWGCE''' General Call Enable&lt;br /&gt;
::Setzt man Bit0, kann zusätzlich auf einen ''General Call'' reagiert werden.&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
==== TWAMR ====&lt;br /&gt;
:Slave Address Mask Register&lt;br /&gt;
:Zus&amp;amp;auml;tzlich zu den schon geannten Registern, kann es bei einigen ATMegas, wie dem [[ATMega168]], dieses Register geben, in der Regel hat es aber den Standardwert von $00, wobei sich das TWI-Modul verh&amp;amp;auml;lt wie bei den anderen ATMegas.&lt;br /&gt;
:Mit dem setzen von einzelnen Bits werden beim vergleich der Slaveadresse (die vom Master gesendet wurde) mit ''TWAR'' diese Bits ausmaskiert, dH. treffen immer zu, was bedeutet, dass der ATMega auf mehr als nur einer bestimmten Slaveadresse (''TWAR'') angesprochen werden kann.&lt;br /&gt;
:Werden zB. alle Bits gesetzt, fühlt sich der [[AVR]] immer angesprochen, egal welche Slaveadresse über den Bus gesendet wurde.&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWAM6|TWAM5|TWAM4|TWAM3|TWAM2|TWAM1|TWAM0|&amp;amp;ndash;}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Wird der [[AVR]] als Slave eingesetzt, kann in den oberen 7 Bit die Adressmaske eingetragen werden,&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
== Übertragungsarten ==&lt;br /&gt;
Bei TWI gibt es diese Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
== Master ==&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''Bit Rate Generator'' zuständig.&lt;br /&gt;
&lt;br /&gt;
=== Bit Rate Generator ===&lt;br /&gt;
Zur Übertragung gibt es die Bitraten ''Standard'', mit bis zu 100kBit/s, und ''FastMode'', mit bis zu 400kBit/s.&lt;br /&gt;
Der Master muss immer den Takt erzeugen, der bei Bedarf auf der Leitung SCL angelegt wird.&lt;br /&gt;
Der SCL-Takt ist beim AVR abhängig von der CPU-Frequenz.&lt;br /&gt;
Da [[I2C]], im Gegensatz zu [[RS232]], ein synchrones Protokoll ist, das mit dem Taktsignal SCL arbeitet, muss man nicht exakt auf eine Frequenz von 100kHz bzw. 400kHz kommen.&lt;br /&gt;
&lt;br /&gt;
Im TWI-Modul des AVR gibt es zwei Stellen, an denen man die Teilung der Frequenz einstellen kann:&lt;br /&gt;
* die ''Prescaler Bits'' (TWPS), diese 2 Bits befinden sich im ''TWI Status Register'' (TWSR)&lt;br /&gt;
* für die genauere Einstellung das ''TWI Bit Rate Register'' (TWBR)&lt;br /&gt;
&lt;br /&gt;
'''Formel zur Berechnung der SCL-Frequenz:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{SCL{-}Frequenz =  \frac{CPU{-}Frequenz}{16 + 2 \cdot TWBR \cdot 4^{TWPS} } }&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ein AVR zur Zeit max. mit 20MHz getaktet werden kann, ist es nicht nötig, den Prescaler zu benutzen, bzw. er wird auf den Teiler 1 gestellt, was keiner Teilung entspricht. Mit diesem Teiler können alle CPU-Frequenzen und TWI-Takte abgedeckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ '''Mögliche&amp;amp;nbsp;Prescaler-Werte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bit-Wert || Teiler&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 ||1&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 ||4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 ||16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 ||64&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die Werte von TWBR gehen von theoretisch 0 bis 255. Laut [[Atmel]] soll der Wert aber mind. 10 Betragen, da es sonst zu Problemen bei der Übertragung kommen kann.&lt;br /&gt;
&lt;br /&gt;
'''Es Ergibt sich somit folgende Formel zum Berechnen von TWBR:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{TWBR = \frac{ \frac {CPU{-}Frequenz}{SCL{-}Frequenz} - 16}{2 \cdot 4^{TWPS} }}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kommt ein Wert kleiner 10 heraus, kann ein höherer CPU-Takt gewählt werden, oder falls das nicht möglich ist, wird der Bus mit einem geringeren Takt betrieben, was trotzdem innerhalb der Spezifikation liegt. Wird eine krumme CPU-Frequenz verwendet, die kein ganzzahliges Ergebnis zur Folge hat, kann man mit der ersten Formel überprüfen, ob der Wert auf- oder abgerundet wird. Auf der sicheren Seite ist man, wenn der Wert aufgerundet wird. Das entspricht einer grösseren Teilung, also eine geringfügig kleinere Bitrate und liegt deshalb im Standard.&lt;br /&gt;
&lt;br /&gt;
== Slave ==&lt;br /&gt;
Um den AVR als Slave zu konfigurieren sind nur diese wenigen Schritte notwendig:&lt;br /&gt;
*gewünschte Slaveadresse im ''Address Register'' (TWAR) setzen&lt;br /&gt;
*im ''Control Register'' (TWCR)&lt;br /&gt;
**mit TWEN das TWI Modul aktivieren&lt;br /&gt;
**mit TWEA das Senden des Bestätigungsbits (ACK) zulassen&lt;br /&gt;
&lt;br /&gt;
anschliessend als Slave&lt;br /&gt;
*warten, bis im ''Control Register'' (TWCR) das Bit TWINT gesetzt ist, welches anzeigt, daß auf dem Bus was los ist&lt;br /&gt;
*das ''Status Register'' (TWSR) abfragen und entsprechend darauf reagieren&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung zur CPU-Frequenz ===&lt;br /&gt;
&lt;br /&gt;
Da der Master den Takt vorgibt, muss der Slave nur mit dessen Takt am Bus mitlauschen. Um zu gewährleisten, daß der Slave dem Takt folgen kann sollte laut [[Atmel]] die CPU-Frequenz eines ATMega-Slave mind. das 16-fache der Bus-Frequenz betragen.&lt;br /&gt;
&lt;br /&gt;
das ergibt folgende Werte :&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bus-Frequenz || minimale CPU-Frequenz&lt;br /&gt;
|-&lt;br /&gt;
|100 kHz || 1,6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|400 kHz || 6,4 MHz&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[RS232]] - serielle Schnittstelle&lt;br /&gt;
* [[RS485]] - serieller (asynchroner) Bus&lt;br /&gt;
* [[TWI Praxis]] - Programmbeispiele&lt;br /&gt;
* [[TWI_Slave_mit_avr-gcc|TWI-Slave mit avr-gcc]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 00:52, 6. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28416</id>
		<title>TWI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=28416"/>
				<updated>2020-02-14T16:45:49Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Formel zum berechnen des TWI taktes richtig gestellt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWI ('''T'''wo-'''w'''ire Serial '''I'''nterface) ist eine Bezeichnung von [[Atmel|Atmel]] für die auf vielen [[AVR|AVR]] Megas vorhandene  [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Hardware.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll nur auf Besonderheiten der [[AVR]]-[[Microcontroller]] eingegangen werden, Einzelheiten zu [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Merkmale =&lt;br /&gt;
&lt;br /&gt;
* Master- und Slavemodus&lt;br /&gt;
* Multimaster&lt;br /&gt;
* 7-Bit Adressierung (als Master auch 10-Bit Adressierung möglich)&lt;br /&gt;
* Übertragungsrate von bis zu 400kBit/s&lt;br /&gt;
&lt;br /&gt;
= TWI verwenden =&lt;br /&gt;
Um TWI mit dem [[AVR]] verwenden zu können sind einige Einstellungen nötig, die hier in Abhängigkeit der Anwendung aufgezeigt werden.&lt;br /&gt;
&lt;br /&gt;
== TWI-Register ==&lt;br /&gt;
Hier eine kurze Beschreibung der für den TWI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== TWBR ====&lt;br /&gt;
:Bit Rate Register, alle 8 bit&lt;br /&gt;
:dient zum einstellen des Bus-Taktes als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWCR ====&lt;br /&gt;
:Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWINT|TWEA|TWSTA|TWSTO|TWWC|TWEN|&amp;amp;ndash;|TWIE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:die Hauptschaltstelle befindet sich hier,&lt;br /&gt;
:*'''TWINT''' TWI Interrupt Flag&lt;br /&gt;
::Nach Abarbeitung der letzten Aktion wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''TWIE'' gesetzt ist.&lt;br /&gt;
::Es sollte anschliessend das Datenregister und das Statusregister ausgelesen werden und darauf entsprechend reagiert werden.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
::Mit dem zurücksetzen (löschen) von ''TWINT'' wird die nächste Aktion ausgelöst, es müssen deshalb vorher alle notwendigen Flags und Register (zB. ''TWDR'') entsprechend gesetzt werden.&lt;br /&gt;
:*'''TWEA''' TWI Enable Acknowledge Bit&lt;br /&gt;
::Sendet ein ACK nach einer Übertragung wenn&lt;br /&gt;
:::*als Slave die eigene Slaveadresse (''TWAR'') erkannt wurde,&lt;br /&gt;
:::*ein General Call erkannt wurde und das ''TWGCE''-Flag in ''TWAR'' gesetzt ist,&lt;br /&gt;
:::*ein ganz normales Byte als Slave oder als Master empfangen wurde.&lt;br /&gt;
:*'''TWSTA''' TWI Start Sequenz senden&lt;br /&gt;
::Die TWI-Hardware überprüft ob der Bus frei ist, und gibt die Startsequenz aus.&lt;br /&gt;
::Ist der Bus nicht frei, wartet das TWI-Modul bis eine Stopsequenz erkannt wurde und sendet die Startsequenz erneut.&lt;br /&gt;
::Dieses Flag muss per Software wieder gelöscht werden.&lt;br /&gt;
:*'''TWSTO''' TWI Stop Sequenz senden&lt;br /&gt;
::Als Master wird durch setzen eine Stopsequenz ausgegeben. Ist die Stopsequenz gesendet wird das Flag automatisch gelöscht.&lt;br /&gt;
::Als Slave kann dieses Flag zum zurücksetzen nach einem Fehler verwendet werden. Es wird keine Stopsequenz ausgegeben, aber das Modul beeinflusst anschliessend nicht mehr die Leitungen SCL oder SDA, das TWI-Modul befindet sich in einem definierten unadressierten Zustand.&lt;br /&gt;
:*'''TWWC''' TWI Write Collision Flag&lt;br /&gt;
::In das Datenregister ''TWDR'' sollte man nur schreiben, wenn ''TWINT'' High ist, ist ''TWINT'' Low, wird dieses Flag gesetzt und zeigt einen Fehler an.&lt;br /&gt;
:*'''TWEN''' TWI Enable&lt;br /&gt;
::Aktivieren des TWI-Moduls. Das TWI-Modul übernimmt u.a. die Steuerung über die Leitungen SCL und SDA.&lt;br /&gt;
:*'''TWIE''' TWI Interrupt Anforderung erlauben&lt;br /&gt;
::Interruptanforderung aktivieren, wenn eine Aktion durchgeführt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==== TWSR ====&lt;br /&gt;
:Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWS7|TWS6|TWS5|TWS4|TWS3|&amp;amp;ndash;|TWPS1|TWPS0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWSx''' TWI Status&lt;br /&gt;
::die oberen 5 Bit geben den Status der letzten Aktion wieder&lt;br /&gt;
:*'''TWPSx''' TWI Prescaler&lt;br /&gt;
::die zwei niederwertigen Bit zum einstellen des Prescaler als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWDR ====&lt;br /&gt;
:Data Register, alle 8 bit&lt;br /&gt;
:Beim Senden: nächstes Byte, das auf den Bus ausgegeben werden soll&lt;br /&gt;
:Beim Empfangen: letztes Byte, das über den Bus gekommen ist&lt;br /&gt;
:Die Daten sind gültig, solange das Bit ''TWINT'' in ''TWCR'' gesetzt ist&lt;br /&gt;
&lt;br /&gt;
==== TWAR ====&lt;br /&gt;
:Slave Address Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWA6|TWA5|TWA4|TWA3|TWA2|TWA1|TWA0|TWGCE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWAx''' Slave Adresse&lt;br /&gt;
::Wird der [[AVR]] als Slave eingesetzt, wird in den oberen 7 Bit die Adresse eingetragen, auf die reagiert werden soll.&lt;br /&gt;
:*'''TWGCE''' General Call Enable&lt;br /&gt;
::Setzt man Bit0, kann zusätzlich auf einen ''General Call'' reagiert werden.&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
==== TWAMR ====&lt;br /&gt;
:Slave Address Mask Register&lt;br /&gt;
:Zus&amp;amp;auml;tzlich zu den schon geannten Registern, kann es bei einigen ATMegas, wie dem [[ATMega168]], dieses Register geben, in der Regel hat es aber den Standardwert von $00, wobei sich das TWI-Modul verh&amp;amp;auml;lt wie bei den anderen ATMegas.&lt;br /&gt;
:Mit dem setzen von einzelnen Bits werden beim vergleich der Slaveadresse (die vom Master gesendet wurde) mit ''TWAR'' diese Bits ausmaskiert, dH. treffen immer zu, was bedeutet, dass der ATMega auf mehr als nur einer bestimmten Slaveadresse (''TWAR'') angesprochen werden kann.&lt;br /&gt;
:Werden zB. alle Bits gesetzt, fühlt sich der [[AVR]] immer angesprochen, egal welche Slaveadresse über den Bus gesendet wurde.&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWAM6|TWAM5|TWAM4|TWAM3|TWAM2|TWAM1|TWAM0|&amp;amp;ndash;}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Wird der [[AVR]] als Slave eingesetzt, kann in den oberen 7 Bit die Adressmaske eingetragen werden,&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
== Übertragungsarten ==&lt;br /&gt;
Bei TWI gibt es diese Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
== Master ==&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''Bit Rate Generator'' zuständig.&lt;br /&gt;
&lt;br /&gt;
=== Bit Rate Generator ===&lt;br /&gt;
Zur Übertragung gibt es die Bitraten ''Standard'', mit bis zu 100kBit/s, und ''FastMode'', mit bis zu 400kBit/s.&lt;br /&gt;
Der Master muss immer den Takt erzeugen, der bei Bedarf auf der Leitung SCL angelegt wird.&lt;br /&gt;
Der SCL-Takt ist beim AVR abhängig von der CPU-Frequenz.&lt;br /&gt;
Da [[I2C]], im Gegensatz zu [[RS232]], ein synchrones Protokoll ist, das mit dem Taktsignal SCL arbeitet, muss man nicht exakt auf eine Frequenz von 100kHz bzw. 400kHz kommen.&lt;br /&gt;
&lt;br /&gt;
Im TWI-Modul des AVR gibt es zwei Stellen, an denen man die Teilung der Frequenz einstellen kann:&lt;br /&gt;
* die ''Prescaler Bits'' (TWPS), diese 2 Bits befinden sich im ''TWI Status Register'' (TWSR)&lt;br /&gt;
* für die genauere Einstellung das ''TWI Bit Rate Register'' (TWBR)&lt;br /&gt;
&lt;br /&gt;
'''Formel zur Berechnung der SCL-Frequenz:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{SCL{-}Frequenz =  \frac{CPU{-}Frequenz}{16 + 2 \cdot TWBR \cdot 4^{TWPS} } }&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ein AVR zur Zeit max. mit 20MHz getaktet werden kann, ist es nicht nötig, den Prescaler zu benutzen, bzw. er wird auf den Teiler 1 gestellt, was keiner Teilung entspricht. Mit diesem Teiler können alle CPU-Frequenzen und TWI-Takte abgedeckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ '''Mögliche&amp;amp;nbsp;Prescaler-Werte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bit-Wert || Teiler&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 ||1&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 ||4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 ||16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 ||64&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die Werte von TWBR gehen von theoretisch 0 bis 255. Laut [[Atmel]] soll der Wert aber mind. 10 Betragen, da es sonst zu Problemen bei der Übertragung kommen kann.&lt;br /&gt;
&lt;br /&gt;
'''Es Ergibt sich somit folgende Formel zum Berechnen von TWBR:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{TWBR = \frac{ \frac {CPU{-}Frequenz}{SCL{-}Frequenz} - 16}{2 \cdot 4^{TWPS} }}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Achtung!''' In der Formel bei TWPS den prescaler Teiler Wert aus der Tabelle einsetzen!&lt;br /&gt;
&lt;br /&gt;
Kommt ein Wert kleiner 10 heraus, kann ein höherer CPU-Takt gewählt werden, oder falls das nicht möglich ist, wird der Bus mit einem geringeren Takt betrieben, was trotzdem innerhalb der Spezifikation liegt. Wird eine krumme CPU-Frequenz verwendet, die kein ganzzahliges Ergebnis zur Folge hat, kann man mit der ersten Formel überprüfen, ob der Wert auf- oder abgerundet wird. Auf der sicheren Seite ist man, wenn der Wert aufgerundet wird. Das entspricht einer grösseren Teilung, also eine geringfügig kleinere Bitrate und liegt deshalb im Standard.&lt;br /&gt;
&lt;br /&gt;
== Slave ==&lt;br /&gt;
Um den AVR als Slave zu konfigurieren sind nur diese wenigen Schritte notwendig:&lt;br /&gt;
*gewünschte Slaveadresse im ''Address Register'' (TWAR) setzen&lt;br /&gt;
*im ''Control Register'' (TWCR)&lt;br /&gt;
**mit TWEN das TWI Modul aktivieren&lt;br /&gt;
**mit TWEA das Senden des Bestätigungsbits (ACK) zulassen&lt;br /&gt;
&lt;br /&gt;
anschliessend als Slave&lt;br /&gt;
*warten, bis im ''Control Register'' (TWCR) das Bit TWINT gesetzt ist, welches anzeigt, daß auf dem Bus was los ist&lt;br /&gt;
*das ''Status Register'' (TWSR) abfragen und entsprechend darauf reagieren&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung zur CPU-Frequenz ===&lt;br /&gt;
&lt;br /&gt;
Da der Master den Takt vorgibt, muss der Slave nur mit dessen Takt am Bus mitlauschen. Um zu gewährleisten, daß der Slave dem Takt folgen kann sollte laut [[Atmel]] die CPU-Frequenz eines ATMega-Slave mind. das 16-fache der Bus-Frequenz betragen.&lt;br /&gt;
&lt;br /&gt;
das ergibt folgende Werte :&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bus-Frequenz || minimale CPU-Frequenz&lt;br /&gt;
|-&lt;br /&gt;
|100 kHz || 1,6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|400 kHz || 6,4 MHz&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[RS232]] - serielle Schnittstelle&lt;br /&gt;
* [[RS485]] - serieller (asynchroner) Bus&lt;br /&gt;
* [[TWI Praxis]] - Programmbeispiele&lt;br /&gt;
* [[TWI_Slave_mit_avr-gcc|TWI-Slave mit avr-gcc]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 00:52, 6. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=28271</id>
		<title>Benutzer:Linux 80</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=28271"/>
				<updated>2018-04-08T19:38:44Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: URL zum RN Profil&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Seit Mai 2005 ASURO-Besitzer, und AVR-Forscher ;-)&lt;br /&gt;
&lt;br /&gt;
Will von den [[AVR]]s so viele Details wissen wie früher vom 6502 !&lt;br /&gt;
&lt;br /&gt;
Näheres auf der RN-Nickpage.&lt;br /&gt;
&lt;br /&gt;
Forschutensilien inzwischen ausgebaut um:&lt;br /&gt;
*[[RN-Control]] 2 Stück, siehe [[Verlosung]]&lt;br /&gt;
*[[RN-Mega8]]&lt;br /&gt;
*[[RN-MiniControl]]&lt;br /&gt;
*[http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=152 RN-LCD-Adapter]&lt;br /&gt;
*TextLCD mit 16*2 Zeichen&lt;br /&gt;
*TextLCD mit 20*4 Zeichen [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=80 EA-Dip204]&lt;br /&gt;
*GrafikLCD 128*64 mit KS0108 ([http://www.pollin.de/shop/downloads/D120423D.PDF Pollin 120423])&lt;br /&gt;
*GrafikLCD 128*64 mit SED1565 ([http://www.pollin.de/shop/downloads/D120292D.RAR Pollin 120292]) &amp;lt;small&amp;gt;(das hat aber sich aber aufgelöst, und eine Art Lochfrass in der Scheibe, sieht aus als wenn immer Pixel gesetzt sind, obwohl keine Power auf dem LCD, vom Prinzip her funktionierts aber noch)&amp;lt;/small&amp;gt;&lt;br /&gt;
*und weitere AT-Megas und -Tinys&lt;br /&gt;
*Schachtelweise elektronisches kleinzeugs, das gelegentlich ausprobiert werden muss&lt;br /&gt;
&lt;br /&gt;
Seit Dezember 2005 im besitz eines Renesas R8C/13 Controllers (samt selbstgebautem Applicationboard), der durch eine bekannte Zeitschrift unters Volk gebracht wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wikibeteiligungen ==&lt;br /&gt;
&lt;br /&gt;
*[[TWI]] - 6. Jan 2006, 00:52&lt;br /&gt;
*[[Atmel Controller Mega8515]] - 8. Jan 2006, 03:08&lt;br /&gt;
*[[TWI Praxis]] - 15. Jan 2006, 15:31&lt;br /&gt;
*[[USI (Avr)]] - 18. Nov 2006, 19:19&lt;br /&gt;
*[[Bascom und USI-Kommunikation]] - 26. Nov 2006, 02:11&lt;br /&gt;
*[[HEX-Datei]] - 27. Aug 2007, 03:05&lt;br /&gt;
*[[Bascom I2C Master]] - 28. Okt 2007, 02:08&lt;br /&gt;
*[[Bascom und 1-Wire]] - 23. Aug 2008, 03:16&lt;br /&gt;
&lt;br /&gt;
*[[Spezial:Contributions/Linux_80]] - Der Rest&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.roboternetz.de/community/members/11490-linux_80 Linux_80] - RN-Profil&lt;br /&gt;
*http://roboter.net-con.net/asuro/ - Homepage&lt;br /&gt;
&amp;lt;!-- *http://www.elektor.de/ - Zeitschrift elektor --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Bascom_und_1-Wire&amp;diff=25051</id>
		<title>Diskussion:Bascom und 1-Wire</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Bascom_und_1-Wire&amp;diff=25051"/>
				<updated>2014-07-19T20:59:41Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bascom 2.077 mag die Variable DIM Sp(9) as Byte nicht mehr,&lt;br /&gt;
ist schon durch Bascom selbst in Gebrauch.&lt;br /&gt;
&lt;br /&gt;
DIM SP(9) as Byte    Fehler&lt;br /&gt;
Sp(1) = 1wread(9)    Fehler &lt;br /&gt;
Print Hex(sp(2));    Fehler&lt;br /&gt;
Print Hex(sp(1))     Fehler&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schlage vor die Variable in den Beispielen &amp;quot;Bestimmtes Gerät ansprechen&amp;quot; umzubenennen&lt;br /&gt;
in Sep(9) oder was anderes.&lt;br /&gt;
&lt;br /&gt;
DIM Sep(9) as Byte     OK&lt;br /&gt;
&lt;br /&gt;
Sep(1) = 1wread(9)    OK &lt;br /&gt;
Print Hex(sep(2));    OK&lt;br /&gt;
Print Hex(sep(1))     OK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Es wurde inzwischen ja schon angepasst,&lt;br /&gt;
ich kann's mangels aktuellem Bascom zZt nicht prüfen.&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|linux_80]] ([[Benutzer Diskussion:Linux 80|Diskussion]]) 22:59, 19. Jul 2014 (CEST)&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=15871</id>
		<title>Bascom I2C Master</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=15871"/>
				<updated>2009-12-29T11:47:48Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: TWEN setzen hat nicht ganz so gepasst ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen verschiedene Programmbeispiele, um einen [[AVR]] mit [[Bascom]] zu einem [[I2C]]-Master zu schlumpfen.&lt;br /&gt;
&lt;br /&gt;
In allen Beispielen wird einem PCF8574 jeweils der Wert &amp;amp;HAA nach einer Pause &amp;amp;H55 gesendet, was als Blinken, evtl. auch als Lauflicht zu erkennen sein kann, falls LEDs an dessen Ports angeschlossen sind.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software I2C ==&lt;br /&gt;
&lt;br /&gt;
Die Softwareversion der I2C-Implementierung kann auf allen AVR programmiert werden, man kann sich die Ports auf denen Data (SDA) und Clock (SCL) angeschlossen werden selbst aussuchen.&lt;br /&gt;
&lt;br /&gt;
Standardmäßig wird von Bascom die Software-Version verwendet um auf den I2C-Bus zuzugreifen, d.H. die einzelnen Bits der zu übertragenden Daten werden per Software auf High- oder Low-Pegel an den Ports ausgegeben. Der AVR kann in dieser Zeit keine anderen Aufgaben erledigen.&lt;br /&gt;
&lt;br /&gt;
Bei dieser Art I2C zu implementieren wird eine aktuelle Aktivität auf dem Bus nicht beachtet, dies kann zu Problemen führen falls mehr als ein Master am Bus hängt. Siehe Links unter &amp;quot;[[#Siehe_auch|Siehe auch]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 Config Scl = Portb.0                              {{vbcomment|Ports fuer IIC-Bus, nicht Standard !}}&lt;br /&gt;
 Config Sda = Portb.1&lt;br /&gt;
&amp;lt;!-- das &amp;quot;=&amp;quot; immer mit &amp;amp;#061; angeben, sonst gibts keinen Kommentar !! --&amp;gt;&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 10                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-Soft Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Falls mehr als nur ein Byte an einen Slave gesendet werden sollte, und nach dem letzten Byte ERR=1 ist, sollte anschließend ein I2Cstop folgen, da der Slave kein weiteres Byte haben will !&lt;br /&gt;
&lt;br /&gt;
== Hardware TWI ==&lt;br /&gt;
&lt;br /&gt;
AVR Controller, die [[I2C]] hardwaremäßig Unterstützen, haben das [[TWI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. TWI ist bei den meisten ATMegas vorhanden, z.B. dem [[ATMega32]].&lt;br /&gt;
&lt;br /&gt;
Damit Bascom das TWI-Modul verwendet muss die &amp;lt;tt&amp;gt;i2c_twi.lib&amp;lt;/tt&amp;gt; (bzw. &amp;lt;tt&amp;gt;.lbx&amp;lt;/tt&amp;gt;, bei der Bascom-Demo) eingebunden werden, ansonsten ist, bis auf die Initialisierung, alles genauso wie bei Software-I2C.&lt;br /&gt;
Bei Verwendung der Bascom-I2C-Befehle macht es Performancemäßig keinen großen Unterschied, ob man Software-I2C oder TWI verwendet, denn bei beiden Versionen wird solange darauf gewartet, bis das Byte über den Bus gesendet ist, und ein ACK oder NACK empfangen ist.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil von TWI ist aber, das es in Multimasterumgebungen besser verträglich ist (z.B. I2CStart). Gibt es nur einen Master, kann man sich für eine der beiden Versionen entscheiden.&lt;br /&gt;
&lt;br /&gt;
Der Master bestimmt wie schnell die Daten auf dem Bus übertragen werden (Ausnahme: [[Clock_Stretching]] ).&lt;br /&gt;
Dafür ist hier die Zeile mit '''&amp;lt;tt&amp;gt;Config TWI&amp;lt;/tt&amp;gt;''' zuständig, Bascom berechnet aus der angegebenen Taktfrequenz den richtigen Wert für TWBR um an den gewünschten I2C-Takt zu kommen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = &amp;amp;B00000100                                 {{vbcomment|nur TWEN setzen}}&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Mit der TWI-Lib wird zwar die Hardware benutzt um die Bytes auf den I2C-Bus auszugeben bzw. von dort einzulesen, es wird aber kein Status von TWSR abgefragt, ob die erwartete Reaktion eingetreten ist !&lt;br /&gt;
&lt;br /&gt;
Unter Zuhilfenahme des Datenblattes könnte eine Highend-Version so aussehen:&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = &amp;amp;B00000100                                 {{vbcomment|nur TWEN setzen}}&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI High-Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;HAA                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
 &lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;H55                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Die Printausgaben im Else-Teil sind natürlich nur in der Demo nützlich, in der Praxis entweder den Else-Teil ganz weglassen, oder entsprechende Variablen setzen um den Fehler später zu bearbeiten.&lt;br /&gt;
&lt;br /&gt;
Eine einfachere Version einen Fehler frühzeitig zu erkennen, ist statt TWSR nur ERR auf 0 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware USI ==&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR Controller, die zwar kein TWI-Modul haben, aber [[I2C]] hardwaremäßig Unterstützen, haben das [[USI (Avr)|USI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. USI ist bei den meisten ATTinys und einigen ATMegas vorhanden, z.B. dem [[ATtiny2313|ATTiny2313]].&lt;br /&gt;
&lt;br /&gt;
Das [[USI (Avr)|USI]]-Modul kann evtl. als eine Art von TWI-Light angesehen werden, denn es ist nicht so komfortabel wie TWI, es muss intern noch viel in Software erledigt werden, weshalb es Performancemäßig auch keinen großen unterschied macht, ob man Software-I2C oder USI beim Master verwendet.&lt;br /&gt;
&lt;br /&gt;
Am einfachsten benutzt man die Lib, die unter [[#Weblinks|Weblinks]] aufgeführt ist, denn dann kann man die von Bascom vorgegebenen Befehle benutzen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;                       {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_usi.lbx&amp;quot;                                {{vbcomment|Für Hardware USI-I2C}}&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.7                              {{vbcomment|Ports fuer IIC-Bus}}&lt;br /&gt;
 Config Sda = Portb.5&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 5                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
  &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-USI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Nach I2Cstart (auch I2CStop) kann ERR kontrolliert werden, ob das Start (bzw. Stop) auch auf den Bus abgesetzt werden konnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beispiele für Hardware USI&lt;br /&gt;
* [[Bascom Soft-I2c Library]] - weitere Tipps zu I2C mit Bascom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:08, 28. Okt 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Testseite&amp;diff=15740</id>
		<title>Testseite</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Testseite&amp;diff=15740"/>
				<updated>2009-11-28T19:00:09Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: TOC&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Marius F. stinkt ==&lt;br /&gt;
&lt;br /&gt;
== Passive Bauteile ==&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
110^{-6}F&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ebene 2 Überschrift ==&lt;br /&gt;
''Kursiver Text''''Kursiver Text''&lt;br /&gt;
== Ebene 2 Überschrift ==&lt;br /&gt;
[http://www.beispiel.de Link-Text]''Kursiver Text''''Kursiver Text''[[Media:Beispiel.mp3]]&lt;br /&gt;
----&lt;br /&gt;
Benutzer:Tocer|Tocer]] 09:12, 10. Jun 2008 (CEST)&lt;br /&gt;
----&lt;br /&gt;
Geil&lt;br /&gt;
&lt;br /&gt;
== da der rest ==&lt;br /&gt;
&lt;br /&gt;
[[:Kategorie:Microcontroller]]&lt;br /&gt;
&lt;br /&gt;
[[:RN-Control Grundfunktionen]]&lt;br /&gt;
&lt;br /&gt;
Hier kann man ein wenig experimentieren wie was geht! Einfach auf bearbeiten klicken und schreiben!&lt;br /&gt;
Wieso ist das jetzt in so einem Kästchen?&lt;br /&gt;
Eine neue Zeile im [[--[[Benutzer:Tocer|Tocer]] 11:43, 9. Jun 2008 (CEST)[[Media:''Marius Fiegenbaum stinktHaupttext'']].]]&lt;br /&gt;
So strukturiert man Seiten: &lt;br /&gt;
 Bla ??? blablabla&lt;br /&gt;
 Test1234&lt;br /&gt;
 Das geht ja gut!!!&lt;br /&gt;
mhm&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
was ist das??&lt;br /&gt;
--[[Benutzer:Keno|Keno]] 18:53, 30. Sep 2008 (CEST)&lt;br /&gt;
was das??&lt;br /&gt;
&amp;lt;nowiki&amp;gt;mhm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Formeln==&lt;br /&gt;
&amp;lt;math&amp;gt; f(x)=x \cdot b^x &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt; f(x)=x \cdot b^x &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k=0}^\infty \frac {(-1)^k \cdot x^{2k}}{(2k)!} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k=0}^3 \frac {(-1)^k \cdot x^{2k}}{(2k)!} = 1-\frac{1}{2}\cdot x^2 +\frac{1}{24}\cdot x^4-\frac{1}{720}\cdot x^4&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
 U_\mathrm{m} = U_\mathrm{ein} \cdot  \frac{t_\mathrm{ein}}{t_\mathrm{ein} + t_\mathrm{aus}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Überschrift =&lt;br /&gt;
und nun der Text &lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Neuer Abschnitt ==&lt;br /&gt;
bla bla bla ...&lt;br /&gt;
&lt;br /&gt;
=== Unterabschnitt ===&lt;br /&gt;
bla bla bla ...&lt;br /&gt;
==== Unter-Unterabschnitt ====&lt;br /&gt;
[[Bild:AtmelController.jpg|thumb|Bildunterzeile für Beschreibung]]&lt;br /&gt;
bla bla bla ...&lt;br /&gt;
* Aufzählung&lt;br /&gt;
* Aufzählung&lt;br /&gt;
* Aufzählung&lt;br /&gt;
* Aufzählung&lt;br /&gt;
&lt;br /&gt;
# Aufzählung &amp;lt;ref name=&amp;quot;rrr&amp;quot;&amp;gt; aaa [xxxx yyy] &amp;lt;/ref&amp;gt;&lt;br /&gt;
# Aufzählung&lt;br /&gt;
# noch einmal&lt;br /&gt;
# Aufzählung&lt;br /&gt;
&lt;br /&gt;
== Ab hier Testbereich zum ausprobieren - kann ruhig verschandelt werden!!!==&lt;br /&gt;
&lt;br /&gt;
===Formatierprobleme===&lt;br /&gt;
&lt;br /&gt;
;Quellcode I:&lt;br /&gt;
:&amp;lt;pre&amp;gt;Zeile 1&lt;br /&gt;
Zeile2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:&amp;lt;pre&amp;gt;Zeile ..... &lt;br /&gt;
jajjj&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ ohne center&lt;br /&gt;
|-&lt;br /&gt;
| a || b&lt;br /&gt;
|-&lt;br /&gt;
| aaaaaa || bbbbb&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
{| {{Blauetabelle}} style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
|+ mit center&lt;br /&gt;
|-&lt;br /&gt;
| a || b&lt;br /&gt;
|-&lt;br /&gt;
| aaaaaa || bbbbb&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
{| style=&amp;quot;text-align:center;&amp;quot; {{Blauetabelle}} &lt;br /&gt;
|+ mit center&lt;br /&gt;
|-&lt;br /&gt;
| a || b&lt;br /&gt;
|-&lt;br /&gt;
| aaaaaa || bbbbb&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Formel ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;E=mc^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
http://images.allposters.com/images/GDF/Z1735D.jpg&lt;br /&gt;
&lt;br /&gt;
==Vorlage==&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
U(t) \,=\, U_0 \cdot e^{-\frac{t}{RC}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Test|aaa|bbb}}&lt;br /&gt;
&lt;br /&gt;
== Teste hier auch mal :-) ==&lt;br /&gt;
&lt;br /&gt;
[[neu|neue Ref]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\downarrow\uparrow&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hat du kopp wie Sieb mutdu aufschreiben ==&lt;br /&gt;
---------------------------&lt;br /&gt;
&lt;br /&gt;
Interrupts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Struktur:&lt;br /&gt;
&lt;br /&gt;
 Config InterruptXXX  		‘Konfiguriere Interrupt&lt;br /&gt;
 Enable Interrupts		‘generell Interrupts zulassen&lt;br /&gt;
 Enable  InterruptXXX		‘schalte speziell den InterruptXXX ein&lt;br /&gt;
 On  InterruptXXX   SprungXXX	‘verzweige bei InterruptXXX zu SprungXXX&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 ....Hauptprogramm		‘Hauptprogramm&lt;br /&gt;
 Loop&lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 SprungXXX:			‘Unterprogramm von InterruptXXX&lt;br /&gt;
 ....Ausführung			‘arbeitet hier etwas ab und springt mit Return &lt;br /&gt;
 Return				‚ wieder zurück, zum Hauptprogramm&lt;br /&gt;
=== xxx ===&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\overline{u} \vee \overline{v} = \overline{u \wedge v}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\bar{u}_1 \wedge \bar{u}_2 \wedge \cdots \wedge \bar{u}_n  &lt;br /&gt;
= \overline{u_1 \vee u_2 \vee \cdots \vee u_n}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\neg u_1 \wedge \neg u_2 \wedge \cdots \wedge \neg u_n  &lt;br /&gt;
= \neg (u_1 \vee u_2 \vee \cdots \vee u_n)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\bar{u} \vee u = 1&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\bar{u} \wedge u = 0&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\bar{A_1} = \overline{A}_1 = \overline{A_1}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\uparrow a&amp;lt;/math&amp;gt;&lt;br /&gt;
|&amp;lt;math&amp;gt;\Downarrow \Uparrow&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Jetzt will ich das ganze auch mal testen! ==&lt;br /&gt;
Test '''Test''' ''Test'' '''''Test'''''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^2 = b^2 + c^2&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;!-- warum geht das mit den ² dingern nich!?! --&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;a=b+c&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;           &amp;lt;!-- ahh so gehts --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^2=b^2+c^2&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt; &lt;br /&gt;
*Dies könnte eine Aufzählung sein&lt;br /&gt;
**und dies einer der Inhalte&lt;br /&gt;
**dies auch&lt;br /&gt;
***und noch ein inhalt von &amp;quot;dies auch&amp;quot;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 nun will ich&lt;br /&gt;
 auch einmal versuchen&lt;br /&gt;
 ein quelltextfenster&lt;br /&gt;
 darzustellen!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{{FarbigerRahmen|&lt;br /&gt;
Wichtiger Text wird in der Mitte geschrieben&amp;lt;br/&amp;gt;&lt;br /&gt;
und zusätzlich ROT umrahmt!&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NAND GATTER ===&lt;br /&gt;
&amp;lt;math&amp;gt; x=a \overline { acb } b&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NOR GATTER ===&lt;br /&gt;
&amp;lt;math&amp;gt; x=a \overline { v } b&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Elayne|Elayne]] 16:20, 27. Dez 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Getriebe ==&lt;br /&gt;
&lt;br /&gt;
=== Achsabstände ===&lt;br /&gt;
Das größte Problem bei selbstgebauten Getrieben ist die Bestimmung&lt;br /&gt;
der Achsabstände. &amp;lt;br&amp;gt;&lt;br /&gt;
Zu weite Abstände verursachen zum einen Schäden an den Zahnrädern &amp;lt;br&amp;gt;&lt;br /&gt;
und zu kurze Abstände sorgen dafür, dass sich das Getriebe,&amp;lt;br&amp;gt; &lt;br /&gt;
wenn überhaupt, nicht drehen lässt und auch schneller verschleißen kann.&lt;br /&gt;
&lt;br /&gt;
Ein wichtiger Parameter, welcher zur Berechnung der Achsabstände benötigt wird,&amp;lt;br&amp;gt;&lt;br /&gt;
ist die Modulgröße oder auch Modulzahl genannt.&lt;br /&gt;
&lt;br /&gt;
Für Zahnräder mit unbekannter Modulgröße gibt es Zahnradlehren,&lt;br /&gt;
welche das ermitteln des Modul's erleichtert ohne raten zu müssen&lt;br /&gt;
&lt;br /&gt;
Der Abstand der Zahnradachsen lässt sich wie folgend ermitteln:&lt;br /&gt;
&lt;br /&gt;
   Anzahl der beiden Zahnradzähne (welche ineiandergreifen) zusammenzählen,&lt;br /&gt;
   davon dann die Hälfte mit der Modulzahl multiplizieren.&lt;br /&gt;
&lt;br /&gt;
=Quellen=&lt;br /&gt;
&lt;br /&gt;
;Quelle1: blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah &lt;br /&gt;
:{|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ghdjs gdjs dgjs &lt;br /&gt;
   dgsjdghsj&lt;br /&gt;
   dgsdhgjs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;Quelle2 und Quelle3: blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah &lt;br /&gt;
:{|&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| '''Quelle2'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ghdjs gdjs dgjs &lt;br /&gt;
   dgsjdghsj&lt;br /&gt;
   dgsdhgjs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
| &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; &amp;lt;!-- space --&amp;gt;&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;| '''Quelle3'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ghdjs gdjs dgjs &lt;br /&gt;
   dgsjdghsj&lt;br /&gt;
   dgsdhgjs&lt;br /&gt;
ghdjs gdjs dgjs &lt;br /&gt;
   dgsjdghsjjavascript:insertTags('\'\'\'','\'\'\'','Fetter Text');&lt;br /&gt;
Fetter Text&lt;br /&gt;
   dgsdhgjs&lt;br /&gt;
ghdjs gdjs dgjs &lt;br /&gt;
   dgsjdghsj&lt;br /&gt;
   dgsdhgjs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Sudoku==&lt;br /&gt;
&lt;br /&gt;
[[Bild:sodoku.gif|center|http://www.rn-wissen.de]]&lt;br /&gt;
&lt;br /&gt;
==Quellen==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Bildergallery ganz einfach anlegen==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:kaercherrobot.jpg&lt;br /&gt;
Image:siemensvsr8000unten.jpg|Siemens von unten&lt;br /&gt;
Image:siemensvsr8000buerste.jpg&lt;br /&gt;
Image:siemensvsr8000basis.jpg|Die Basisstation&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Test]]&lt;br /&gt;
&lt;br /&gt;
[[Media:Beispiel.mp3]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
darf ich auch mal, ja? Gut:&lt;br /&gt;
L'''o'''r''e''m ipsum dolor sit amet.......&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ebene 2 Überschrift ==&lt;br /&gt;
Mal ein Test&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wie erzeuge ich eigentlich ein Inhaltsverzeichnis? ==&lt;br /&gt;
A: Inhaltsverzeichnis wird vom Wiki automatisch erzeugt, aber einer bestimmten Anzahl Überschriften.&lt;br /&gt;
Oder man gibt &amp;quot;__ TOC __&amp;quot; an (ohne Leerzeichen), dann kommts an dieser Stelle.&lt;br /&gt;
&lt;br /&gt;
Siehe Hilfeseiten:&lt;br /&gt;
* [[RN-Wissen:Editierhilfe|Editierhilfe]]&lt;br /&gt;
* [[RN-Wissen:Hilfe|Hilfe]]&lt;br /&gt;
* [[Hilfe:Inhaltsverzeichnis|Inhaltsverzeichnis]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Möchte nur mal testen wie die Editoren Funktionieren und wie man damit klar kommt&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Unformatierten Text hier einfügen&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=I2C&amp;diff=14854</id>
		<title>I2C</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=I2C&amp;diff=14854"/>
				<updated>2009-04-22T21:23:30Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Link entfernt, schaut nicht aus, wenn das ein temp. Problem wäre&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''IIC''', '''Inter-IC''' bzw. '''Inter Integrated Circuit''' Bus&lt;br /&gt;
__TOC__&lt;br /&gt;
==Geschichte==&lt;br /&gt;
&lt;br /&gt;
Der I2C-Bus (''Inter Integrated Circuit'') ist ein serieller synchroner Zweidraht-Bus, der vor rund 20 Jahren von Philips entwickelt wurde. Was die Philips-Designer seinerzeit kaum ahnen konnten: Ihr Inter-IC Bus (I2C, &amp;quot;1 Squared C&amp;quot;) ist mittlerweile ein Industriestandard für Steuerungs-, Diagnose- und Überwachungslösungen in unzähligen Embedded-Applikationen. Mit einfacher Implementierung, niedrigen Kosten und einer Übertragungsrate bis 3,4 MBit/s ist der Bus-Veteran aktuell wie nie zuvor.&lt;br /&gt;
&lt;br /&gt;
Ziel der damaligen Entwicklung war ein hierarchisches Bus-System, über das mehrere ICs bei geringstem Aufwand (Leiterbahnen, Komponenten, etc.) miteinander kommunizieren sollten. Daher bot sich eine serielle Struktur an, um&lt;br /&gt;
* im Vergleich zu parallelen Bus-Systemen &lt;br /&gt;
* mit weniger Leiterbahnen und I/0s auszukommen und so letztendlich Platinenfläche, IC-Abmessungen (Pin-Anzahl) und Kosten zu reduzieren. &lt;br /&gt;
&lt;br /&gt;
Aus diesen Überlegungen entstand schließlich ein echter bidirektionaler Zweidraht-Bus in Master/Slave-Architektur mit integriertem Übertragungsprotokoll und Software-Adressierung, der nur zwei Verbindungen zwischen den ICs/Boards erfordert: Die Taktleitung SCL (Serial Clock Line) und die Datenleitung SDA (Serial Data Line).&lt;br /&gt;
&lt;br /&gt;
Das bedeutet in der Praxis, dass z.B. ein Microcontroller ein ganzes &amp;quot;Netzwerk&amp;quot; von Chips mit nur zwei I/O Pins und einfacher Software steuern bzw. für bestimmte Funktionen nutzen kann. Ursprünglich wurde der I2C-Bus für Interaktionen zwischen einigen wenigen ICs entwickelt, die auf derselben Platine montiert waren, etwa zur Steuerung der Abstimmung von Autoradios oder TV-Geräten.&lt;br /&gt;
&lt;br /&gt;
Dabei betrug die Übertragungsrate nur 100 kBit/s bei einer zulässigen Bus-Kapazität von 400 pF. Den ständig steigenden Leistungsanforderungen folgend, wurde die Übertragungsrate 1992 und 1998 auf 400 kBit/s bzw. 3,4 Mbit/s angehoben. Ein weiterer großer Vorteil des I2C-Bus besteht darin, dass auch deutlich langsamere Busteilnehmer am Bus betrieben werden können. Siehe dazu [[Clock Stretching]].&lt;br /&gt;
&lt;br /&gt;
Heute wird der I2C-Bus auch in Systemen mit mehreren Boards wie Blade- oder Rack-Mount-Servern eingesetzt, wobei I2C-Hot-Swap-Buffer ein störungsfreies Einsetzen oder Austauschen von Boards während des Betriebs gewährleisten. Zum Beispiel wird der I2C-Bus heute auch bei nahezu allen Projekten aus dem Roboternetz verwendet. Siehe dazu [[:Kategorie:Projekte|Projekte und Schaltungen]]. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe neuer Expansions- und Steuerungs-Bauelemente kann der I2C-Bus inzwischen über die 400-pF-Grenze (ca. 20 bis 30 ICs pro Bus-Segment) hinaus erweitert werden. Dadurch können Entwickler mehr Chips '''sogar mehrere identische ICs mit der selben Adresse''' anschließen und flexibel auf die steigende Zahl von I2C-Bauelementen reagieren.&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil des I2C-Bus ist auch die einfache Ansteuerung. Da keine festen Taktzeiten eingehalten werden müssen, können sowohl langsame als auch sehr schnelle Busteilnehmer, Chips und Programmiersprachen eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
http://www.roboternetz.de/bilder/i2cbeitrag1.gif&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Bitübertragung==&lt;br /&gt;
&lt;br /&gt;
Um ein Bit als gültig zu werten, muss SCL High sein. SDA darf sich währendessen nicht ändern (es sei denn es handelt sich um die Start- oder Stoppbedingung, doch dazu später mehr). Um beispielsweise eine 1 zu übertragen, müssen SDA sowie SCL High sein. Für eine 0, muss SDA Low sein, SCL jedoch High.&lt;br /&gt;
&lt;br /&gt;
[[Bild:I2C_Bituebertragung.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Start- und Stoppbedingungen==&lt;br /&gt;
&lt;br /&gt;
===Startbedingung===&lt;br /&gt;
&lt;br /&gt;
Um die angeschlossenen ICs zu informieren, dass eine Datenübertragung beginnt, muss eine Startbedingung erzeugt werden. Vorher kann keine Datenübertragung erfolgen.&lt;br /&gt;
Eine Startbedingung wird erzeugt, indem, während SCL High ist, SDA von High auf Low wechselt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:I2C_Startbedingung2.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Stoppbedingung===&lt;br /&gt;
&lt;br /&gt;
Die Stoppbedingung funktioniert genau anders herum: SCL muss High sein und während dieser Phase wechselt SDA von Low auf High.&lt;br /&gt;
Die Stoppbedingung beendet, wie der Name schon vermuten lässt, eine Datenübertragung. So kann der Master signalisieren, dass er keine weiteren Daten empfangen oder senden möchte.&lt;br /&gt;
&lt;br /&gt;
[[Bild:I2C_Stoppbedingung.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Repeated-Startbedingung===&lt;br /&gt;
&lt;br /&gt;
Da die Stoppbedingung gleichzeitig auch eine Freigabe des Bus bedeutet (und dann könnte ja ein anderer Master den Bus übernehmen), gibt es auch den Start ohne vorheriges Stopp. Das wird dann benötigt, wenn vor dem Lesen erst ein Argument/Command geschickt werden muß. Abfolge:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 I2C Start&lt;br /&gt;
 I2C Send Write-Address&lt;br /&gt;
 I2C Send Argument&lt;br /&gt;
 I2C Start oder Repeated Start&lt;br /&gt;
 I2C Send Read-Address&lt;br /&gt;
 I2C Read Data&lt;br /&gt;
 ....&lt;br /&gt;
 I2C Stopp oder Release Bus&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Datenübertragung größerer Datenmengen==&lt;br /&gt;
&lt;br /&gt;
===Byteübertragung===&lt;br /&gt;
&lt;br /&gt;
Wenn ein Byte verschickt werden soll, dann wird als erstes das höchstwertigste Bit verschickt. Dann folgen die anderen bis hin zum niederwertigstem. Folgende Tabelle soll dieses Schema anhand der Zahl 109 verdeutlichen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align = &amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
 | '''Dezimal'''&lt;br /&gt;
 | 128&lt;br /&gt;
 | 64&lt;br /&gt;
 | 32&lt;br /&gt;
 | 16&lt;br /&gt;
 | 8 &lt;br /&gt;
 | 4 &lt;br /&gt;
 | 2 &lt;br /&gt;
 | 1 &lt;br /&gt;
 |-&lt;br /&gt;
 | '''Dual'''&lt;br /&gt;
 | 0&lt;br /&gt;
 | 1  &lt;br /&gt;
 | 1&lt;br /&gt;
 | 0&lt;br /&gt;
 | 1&lt;br /&gt;
 | 1&lt;br /&gt;
 | 0&lt;br /&gt;
 | 1&lt;br /&gt;
 |-&lt;br /&gt;
 | '''Übertragungsreihenfolge'''&lt;br /&gt;
 | 1&lt;br /&gt;
 | 2  &lt;br /&gt;
 | 3&lt;br /&gt;
 | 4&lt;br /&gt;
 | 5&lt;br /&gt;
 | 6&lt;br /&gt;
 | 7&lt;br /&gt;
 | 8&lt;br /&gt;
 |}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie man sieht wird das Bit, das die Dezimalzahl 128 repräsentiert, als erstes übertragen.&lt;br /&gt;
&lt;br /&gt;
===Bestätigung (Acknowledgment)===&lt;br /&gt;
&lt;br /&gt;
Der Empfänger quittiert den Erhalt der Daten mit einer Bestätigung (oder auch Acknowledgment). Nach acht Datenbits und folglich auch acht Taktimpulsen wird eine Bestätigung erzeugt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:I2C_Bestaetigung.png|center]]&lt;br /&gt;
&lt;br /&gt;
Der Empfänger &amp;quot;zieht&amp;quot; SDA auf Low, bis der Master den neunten Taktimpuls generiert hat. Findet diese Bestätigung statt, bedeutet dies auch gleichzeitig, dass der Empfänger ein weiteres Byte empfangen möchte.&lt;br /&gt;
Möchte der Empfänger kein weiteres Byte mehr empfangen, dann verschickt er keine Bestätigung. Das eigentliche Ende der Datenübertragung wird aber durch die Stoppbedingung ausgelöst (Oder die &amp;quot;Repeated Startbedingung&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Adressierung==&lt;br /&gt;
&lt;br /&gt;
Das erste Byte nach der Startbedingung, das der Master verschickt, ist die Adresse des Slaves, den er ansprechen möchte.&lt;br /&gt;
&lt;br /&gt;
===7-Bit Adressierung===&lt;br /&gt;
&lt;br /&gt;
Die 7-Bit Adressierung ist die erste Adressierungsform des I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C Busses und ermöglicht prinzipiell bis zu 128 (2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;) Geräte an einem Bus. Durch die Reservierung einiger Adressen, unter anderem für die 10-Bit Adressierung, ist die 7-Bit Addressierung auf 112 Geräte begrenzt und ermöglicht so eine konfliktfreie Adressierung des 7-Bit und des 10-Bit Adressraumes&lt;br /&gt;
(siehe Tabelle unten: [[#Reservierte_Adressen|Reservierte Adressen]]).&lt;br /&gt;
&lt;br /&gt;
====Aufbau einer 7-Bit Adresse====&lt;br /&gt;
&lt;br /&gt;
[[Bild: I2C_Adresse_Aufbau.png|center]]&lt;br /&gt;
&lt;br /&gt;
Auch hier wird mit dem wichtigstem Bit begonnen. Da ein Byte aber acht Bits hat, und die Adresse nur sieben Bits, gibt es noch ein Bit, das die Datenrichtung angibt. Dieses Bit bestimmt, ob der Master Daten empfangen möchte oder ob er dem Slave Daten schicken möchte. Dieses letzte Bit wird als R/W Bit bezeichnet (&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; steht für &amp;quot;schreiben&amp;quot;, &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; für &amp;quot;lesen&amp;quot;).&lt;br /&gt;
Hat ein Slave seine Adresse richtig verstanden und ist bereit Daten zu empfangen oder, je nach Fall, zu verschicken, dann sendet er eine Bestätigung.&lt;br /&gt;
Hat er seine Adresse nicht richtig mitbekommen, oder ist gerade nicht in der Lage seine Daten zu verschicken oder zu empfangen, dann bleibt die Bestätigung aus. Der Master kann dann eine Stoppbedingung erzeugen, sodass die Datenübertragung abgebrochen wird.&lt;br /&gt;
&lt;br /&gt;
====Reservierte Adressen====&lt;br /&gt;
&lt;br /&gt;
Einige Adressen wurden reserviert, um den Bus ausbaufähig zu halten oder um Missverständnissen vorzubeugen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align = &amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Adresse || R/W Bit || Beschreibung&lt;br /&gt;
 |-&lt;br /&gt;
 | 0000000 || 0 || General Call Adresse&lt;br /&gt;
 |-&lt;br /&gt;
 | 0000001 || X || CBUS Adresse&lt;br /&gt;
 |-&lt;br /&gt;
 | 0000010 || X || Reserviert für ein anderes Busformat&lt;br /&gt;
 |-&lt;br /&gt;
 | 0000011 || X || Für zukünftige Erweiterungen reserviert&lt;br /&gt;
 |-&lt;br /&gt;
 | 00001XX || X || Für zukünftige Erweiterungen reserviert&lt;br /&gt;
 |-&lt;br /&gt;
 | 11111XX || X || Für zukünftige Erweiterungen reserviert&lt;br /&gt;
 |-&lt;br /&gt;
 | 11110XX || X || 10-Bit Adressierung&lt;br /&gt;
 |}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Abzug der Reservierten Adressen bleiben also 112 freie Adressen übrig, die man mit der 7-Bit Adressierung verwenden kann.&lt;br /&gt;
&lt;br /&gt;
====Subadressen====&lt;br /&gt;
&lt;br /&gt;
Als Subadressen bezeichnet man die vom Benutzer programmierbaren Adressbits einer Adresse. Dies sind bei den meisten ICs die letzten drei Adressbits. Da man so acht verschiedene Adresskombinationen zusammenbekommt (2&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;), kann man folglich maximal acht dieser ICs an einem Bus gleichzeitig nutzen.&lt;br /&gt;
Folgende Tabelle verdeutlicht dies am Beispiel des I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C Bausteins PCF 8570:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align = &amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
 |- {{Hintergrund1}}&lt;br /&gt;
!| 1. Teil: Feste Adresse || 2. Teil: Subadresse&lt;br /&gt;
 |-&lt;br /&gt;
 | 1010 || XXX&lt;br /&gt;
 |}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===10-Bit Adressierung===&lt;br /&gt;
&lt;br /&gt;
Da es mit der Zeit immer mehr I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C-Bausteine wurden und es schon vorher Überschneidungen, was die Adressen betraf, gab, wurden 10-Bit Adressen eingeführt. Diese erlauben bis zu 1024 (2&amp;lt;sup&amp;gt;10&amp;lt;/sup&amp;gt;) Geräte an einem Bus. &lt;br /&gt;
Durch die Reservierung der Adressen 1111 0XX und des R/W Bits dieser Adresse, werden mögliche 7-Bit Geräte am Bus nicht gestört. Im Gegenteil, es können sogar 7- und 10-Bit Geräte an einem Bus betrieben werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align = &amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
 |- {{Hintergrund1}}&lt;br /&gt;
!| Reservierte Adresse || Adresse Teil 1 || R/W Bit || || Adresse Teil 2 || &lt;br /&gt;
 |-&lt;br /&gt;
 | 11110 || XX || X || 1. Bestätigung || XXXXXXXX || 2. Bestätigung&lt;br /&gt;
 |}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als erstes wird die reservierte Adresse mit den ersten fünf Bits &amp;quot;11110&amp;quot; gesendet. Dadurch wird &amp;amp;ndash; wie schon gesagt &amp;amp;ndash; das Stören von Bausteinen mit 7-Bit Adressen vermieden. Nun folgen die ersten zwei Bits der eigentlichen Adresse. Dann kommt schon das R/W Bit, da nach einem Byte immer eine Bestätigung folgen muss, wenn eine weitere Datenübertragung erwünscht ist. Da es vorkommen kann, dass mehrere Teilnehmer auf den ersten Teil der Adresse reagieren, werden auch alle diese betroffenen Teilnehmer die Bestätigung generieren. Nach der ersten Bestätigung kommt der 2. Teil der Adresse, der diesmal ein ganzes Byte ist. Alle Teilnehmer, bei denen der erste Adressteil schon zugetroffen hat, werden auch das zweite Adressbyte überprüfen, aber nur der nun adressierter Teilnehmer wird eine Bestätigung erzeugen. Nach der zweiten Bestätigung kann der eigentliche Datenaustausch beginnen.&lt;br /&gt;
&lt;br /&gt;
==Beispiel einer Datenübertragung==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
Zum Abschluss noch das schematische Beispiel einer vollständigen Kommunikation zwischen einem Mikrocontroller als Master und einem Slave mit 7-Bit Adresse. In diesem Fall wird schreibend auf den Slave zugegriffen. Der Master ist also ein Sender, während der Slave als Empfänger fungiert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:I2C_Datenuebertragung.png|center]]&lt;br /&gt;
&lt;br /&gt;
Nach der Startbedingung folgt die Slaveadresse mit dem R/W Bit. Dann kommt die obligatorische Bestätigung und der Master sendet ein Byte. Nun folgt wieder eine Bestätigung und der Master sendet wiederum ein Byte. Der Slave sendet wieder seine Bestätigung, jedoch möchte der Master jetzt keine Daten mehr senden, da SDA jetzt auf +5 Volt liegt. Da nun das Ende der Datenübertragung erreicht ist, löst der Master die Stoppbedingung aus. &lt;br /&gt;
&lt;br /&gt;
===Oszillogramm===&lt;br /&gt;
&lt;br /&gt;
Hier ein typisches Bild einer I2C-Kommunikation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
http://www.tobias-schlegel.de/PublicData/DOUBLE.png&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Programmierung Beispiel===&lt;br /&gt;
Ein typisches Beispiel wie in einer Programmiersprache (hier [[Bascom]] Basic) Daten über den I2C-Bus verschickt werden:&lt;br /&gt;
&lt;br /&gt;
 i2c_init &lt;br /&gt;
 i2c_start &lt;br /&gt;
 i2c_sendebyte(slaveid) &lt;br /&gt;
 i2c_sendebyte(wert1) &lt;br /&gt;
 i2c_sendebyte(wert2) &lt;br /&gt;
 i2c_stop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''Artikelautoren:''&lt;br /&gt;
: [[Benutzer:Frank|Frank]]&lt;br /&gt;
: [[Benutzer:Vish|Vish]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Verwendete Quellen für diesen Text:&lt;br /&gt;
# Philips Infos&lt;br /&gt;
# Spoerle Produktinfos &lt;br /&gt;
# mehrere Roboternetz-Artikel&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
*[[RN-Definitionen]]&lt;br /&gt;
*[[Clock Stretching]]&lt;br /&gt;
*[[I2C Chip-Übersicht]]&lt;br /&gt;
*[[TWI|Two-wire Serial Interface (TWI) bei AVR Megas]]&lt;br /&gt;
*[[TWI_Slave_mit_avr-gcc|TWI-Slave mit avr-gcc]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=28 Spezifikationen]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=4509 PC -&amp;gt; I2C Bus Adapter]&lt;br /&gt;
* [http://www.semiconductors.philips.com/pip/P82B715.html I2C über 50 Meter mit I2C Bus Extender möglich  (IC P82B715)]]&lt;br /&gt;
* [http://www.i2c-bus.org/ i2c-bus.org - Hilfreiche I2C Informationen / Englisch]&lt;br /&gt;
* [http://www.esacademy.com/faq/i2c/index.htm I2C Technical Overview and Frequently Asked Questions  / Englisch]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Diskussion:Timer/Counter_(Avr)&amp;diff=14818</id>
		<title>Diskussion:Timer/Counter (Avr)</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Diskussion:Timer/Counter_(Avr)&amp;diff=14818"/>
				<updated>2009-04-12T22:15:46Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der Link zum Java Applet zur Timer Berechnung funktionniert anscheinend nicht mehr. --[[Benutzer:Cbg|cbg]] 00:06, 13. Apr 2009 (CEST)&lt;br /&gt;
&lt;br /&gt;
der Link geht per DynDNS, der ist wohl grad nicht online, evtl. findet sich das Applet an anderer Stelle !?&lt;br /&gt;
--[[Benutzer:Linux 80|linux_80]] 00:15, 13. Apr 2009 (CEST)&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Ultraschallsensor_SRF02_am_RN-Board&amp;diff=14625</id>
		<title>Ultraschallsensor SRF02 am RN-Board</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Ultraschallsensor_SRF02_am_RN-Board&amp;diff=14625"/>
				<updated>2009-03-01T19:06:50Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Mode-Pin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Noch recht wenig bekannt ist der neue kompakte Ultraschallsensor SRF02. Dieser Sensor stellt eine preiswerte Alternative zu den Sensoren SRF05 oder SRF10 dar, kann jedoch keine kleineren Entfernungen als 15 cm messen. Allerdings reicht der Messbereich von 15cm bis ca. 6m durchaus für viele Anwendungen aus.&lt;br /&gt;
&lt;br /&gt;
Der Sensor lässt sich wahlweise per RS232 oder I2C anschließen. Jeweils bis zu 16 Stück können an einer Schnittstelle betrieben werden, auch an der RS232 TTL was durchaus ungewöhnlich ist. Die Beispiele sollen demonstrieren wie einfach der Sensor an ein RN-Board angeschlossen werden kann. Konkret verwenden wir hier das [[RN-Control]] Board, allerdings ist es sehr ähnlich auch bei allen anderen RN- und AVR-Boards. Die Programme sind in Bascom-Basic programmiert und können somit fast ohne Änderung auf alle anderen RN-Boards übertragen werden (lediglich Ports und Quarztakt anpassen).&lt;br /&gt;
&lt;br /&gt;
==SRF02 Daten==&lt;br /&gt;
Der erste Sensor aus der SRF-Reihe der mit nur einem Ultraschallwandler auskommt. Dennoch können sich die Leistungen zeigen. Vorallem die Tatsache das sowohl RS232 und I2C-Bus Schnittstelle vorhanden ist dürfte viele Bastler erfreuen.&lt;br /&gt;
&lt;br /&gt;
* Betriebsspannung 5V (stabilisiert) &lt;br /&gt;
* Stromaufnahme nur 4mA (typisch) &lt;br /&gt;
* Ultraschallfrequenz 40khz &lt;br /&gt;
* Reichweite 15cm bis 6 Meter &lt;br /&gt;
* Schnittstelle RS232 (TTL) und I2C-Bus &lt;br /&gt;
* Ausgabeeinheit wahlweise mm, inch oder uS &lt;br /&gt;
* Einfachste Verwendung, keine Kalibration/Justierung notwendig&lt;br /&gt;
* Größe 24mm x 20mm x 17mm &lt;br /&gt;
&lt;br /&gt;
[[Bild:srf02_germany.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==SRF02 im I2C-Mode==&lt;br /&gt;
In dem Beispiel wurde ein Adapter verwendet, es ginge natürlich auch ohne indem man ein passendes Kabel für den I2C Stecker bastelt oder aber die Steckleisten auf dem Board RN-Control nutzt.&lt;br /&gt;
&lt;br /&gt;
Der Mode-Pin bleibt unbeschaltet.&lt;br /&gt;
&lt;br /&gt;
[[Bild:srf02_i2c_rncontrol.jpg|framed|center|Der neue Ultraschallsensor SRF02 im I2C Mode über Adapter an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'###################################################&lt;br /&gt;
'SRF02_rncontrol_i2c_beispiel2.bas&lt;br /&gt;
'für&lt;br /&gt;
'RoboterNetz Board RN-CONTROL (ab Version 1.1)&lt;br /&gt;
'und das SRF02 Ultraschallmodul für Entfernungsmessung&lt;br /&gt;
'Datenblatt zu SRF02:&lt;br /&gt;
'http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=357&lt;br /&gt;
'Anschlussbeschreibung:&lt;br /&gt;
'http://www.roboternetz.de/wissen/index.php/Sensorarten&lt;br /&gt;
&lt;br /&gt;
'Aufgabe:&lt;br /&gt;
' Gibt die Firmware-Version vom SRF02 aus und&lt;br /&gt;
' anschließend in einer Endlosschleife die&lt;br /&gt;
' Entfernung von Objekten in Zentimetern&lt;br /&gt;
' Die Entfernung wird 1 mal pro Sekunde über RS232&lt;br /&gt;
' ausgegeben&lt;br /&gt;
' Hier wird noch genau gescheckt ob ein Sensor die&lt;br /&gt;
' Messung schon beendet hat. Dadurch sind noch&lt;br /&gt;
' schnellere Messungen als nur 15 pro Sekunde möglich&lt;br /&gt;
&lt;br /&gt;
'Autor: Frank  (Roboternetz)&lt;br /&gt;
'Weitere Beispiele und Beschreibung der Hardware&lt;br /&gt;
'unter http://www.Roboternetz.de oder robotikhardware.de&lt;br /&gt;
'#######################################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Declare Function Srf02_firmware(byval Slaveid As Byte) As Byte&lt;br /&gt;
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot;&lt;br /&gt;
$framesize = 42&lt;br /&gt;
$swstack = 42&lt;br /&gt;
$hwstack = 42&lt;br /&gt;
&lt;br /&gt;
$crystal = 16000000                                         'Quarzfrequenz&lt;br /&gt;
$baud = 9600&lt;br /&gt;
&lt;br /&gt;
Config Scl = Portc.0                                        'Ports fuer IIC-Bus&lt;br /&gt;
Config Sda = Portc.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Const Srf02_slaveid = &amp;amp;HE0                                  'Standard I2C Adresse von SRF02&lt;br /&gt;
&lt;br /&gt;
Dim Entfernung As Integer&lt;br /&gt;
Dim V As Byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   Wait 3                                                   'Warte 3 Sekunden&lt;br /&gt;
   I2cinit&lt;br /&gt;
   Print &amp;quot;SRF02 Testprogramm von robotikhardware.de&amp;quot;&lt;br /&gt;
   Print &amp;quot;SRF02 Ultraschall-Firmware Version:&amp;quot; ; Srf02_firmware(srf02_slaveid)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   V = 1&lt;br /&gt;
   Do&lt;br /&gt;
     Entfernung = Srf02_entfernung(srf02_slaveid)&lt;br /&gt;
     Print &amp;quot;Entfernung:&amp;quot; ; Entfernung ; &amp;quot;cm&amp;quot;&lt;br /&gt;
     Wait 1&lt;br /&gt;
   Loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
End&lt;br /&gt;
'------------- Hilfsfunktionen für SRF02 ----------&lt;br /&gt;
Function Srf02_firmware(byval Slaveid As Byte) As Byte&lt;br /&gt;
  Local Firmware As Byte&lt;br /&gt;
  Local Slaveid_read As Byte&lt;br /&gt;
  slaveid_read = Slaveid + 1&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Slaveid&lt;br /&gt;
  I2cwbyte 0 'Leseregister festlegen&lt;br /&gt;
  I2cstop&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Slaveid_read&lt;br /&gt;
  I2crbyte Firmware , Nack&lt;br /&gt;
  I2cstop&lt;br /&gt;
  Srf02_firmware = Firmware&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
Function Srf02_entfernung(byval Slaveid As Byte) As Integer&lt;br /&gt;
  Local Lob As Byte&lt;br /&gt;
  Local Hib As Byte&lt;br /&gt;
  Local Firmware As Byte&lt;br /&gt;
  Local Temp As Byte&lt;br /&gt;
  Local Slaveid_read As Byte&lt;br /&gt;
&lt;br /&gt;
  slaveid_read = Slaveid + 1&lt;br /&gt;
&lt;br /&gt;
  'Messvorgang in starten&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Slaveid&lt;br /&gt;
  I2cwbyte 0&lt;br /&gt;
  I2cwbyte 81 'in Zentimetern messen&lt;br /&gt;
  I2cstop&lt;br /&gt;
&lt;br /&gt;
  Warteaufmessung:&lt;br /&gt;
    Waitms 1&lt;br /&gt;
    Firmware = Srf02_firmware(slaveid)&lt;br /&gt;
  If Firmware = 255 Then Goto Warteaufmessung&lt;br /&gt;
&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Slaveid&lt;br /&gt;
  I2cwbyte 2 'Leseregister festlegen&lt;br /&gt;
  I2cstop&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Slaveid_read&lt;br /&gt;
  I2crbyte Hib , Ack&lt;br /&gt;
  I2crbyte Lob , Nack&lt;br /&gt;
  I2cstop&lt;br /&gt;
  Srf02_entfernung = Makeint(lob , Hib)&lt;br /&gt;
 End Function&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SRF02 im RS232-Mode==&lt;br /&gt;
Das nachfolgende Beispiel demonstriert wie einfach sich ein oder mehrere SRF02 Ultraschallsensoren an RN-Control anschließen lassen. Da wir die normale RS232 an RN-Control weiterhin benötigen um Daten und Ergebnisse von RN-Control zum PC zu senden, definieren wir per Software einfach eine neue Software RS232 Schnittstelle auf die Ports PA0 und PA1. Dadurch können die SRF02´s sehr einfach an die orange Stecklemme von RN-Control angeschlossen werden. Wir können uns so den Stecker-Adapter sparen. Es wäre natürlich auch jeder andere freie Port verwendbar.&lt;br /&gt;
&lt;br /&gt;
Der Mode-Pin wird mit GND verbunden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:srf02_an_rncontrol_rs232mode.jpg|framed|center|Der neue Ultraschallsensor SRF02 im RS232 Mode an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'###################################################&lt;br /&gt;
'SRF02_rncontrol_rs232_beispiel.bas&lt;br /&gt;
'für&lt;br /&gt;
'RoboterNetz Board RN-CONTROL (ab Version 1.1)&lt;br /&gt;
'und das SRF02 Ultraschallmodul für Entfernungsmessung&lt;br /&gt;
'Datenblatt zu SRF02:&lt;br /&gt;
'http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=357&lt;br /&gt;
'Anschlussbeschreibung:&lt;br /&gt;
'http://www.roboternetz.de/wissen/index.php/Sensorarten&lt;br /&gt;
&lt;br /&gt;
'Aufgabe:&lt;br /&gt;
' Gibt die Firmware-Version vom SRF02 aus und&lt;br /&gt;
' anschließend in einer Endlosschleife die&lt;br /&gt;
' Entfernung von Objekten in Zentimetern&lt;br /&gt;
' Die Entfernung wird 1 mal pro Sekunde über RS232&lt;br /&gt;
' ausgegeben&lt;br /&gt;
' Dieses Beispiel nutzt den RS232 Mode vom SRF02&lt;br /&gt;
' Um die Ergebnisse auch gleichzeitig an PC&lt;br /&gt;
' übermitteln zu können, wird in dem Beispiel eine&lt;br /&gt;
' zweite RS232 Schnittstelle per Software eingerichtet.&lt;br /&gt;
' Dadurch kann der Sensor (oder auch mehrere) bequem&lt;br /&gt;
' an der Steckklemme angeschlossen werden&lt;br /&gt;
&lt;br /&gt;
'Autor: Frank  (Roboternetz)&lt;br /&gt;
'Weitere Beispiele und Beschreibung der Hardware&lt;br /&gt;
'unter http://www.Roboternetz.de oder robotikhardware.de&lt;br /&gt;
'#######################################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Declare Function Srf02_firmware(byval Slaveid As Byte) As Byte&lt;br /&gt;
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot;&lt;br /&gt;
$framesize = 42&lt;br /&gt;
$swstack = 42&lt;br /&gt;
$hwstack = 42&lt;br /&gt;
&lt;br /&gt;
$crystal = 16000000                                         'Quarzfrequenz&lt;br /&gt;
$baud = 9600                                                'Normale Hardware RS232 (hier hängt PC dran)&lt;br /&gt;
&lt;br /&gt;
Open &amp;quot;COMA.0:9600,8,N,2&amp;quot; For Output As #1                   'Port PA0 wird als TX definiert&lt;br /&gt;
Open &amp;quot;COMA.1:9600,8,N,2&amp;quot; For Input As #2                    'Port PA1 wird als RX definiert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Const Srf02_slaveid = 0                                     'Standard RS232 Slave ID von SRF02&lt;br /&gt;
Dim Entfernung As Integer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   Wait 3                                                   'Warte 3 Sekunden&lt;br /&gt;
   Print &amp;quot;SRF02 RS232 Testprogramm von robotikhardware.de&amp;quot;&lt;br /&gt;
   Print &amp;quot;SRF02 Ultraschall-Firmware Version:&amp;quot; ; Srf02_firmware(srf02_slaveid)&lt;br /&gt;
   Print &amp;quot;PA0 wird TX und PA1 wird als RX genutzt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   V = 1&lt;br /&gt;
   Do&lt;br /&gt;
     Entfernung = Srf02_entfernung(srf02_slaveid)&lt;br /&gt;
     Print &amp;quot;Entfernung:&amp;quot; ; Entfernung ; &amp;quot;cm&amp;quot;&lt;br /&gt;
     Wait 1&lt;br /&gt;
   Loop&lt;br /&gt;
End&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'------------- Hilfsfunktionen für SRF02 ----------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function Srf02_firmware(byval Slaveid As Byte) As Byte&lt;br /&gt;
&lt;br /&gt;
   Print #1 , Chr(slaveid) ; Chr(93);&lt;br /&gt;
   Srf02_firmware = Waitkey(#2)&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function Srf02_entfernung(byval Slaveid As Byte) As Integer&lt;br /&gt;
Local Lob As Byte&lt;br /&gt;
Local Hib As Byte&lt;br /&gt;
&lt;br /&gt;
   Print #1 , Chr(slaveid) ; Chr(84);                       'Messvorgang in cm starten&lt;br /&gt;
   Inputbin #2 , Hib , Lob                                  'Warte auf Ergebnis&lt;br /&gt;
   Srf02_entfernung = Makeint(lob , Hib)&lt;br /&gt;
End Function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[RN-Control]]&lt;br /&gt;
* [[Sensorarten]]&lt;br /&gt;
* [[Ultraschall SRF10 an RN-Control]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=357 Deutsche Anleitung zum SRF02]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Sensoren]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Distanzmessung_mit_SRF05_an_RN-MiniControl_und_RN-DIGI&amp;diff=14607</id>
		<title>Distanzmessung mit SRF05 an RN-MiniControl und RN-DIGI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Distanzmessung_mit_SRF05_an_RN-MiniControl_und_RN-DIGI&amp;diff=14607"/>
				<updated>2009-02-20T13:05:40Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Kategorien&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das nachfolgende Beispiel demonstriert eine Distanzmessung mit dem SRF05 an RN-MiniControl und den RN-DIGI LCD Anzeige.&lt;br /&gt;
&lt;br /&gt;
RN-Minicontrol misst in einer Endlosschleife die Entfernung, rechnet sie in cm um und zeigt sie auf der RN-DIGI Anzeige an.&lt;br /&gt;
&lt;br /&gt;
[[Bild:DistanzmessungSRF05RNMiniRNDigi2.jpg]]&lt;br /&gt;
[[Bild:DistanzmessungSRF05RNMiniRNDigi1.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'###################################################&lt;br /&gt;
'Entfernungsmessung&lt;br /&gt;
'###################################################&lt;br /&gt;
&lt;br /&gt;
'Die üblichen Definitionen bei Standardprogrammen auf Miniboard&lt;br /&gt;
$regfile = &amp;quot;m168def.dat&amp;quot;&lt;br /&gt;
$crystal = 16000000                                         'Quarzfrequenz&lt;br /&gt;
$baud = 9600&lt;br /&gt;
$hwstack = 32&lt;br /&gt;
$framesize = 32&lt;br /&gt;
$swstack = 32&lt;br /&gt;
&lt;br /&gt;
'************ SRF05 Sensor **************************&lt;br /&gt;
Dim Zeitmessung As Word&lt;br /&gt;
Dim Entfernung As Word&lt;br /&gt;
&lt;br /&gt;
'************ RN-Digi *******************************&lt;br /&gt;
Const Rn_digi_slave_write = &amp;amp;H76&lt;br /&gt;
Const Dezimalpunktziffer = 0                                'Segment wo Dezimalpunkt leuchten soll (0=keinen)&lt;br /&gt;
&lt;br /&gt;
Dim Segmente As Byte&lt;br /&gt;
Dim Z As Byte&lt;br /&gt;
Dim Switch As Byte&lt;br /&gt;
&lt;br /&gt;
Declare Sub Led_display_init()&lt;br /&gt;
Declare Sub Led_display(byval Ziffer As Byte , Byval Zahl As Byte)&lt;br /&gt;
Declare Sub Entfernungmessen()&lt;br /&gt;
Declare Sub Displaytest()&lt;br /&gt;
Declare Sub Entfernunganzeigen(byval Zahl As Word)&lt;br /&gt;
&lt;br /&gt;
Config Scl = Portc.5                                        'Ports fuer IIC-Bus&lt;br /&gt;
Config Sda = Portc.4&lt;br /&gt;
&lt;br /&gt;
' I2C-Init für RN-Digi&lt;br /&gt;
I2cinit&lt;br /&gt;
Led_display_init&lt;br /&gt;
Switch = 0&lt;br /&gt;
&lt;br /&gt;
' SRF05 Signal&lt;br /&gt;
Config Pind.2 = Output&lt;br /&gt;
&lt;br /&gt;
Displaytest&lt;br /&gt;
Wait 1&lt;br /&gt;
Displaytest&lt;br /&gt;
Wait 1&lt;br /&gt;
Displaytest&lt;br /&gt;
Wait 1&lt;br /&gt;
Displaytest&lt;br /&gt;
Wait 1&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
   Entfernungmessen&lt;br /&gt;
   Call Entfernunganzeigen(entfernung)&lt;br /&gt;
   Waitms 500&lt;br /&gt;
Loop&lt;br /&gt;
&lt;br /&gt;
Sub Entfernunganzeigen(byval Zahl As Word)&lt;br /&gt;
   Dim Einer As Byte&lt;br /&gt;
   Dim Zehner As Byte&lt;br /&gt;
   Dim Hunderter As Byte&lt;br /&gt;
   Dim Tausender As Byte&lt;br /&gt;
   Dim A As Word&lt;br /&gt;
&lt;br /&gt;
   A = Zahl&lt;br /&gt;
   einer = A mod 10&lt;br /&gt;
   A = A - einer&lt;br /&gt;
   A = A  / 10&lt;br /&gt;
   zehner = A mod 10&lt;br /&gt;
   A = A - zehner&lt;br /&gt;
   A = A / 10&lt;br /&gt;
   hunderter = A mod 10&lt;br /&gt;
   A = A - hunderter&lt;br /&gt;
   A = A / 10&lt;br /&gt;
   Tausender = A Mod 10&lt;br /&gt;
&lt;br /&gt;
   Print &amp;quot;Einer&amp;quot; ; Einer&lt;br /&gt;
   Print &amp;quot;zehner&amp;quot; ; Zehner&lt;br /&gt;
   Print &amp;quot;hunderter&amp;quot; ; Hunderter&lt;br /&gt;
   Print &amp;quot;Tausender&amp;quot; ; Tausender&lt;br /&gt;
   Print &amp;quot;**********************&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   Call Led_display(4 , Einer)&lt;br /&gt;
   Call Led_display(3 , Zehner)&lt;br /&gt;
   Call Led_display(2 , Hunderter)&lt;br /&gt;
   Call Led_display(1 , Tausender)&lt;br /&gt;
&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Sub Displaytest()&lt;br /&gt;
   For Z = 1 To 4&lt;br /&gt;
      Led_display Z , Switch&lt;br /&gt;
   Next Z&lt;br /&gt;
   Print &amp;quot;Test&amp;quot;&lt;br /&gt;
   If Switch = 0 Then&lt;br /&gt;
      Switch = 1&lt;br /&gt;
   Else&lt;br /&gt;
      Switch = 0&lt;br /&gt;
   End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Sub Entfernungmessen()&lt;br /&gt;
    Portd.2 = 0                                             'Port Low&lt;br /&gt;
    Pulseout Portd , 2 , 40                                 'Min. 10uS Impuls senden&lt;br /&gt;
    Pulsein Zeitmessung , Pind , 2 , 1&lt;br /&gt;
    Zeitmessung = Zeitmessung * 10                          'mal 10 da Pulsein in 10uS Einheiten Ergebnis ermittelt&lt;br /&gt;
    Entfernung = Zeitmessung / 58                           'Umrechnen in Zentimeter&lt;br /&gt;
    Print &amp;quot;Entfernung: &amp;quot; ; Entfernung ; &amp;quot; cm&amp;quot;&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Sub Led_display_init()&lt;br /&gt;
  I2cstart&lt;br /&gt;
  I2cwbyte Rn_digi_slave_write&lt;br /&gt;
  I2cwbyte 0                                                'Control Byte&lt;br /&gt;
&lt;br /&gt;
  'Dynamic Alternative Mode und Helligkeit&lt;br /&gt;
  'Die oberen 3 Bits bestimmen die Helligkeit&lt;br /&gt;
  'Wenn es dunkler sein soll dann z.b. &amp;amp;B0110111&lt;br /&gt;
  I2cwbyte &amp;amp;B1110111&lt;br /&gt;
&lt;br /&gt;
  I2cstop&lt;br /&gt;
&lt;br /&gt;
  'Alle Ziffern auf 0&lt;br /&gt;
  For Z = 1 To 4&lt;br /&gt;
       Led_display Z , 0&lt;br /&gt;
  Next Z&lt;br /&gt;
&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sub Led_display(ziffer As Byte , Zahl As Byte)&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Rn_digi_slave_write&lt;br /&gt;
     I2cwbyte Ziffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
     Select Case Zahl&lt;br /&gt;
         Case 0:&lt;br /&gt;
               Segmente = &amp;amp;H3F&lt;br /&gt;
         Case 1:&lt;br /&gt;
                Segmente = &amp;amp;H06&lt;br /&gt;
         Case 2:&lt;br /&gt;
                Segmente = &amp;amp;H5B&lt;br /&gt;
         Case 3:&lt;br /&gt;
                Segmente = &amp;amp;H4F&lt;br /&gt;
         Case 4:&lt;br /&gt;
                Segmente = &amp;amp;H66&lt;br /&gt;
         Case 5:&lt;br /&gt;
                Segmente = &amp;amp;H6D&lt;br /&gt;
         Case 6:&lt;br /&gt;
                Segmente = &amp;amp;H7D&lt;br /&gt;
         Case 7:&lt;br /&gt;
                Segmente = &amp;amp;H07&lt;br /&gt;
         Case 8:&lt;br /&gt;
                Segmente = &amp;amp;H7F&lt;br /&gt;
         Case 9:&lt;br /&gt;
                Segmente = &amp;amp;H67&lt;br /&gt;
         Case Else :&lt;br /&gt;
                Segmente = &amp;amp;H80                             'Ansonsten Dezimalpunkt&lt;br /&gt;
&lt;br /&gt;
     End Select&lt;br /&gt;
&lt;br /&gt;
     If Dezimalpunktziffer = Ziffer Then Segmente = Segmente Or &amp;amp;H80&lt;br /&gt;
     I2cwbyte Segmente&lt;br /&gt;
     I2cstop&lt;br /&gt;
End Sub&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Sensoren]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=AVR-Errata&amp;diff=14004</id>
		<title>AVR-Errata</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=AVR-Errata&amp;diff=14004"/>
				<updated>2008-09-20T09:55:22Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So wie alles und jedes auf der Welt sind auch [[AVR|AVR-Mikrocontroller]] nicht frei von Fehlern: sie haben ''Silicon Bugs'' bzw. ''Hard-Bugs'', also Fehler, die etwa durch den Herstellungsprozess oder mangelhaftes Chip-Design verursacht werden. Je nach Art des Fehlers (Erratum) gibt es verschiedene Möglichkeiten, ihn zu umschiffen, also einen ''Workaround'' zu finden. Das kann durch zusätzliche Hardware geschehen, indem man bestimmte Features nicht nutzt, oder indem ein Übersetzungsprogramm wie Compiler oder Assembler adäquaten Code erzeugt.&lt;br /&gt;
&lt;br /&gt;
Im folgenden ein Überblick über bekannte Errata der AVRs. Die Liste soll nur ein kurzer Überblick mit Beschreibung und Vorschlägen für Workarounds sein, den man bei Problemen überfliegen kann, um Hard-Bugs auszuschlie&amp;amp;szlig;en. Ob ein Erratum überhaupt auf eine spezielle AVR-Version oder  -Revision zutrifft sowie näheres dazu findet man in den Handbüchern.&lt;br /&gt;
&lt;br /&gt;
=Erratum: EEPROM Adresse 0 fehlerhaft=&lt;br /&gt;
;Beschreibung: [[EEPROM]]-Zelle an Adresse 0 funktioniert nicht fehlerfrei. Beim Zusammenbrechen der Spannung kann das EEPROM an Adresse 0 überschrieben werden.&lt;br /&gt;
;Behebung: Brownout aktivieren und/oder EEPROM-Adresse 0 nicht verwenden. Ob die Entwicklungsumgebung den Fehler umschifft &amp;amp;ndash; also keine Daten an diese Adresse lokatiert &amp;amp;ndash; findet man evtl. in der Dokumentation der Entwicklungsumgebung. Siehe auch [[avr-gcc#Sections|Workaround mit avr-gcc]].&lt;br /&gt;
&lt;br /&gt;
=Erratum: Interner 33pF wird nicht aktiviert=&lt;br /&gt;
;Beschreibung: Über [[AVR#Die Fusebits|Fuses]] kann bei Verwendung eines externen Low-Frequency-Quarzes (32kHz) ein interner [[Kondensator]] von 32pF aktiviert werden, um ein Bauteil einzusparen. Den C kann man auch zusammen mit einem externen R als RC-Glied zur Takterzeugung verwenden. Der Kondensator wird jedoch nicht aktiviert.&lt;br /&gt;
;Behebung: Verwendung eines externen 32pF Kondensators.&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13977</id>
		<title>Bascom und 1-Wire</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13977"/>
				<updated>2008-09-07T19:45:12Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Zeile war verschluckt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele, in denen gezeigt wird wie Bascom über den 1-Wire-Bus kommuniziert.&lt;br /&gt;
&lt;br /&gt;
1-Wire (Eindraht) ist eine serielle Schnittstelle, die mit nur einer Datenleitung auskommt, die gleichzeitig auch noch als Stromversorgung genutzt werden kann.&lt;br /&gt;
Aufgrund der Einfachheit kann diese Schnittstelle leicht in Software auf einem Mikrocontroller nachgebildet werden.&lt;br /&gt;
&lt;br /&gt;
In Bascom sind [[Bascom#1WIRE_Bus|Befehle]] für die 1-Wire-Kommunikation enthalten, sodass der Programmierer sich nicht um das Protokoll und das Timing der Übertragung kümmern muss.&lt;br /&gt;
&lt;br /&gt;
Es gibt 1-Wire-Geräte mit verschiedenen Funktionen, in der Roboterwelt dürfte einer der bekanntesten der Temperatursensor DS18S20 (bzw. DS18B20) sein, deswegen wird dieser in den Beipielen verwendet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Die Beschaltung rund um den DS18B20 sieht so aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ablauf der Kommunikation ==&lt;br /&gt;
&lt;br /&gt;
Die Kommunikation mit dem 1-Wire-Gerät muss immer diesen Ablauf haben:&lt;br /&gt;
&lt;br /&gt;
* Initialisierung&lt;br /&gt;
* &amp;quot;ROM Function&amp;quot; Befehl&lt;br /&gt;
* &amp;quot;Memory Function&amp;quot; Befehl&lt;br /&gt;
* Übertragung/Daten&lt;br /&gt;
&lt;br /&gt;
Aus diesem Ablauf ergeben sich die beiden folgenden Programmabläufe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit nur einem Gerät ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich nur ein einziges Gerät am Bus befindet kann man diese kurze Version der Kommunikation verwenden. Ein ROM-Befehl ist dabei nicht notwendig und kann übersprungen werden, dies muss aber dem Gerät mitgeteilt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 {{vbcomment|Minimalprogramm für Temperaturmessung}}&lt;br /&gt;
 Config 1wire = Portc.7 &lt;br /&gt;
 &lt;br /&gt;
 Dim Sp(9) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;H44                                    {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                      {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;HBE                                    {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
 Sp(1) = 1wread(9)                               {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Sp() stehen die Daten des Gerätes die dann Anhand des Datenblattes ausgewertet werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit mehreren Geräten ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich mehrere Geräte am 1-Wire-Bus befinden, müssen diese jeweils Adressiert werden um mit dem gewünschten Gerät in Kontakt zu treten. Zum Adressieren wird die Seriennummer verwendet, die in jedem 1-Wire-Gerät eindeutig vorhanden ist. Um an diese Seriennummer zu kommen gibt es zwei Strategien.&lt;br /&gt;
&lt;br /&gt;
Entweder man liest bei allen Geräten vorher einzeln diese Nr. aus, um diese in das eigentliche Programm einzutragen (kürzer), oder man sucht beim Programmstart jedesmal nach vorhandenen Ger&amp;amp;auml;ten (flexibler).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr einzeln auslesen ===&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 1wwrite &amp;amp;H33                                        {{vbcomment|ROM-Befehl zum lesen der SerienNr}}&lt;br /&gt;
 Ar(1) = 1wread(8)                                   {{vbcomment|8 Bytes lesen}}&lt;br /&gt;
 &lt;br /&gt;
 For I = 1 To 8&lt;br /&gt;
     Print Hex(ar(i));                               {{vbcomment|Ausgeben}}&lt;br /&gt;
     Print &amp;quot; &amp;quot;;&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Ar() befindet sich somit die SerienNr des Gerätes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr aller Geräte ===&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 38400&lt;br /&gt;
 &lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                   {{vbcomment|Array für SerienNr.}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 Dim W As Word&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.7 , 400 , 450                           {{vbcomment|BEEP bei RN-Control}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;1-Wire&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Ar(1) = 1wsearchfirst()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|gibts überhaupt ein Ger&amp;amp;auml;t}}&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Ausgabe der SerienNr.}}&lt;br /&gt;
         For I = 1 To 8&lt;br /&gt;
             Print Hex(ar(i));&lt;br /&gt;
             Print &amp;quot; &amp;quot;;&lt;br /&gt;
         Next&lt;br /&gt;
         Print&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Nach weiterem Ger&amp;amp;auml;t suchen}}&lt;br /&gt;
         Ar(1) = 1wsearchnext()&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Err = 1                       {{vbcomment|solange bis sich kein weiteres Ger&amp;amp;auml;t mehr meldet.}}&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Fertig&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 W = 1wirecount()                                {{vbcomment|Anzahl der gefundenen Ger&amp;amp;auml;te z&amp;amp;auml;hlen}}&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Anzahl &amp;quot;;&lt;br /&gt;
 Print W&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Am ersten Byte der SerienNr (Family-Code) ist zu erkennen um welches Ger&amp;amp;auml;t es sich handelt, beim DS18B20 ist es die &amp;amp;amp;H28, beim DS18S20 die &amp;amp;amp;H10. Da beide unterschiedliche Formate beim Temperaturwert haben, kann die Berechnung anhand des Family-Code angepasst werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bestimmtes Gerät ansprechen ===&lt;br /&gt;
&lt;br /&gt;
Um bei mehreren vorhandenen Ger&amp;amp;auml;ten ein bestimmtes anzusprechen muss es mit der SerienNr adressiert werden.&lt;br /&gt;
&lt;br /&gt;
 Do&lt;br /&gt;
     1wverify Ar(1)                                 {{vbcomment|Ger&amp;amp;auml;t mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
     {{vbcomment|Gerät vorhanden}}&lt;br /&gt;
     If Err = 0 Then&lt;br /&gt;
 &lt;br /&gt;
         1wwrite &amp;amp;H44                               {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
         Waitms 500                                 {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
         1wverify Ar(1)                             {{vbcomment|Ger&amp;amp;auml;t mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
         1wwrite &amp;amp;HBE                               {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
         Sp(1) = 1wread(9)                          {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
         For I = 1 To 9&lt;br /&gt;
             Print Hex(sp(i));&lt;br /&gt;
         Next&lt;br /&gt;
         Print&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Nur für die Temperatur wichtige Daten ausgeben}}&lt;br /&gt;
         Print Hex(sp(2));&lt;br /&gt;
         Print Hex(sp(1))&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
&lt;br /&gt;
Die SerienNr. des gew&amp;amp;uuml;nschten Ger&amp;amp;auml;tes muss im Array Ar() stehen, bevor es mit &amp;lt;tt&amp;gt;1wverify&amp;lt;/tt&amp;gt; gesucht wird, dies ist auch gleichzeitig der ROM-Befehl, diesem kann der Memory-Befehl folgen, und anschlie&amp;amp;szlig;end die Daten übertragen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prüfsumme ==&lt;br /&gt;
&lt;br /&gt;
Da wegen der einen Datenleitung durchaus mit St&amp;amp;ouml;rungen zu rechnen ist, wird jeder &amp;amp;Uuml;bertragung ein Pr&amp;amp;uuml;fbyte angehängt, mit dem sich die Korrektheit der Daten überpr&amp;amp;uuml;fen lässt.&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                   {{vbcomment|Array für SerienNr}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
     1wwrite &amp;amp;H33                                    {{vbcomment|ROM-Befehl zum lesen der SerienNr.}}&lt;br /&gt;
     Ar(1) = 1wread(8)                               {{vbcomment|8 Bytes lesen}}&lt;br /&gt;
 &lt;br /&gt;
     For I = 1 To 8&lt;br /&gt;
         Print Hex(ar(i));                           {{vbcomment|Ausgabe der SerienNr.}}&lt;br /&gt;
         Print &amp;quot; &amp;quot;;&lt;br /&gt;
     Next&lt;br /&gt;
     Print&lt;br /&gt;
 &lt;br /&gt;
     Print Hex(crc8(ar(1) , 7) )                     {{vbcomment|Pr&amp;amp;uuml;fsumme ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
     If Ar(8) = Crc8(ar(1) , 7) Then                 {{vbcomment|Pr&amp;amp;uuml;fsumme vergleichen}}&lt;br /&gt;
         Print &amp;quot;Daten OK&amp;quot;&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
&lt;br /&gt;
Wenn das letzte Byte der Übertragung und die berechnete Pr&amp;amp;uuml;fsumme aus den Bytes 1-7 übereinstimmt, war die &amp;amp;Uuml;bertragung erfolgreich, und die Daten k&amp;amp;ouml;nnen weiterverarbeitet werden.&lt;br /&gt;
Beim auslesen der Temperatur werden 9 Bytes &amp;amp;uuml;bertragen, deshalb m&amp;amp;uuml;ssen zum berechnen der Pr&amp;amp;uuml;fsumme Byte 1-8 einbezogen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parasitäre Stromversorgung ==&lt;br /&gt;
&lt;br /&gt;
Da bei der Schaltung von oben eigentlich drei Leitungen ben&amp;amp;ouml;tigt werden, statt der einen wie man vermuten k&amp;amp;ouml;nnte, ist es mit der folgenden Schaltung immerhin m&amp;amp;ouml;glich die Anzahl auf zwei Leitungen zu reduzieren.&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820_parasit.png]]&lt;br /&gt;
&lt;br /&gt;
Es ist aber Abh&amp;amp;auml;ngig vom Ger&amp;amp;auml;t und den Umgebungsbedingungen ob es sich immer so l&amp;amp;ouml;sen l&amp;amp;auml;sst. Ein Blick ins Datenblatt hilft da weiter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[Bascom#1WIRE_Bus|1-Wire Bascom-Befehle]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.maxim-ic.com/quick_view2.cfm?qv_pk=2812] - Datenblatt zu DS18B20&lt;br /&gt;
* [http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2815] - Datenblatt zu DS18S20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 03:16, 23. Aug 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13966</id>
		<title>Bascom und 1-Wire</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13966"/>
				<updated>2008-09-06T10:12:16Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: DB Link und ID des 18S20&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele, in denen gezeigt wird wie Bascom über den 1-Wire-Bus kommuniziert.&lt;br /&gt;
&lt;br /&gt;
1-Wire (Eindraht) ist eine serielle Schnittstelle, die mit nur einer Datenleitung auskommt, die gleichzeitig auch noch als Stromversorgung genutzt werden kann.&lt;br /&gt;
Aufgrund der Einfachheit kann diese Schnittstelle leicht in Software auf einem Mikrocontroller nachgebildet werden.&lt;br /&gt;
&lt;br /&gt;
In Bascom sind [[Bascom#1WIRE_Bus|Befehle]] für die 1-Wire-Kommunikation enthalten, sodass der Programmierer sich nicht um das Protokoll und das Timing der Übertragung kümmern muss.&lt;br /&gt;
&lt;br /&gt;
Es gibt 1-Wire-Geräte mit verschiedenen Funktionen, in der Roboterwelt dürfte einer der bekanntesten der Temperatursensor DS18S20 (bzw. DS18B20) sein, deswegen wird dieser in den Beipielen verwendet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Die Beschaltung rund um den DS18B20 sieht so aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ablauf der Kommunikation ==&lt;br /&gt;
&lt;br /&gt;
Die Kommunikation mit dem 1-Wire-Gerät muss immer diesen Ablauf haben:&lt;br /&gt;
&lt;br /&gt;
* Initialisierung&lt;br /&gt;
* &amp;quot;ROM Function&amp;quot; Befehl&lt;br /&gt;
* &amp;quot;Memory Function&amp;quot; Befehl&lt;br /&gt;
* Übertragung/Daten&lt;br /&gt;
&lt;br /&gt;
Aus diesem Ablauf ergeben sich die beiden folgenden Programmabläufe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit nur einem Gerät ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich nur ein einziges Gerät am Bus befindet kann man diese kurze Version der Kommunikation verwenden. Ein ROM-Befehl ist dabei nicht notwendig und kann übersprungen werden, dies muss aber dem Gerät mitgeteilt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 {{vbcomment|Minimalprogramm für Temperaturmessung}}&lt;br /&gt;
 Config 1wire = Portc.7 &lt;br /&gt;
 &lt;br /&gt;
 Dim Sp(9) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;H44                                    {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                      {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;HBE                                    {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
 Sp(1) = 1wread(9)                               {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Sp() stehen die Daten des Gerätes die dann Anhand des Datenblattes ausgewertet werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit mehreren Geräten ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich mehrere Geräte am 1-Wire-Bus befinden, müssen diese jeweils Adressiert werden um mit dem gewünschten Gerät in Kontakt zu treten. Zum Adressieren wird die Seriennummer verwendet, die in jedem 1-Wire-Gerät eindeutig vorhanden ist. Um an diese Seriennummer zu kommen gibt es zwei Strategien.&lt;br /&gt;
&lt;br /&gt;
Entweder man liest bei allen Geräten vorher einzeln diese Nr. aus, um diese in das eigentliche Programm einzutragen (kürzer), oder man sucht beim Programmstart jedesmal nach vorhandenen Ger&amp;amp;auml;ten (flexibler).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr einzeln auslesen ===&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 1wwrite &amp;amp;H33                                            {{vbcomment|ROM-Befehl zum lesen der SerienNr}}&lt;br /&gt;
 Ar(1) = 1wread(8)                                       {{vbcomment|8 Bytes lesen}}&lt;br /&gt;
 &lt;br /&gt;
 For I = 1 To 8&lt;br /&gt;
     Print Hex(ar(i));                                   {{vbcomment|Ausgeben}}&lt;br /&gt;
     Print &amp;quot; &amp;quot;;&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Ar() befindet sich somit die SerienNr des Gerätes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr aller Geräte ===&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 38400&lt;br /&gt;
 &lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                           {{vbcomment|Array für SerienNr.}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 Dim W As Word&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.7 , 400 , 450                                   {{vbcomment|BEEP bei RN-Control}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;1-Wire&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Ar(1) = 1wsearchfirst()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|gibts überhaupt ein Gerät}}&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Ausgabe der SerienNr.}}&lt;br /&gt;
         For I = 1 To 8&lt;br /&gt;
             Print Hex(ar(i));&lt;br /&gt;
             Print &amp;quot; &amp;quot;;&lt;br /&gt;
         Next&lt;br /&gt;
         Print&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Nach weiteren Geräte suchen}}&lt;br /&gt;
         Ar(1) = 1wsearchnext()&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Err = 1                       {{vbcomment|solange bis sich kein weiteres Ger&amp;amp;auml;t mehr meldet.}}&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Fertig&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 W = 1wirecount()                                {{vbcomment|Anzahl der gefundenen Ger&amp;amp;auml;te z&amp;amp;auml;hlen}}&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Anzahl &amp;quot;;&lt;br /&gt;
 Print W&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Am ersten Byte der SerienNr (Family-Code) ist zu erkennen um welches Gerät es sich handelt, beim DS18B20 ist es die &amp;amp;amp;H28, beim DS18S20 die &amp;amp;amp;H10. Da beide unterschiedliche Formate beim Temperaturwert haben, kann die Berechnung anhand des Family-Code angepasst werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bestimmtes Gerät ansprechen ===&lt;br /&gt;
&lt;br /&gt;
Um bei mehreren vorhandenen Geräten ein bestimmtes anzusprechen muss es mit der SerienNr adressiert werden.&lt;br /&gt;
&lt;br /&gt;
 Do&lt;br /&gt;
     1wverify Ar(1)                                     {{vbcomment|Gerät mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
     {{vbcomment|Gerät vorhanden}}&lt;br /&gt;
     If Err = 0 Then&lt;br /&gt;
 &lt;br /&gt;
         1wwrite &amp;amp;H44                                   {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
         Waitms 500                                     {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
         1wverify Ar(1)                                 {{vbcomment|Gerät mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
         1wwrite &amp;amp;HBE                                   {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
         Sp(1) = 1wread(9)                              {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
         For I = 1 To 9&lt;br /&gt;
             Print Hex(sp(i));&lt;br /&gt;
         Next&lt;br /&gt;
         Print&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Nur für die Temperatur wichtige Daten ausgeben}}&lt;br /&gt;
         Print Hex(sp(2));&lt;br /&gt;
         Print Hex(sp(1))&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
&lt;br /&gt;
Die SerienNr. des gewünschten Gerätes muss im Array Ar() stehen, bevor es mit &amp;lt;tt&amp;gt;1wverify&amp;lt;/tt&amp;gt; gesucht wird, dies ist auch gleichzeitig der ROM-Befehl, diesem kann der Memory-Befehl folgen, und anschließend die Daten übertragen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prüfsumme ==&lt;br /&gt;
&lt;br /&gt;
Da wegen der einen Datenleitung durchaus mit Störungen zu rechnen ist, wird jeder Übertragung ein Prüfbyte angehängt, mit dem sich die Korrektheit der Daten überprüfen lässt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                           {{vbcomment|Array für SerienNr}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
     1wwrite &amp;amp;H33                                            {{vbcomment|ROM-Befehl zum lesen der SerienNr.}}&lt;br /&gt;
     For I = 1 To 8&lt;br /&gt;
         Print Hex(ar(i));                                   {{vbcomment|Ausgabe der SerienNr.}}&lt;br /&gt;
         Print &amp;quot; &amp;quot;;&lt;br /&gt;
     Next&lt;br /&gt;
     Print&lt;br /&gt;
 &lt;br /&gt;
     Print Hex(crc8(ar(1) , 7) )                             {{vbcomment|Prüfsumme ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
     If Ar(8) = Crc8(ar(1) , 7) Then                         {{vbcomment|Prüfsumme vergleichen}}&lt;br /&gt;
         Print &amp;quot;Daten OK&amp;quot;&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
&lt;br /&gt;
Wenn das letzte Byte der Übertragung und die berechnete Prüfsumme aus den Bytes 1-7 übereinstimmt, war die Übertragung erfolgreich, und die Daten können weiterverarbeitet werden.&lt;br /&gt;
Beim auslesen der Temperatur werden 9 Bytes übertragen, deshalb müssen zum berechnen der Prüfsumme Byte 1-8 einbezogen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parasitäre Stromversorgung ==&lt;br /&gt;
&lt;br /&gt;
Da bei der Schaltung von oben eigentlich drei Leitungen benötigt werden, statt der einen wie man vermuten könnte, ist es mit der folgenden Schaltung immerhin möglich die Anzahl auf zwei Leitungen zu reduzieren.&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820_parasit.png]]&lt;br /&gt;
&lt;br /&gt;
Es ist aber Abhängig vom Gerät und den Umgebungsbedingungen ob es sich immer so lösen lässt. Ein Blick ins Datenblatt hilft da weiter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[Bascom#1WIRE_Bus|1-Wire Bascom-Befehle]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.maxim-ic.com/quick_view2.cfm?qv_pk=2812] - Datenblatt zu DS18B20&lt;br /&gt;
* [http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2815] - Datenblatt zu DS18S20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 03:16, 23. Aug 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=13927</id>
		<title>Benutzer:Linux 80</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=13927"/>
				<updated>2008-08-23T12:08:53Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Seit Mai 2005 ASURO-Besitzer, und AVR-Forscher ;-)&lt;br /&gt;
&lt;br /&gt;
Will von den [[AVR]]s so viele Details wissen wie früher vom 6502 !&lt;br /&gt;
&lt;br /&gt;
Näheres auf der RN-Nickpage.&lt;br /&gt;
&lt;br /&gt;
Forschutensilien inzwischen ausgebaut um:&lt;br /&gt;
*[[RN-Control]] 2 Stück, siehe [[Verlosung]]&lt;br /&gt;
*[[RN-Mega8]]&lt;br /&gt;
*[[RN-MiniControl]]&lt;br /&gt;
*[http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=152 RN-LCD-Adapter]&lt;br /&gt;
*TextLCD mit 16*2 Zeichen&lt;br /&gt;
*TextLCD mit 20*4 Zeichen [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=80 EA-Dip204]&lt;br /&gt;
*GrafikLCD 128*64 mit KS0108 ([http://www.pollin.de/shop/downloads/D120423D.PDF Pollin 120423])&lt;br /&gt;
*GrafikLCD 128*64 mit SED1565 ([http://www.pollin.de/shop/downloads/D120292D.RAR Pollin 120292]) &amp;lt;small&amp;gt;(das hat aber sich aber aufgelöst, und eine Art Lochfrass in der Scheibe, sieht aus als wenn immer Pixel gesetzt sind, obwohl keine Power auf dem LCD, vom Prinzip her funktionierts aber noch)&amp;lt;/small&amp;gt;&lt;br /&gt;
*und weitere AT-Megas und -Tinys&lt;br /&gt;
*Schachtelweise elektronisches kleinzeugs, das gelegentlich ausprobiert werden muss&lt;br /&gt;
&lt;br /&gt;
Seit Dezember 2005 im besitz eines Renesas R8C/13 Controllers (samt selbstgebautem Applicationboard), der durch eine bekannte Zeitschrift unters Volk gebracht wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wikibeteiligungen ==&lt;br /&gt;
&lt;br /&gt;
*[[TWI]] - 6. Jan 2006, 00:52&lt;br /&gt;
*[[Atmel Controller Mega8515]] - 8. Jan 2006, 03:08&lt;br /&gt;
*[[TWI Praxis]] - 15. Jan 2006, 15:31&lt;br /&gt;
*[[USI (Avr)]] - 18. Nov 2006, 19:19&lt;br /&gt;
*[[Bascom und USI-Kommunikation]] - 26. Nov 2006, 02:11&lt;br /&gt;
*[[HEX-Datei]] - 27. Aug 2007, 03:05&lt;br /&gt;
*[[Bascom I2C Master]] - 28. Okt 2007, 02:08&lt;br /&gt;
*[[Bascom und 1-Wire]] - 23. Aug 2008, 03:16&lt;br /&gt;
&lt;br /&gt;
*[[Spezial:Contributions/Linux_80]] - Der Rest&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/nickpage.php?user=linux_80 Linux_80] - RN-Nickpage&lt;br /&gt;
*http://roboter.net-con.net/asuro/ - Homepage&lt;br /&gt;
&amp;lt;!-- *http://www.elektor.de/ - Zeitschrift elektor --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=13926</id>
		<title>Benutzer:Linux 80</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=13926"/>
				<updated>2008-08-23T11:43:16Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Wikibeteiligungen dazu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Seit Mai 2005 ASURO-Besitzer, und AVR-Forscher ;-)&lt;br /&gt;
&lt;br /&gt;
Will von den [[AVR]]s so viele Details wissen wie früher vom 6502 !&lt;br /&gt;
&lt;br /&gt;
Näheres auf der RN-Nickpage.&lt;br /&gt;
&lt;br /&gt;
Forschutensilien inzwischen ausgebaut um:&lt;br /&gt;
*[[RN-Control]] 2 Stück, siehe [[Verlosung]]&lt;br /&gt;
*[[RN-Mega8]]&lt;br /&gt;
*[[RN-MiniControl]]&lt;br /&gt;
*[http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=152 RN-LCD-Adapter]&lt;br /&gt;
*TextLCD mit 16*2 Zeichen&lt;br /&gt;
*TextLCD mit 20*4 Zeichen [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=80 EA-Dip204]&lt;br /&gt;
*GrafikLCD 128*64 mit KS0108 ([http://www.pollin.de/shop/downloads/D120423D.PDF Pollin 120423])&lt;br /&gt;
*GrafikLCD 128*64 mit SED1565 ([http://www.pollin.de/shop/downloads/D120292D.RAR Pollin 120292]) &amp;lt;small&amp;gt;(das hat aber sich aber aufgelöst, und eine Art Lochfrass in der Scheibe, sieht aus als wenn immer Pixel gesetzt sind, obwohl keine Power auf dem LCD, vom Prinzip her funktionierts aber noch)&amp;lt;/small&amp;gt;&lt;br /&gt;
*und weitere AT-Megas und -Tinys&lt;br /&gt;
*Schachtelweise elektronisches kleinzeugs, das gelegentlich ausprobiert werden muss&lt;br /&gt;
&lt;br /&gt;
Seit Dezember 2005 im besitz eines Renesas R8C/13 Controllers (samt selbstgebautem Applicationboard), der durch eine bekannte Zeitschrift unters Volk gebracht wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Wikibeteiligungen ==&lt;br /&gt;
&lt;br /&gt;
*[[TWI]] - 6. Jan 2006, 00:52&lt;br /&gt;
*[[Atmel Controller Mega8515]] - 8. Jan 2006, 03:08&lt;br /&gt;
*[[TWI Praxis]] - 15. Jan 2006, 15:31&lt;br /&gt;
*[[USI (Avr)]] - 18. Nov 2006, 19:19&lt;br /&gt;
*[[Bascom und USI-Kommunikation]] - 26. Nov 2006, 02:11&lt;br /&gt;
*[[HEX-Datei]] - 27. Aug 2007, 03:05&lt;br /&gt;
*[[Bascom I2C Master]] - 28. Okt 2007, 02:08&lt;br /&gt;
*[[Bascom und 1-Wire]] - 23. Aug 2008, 03:16&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/nickpage.php?user=linux_80 Linux_80] - RN-Nickpage&lt;br /&gt;
*http://roboter.net-con.net/asuro/ - Homepage&lt;br /&gt;
&amp;lt;!-- *http://www.elektor.de/ - Zeitschrift elektor --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13923</id>
		<title>Bascom und 1-Wire</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_1-Wire&amp;diff=13923"/>
				<updated>2008-08-23T01:16:33Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Neu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele, in denen gezeigt wird wie Bascom über den 1-Wire-Bus kommuniziert.&lt;br /&gt;
&lt;br /&gt;
1-Wire (Eindraht) ist eine serielle Schnittstelle, die mit nur einer Datenleitung auskommt, die gleichzeitig auch noch als Stromversorgung genutzt werden kann.&lt;br /&gt;
Aufgrund der Einfachheit kann diese Schnittstelle leicht in Software auf einem Mikrocontroller nachgebildet werden.&lt;br /&gt;
&lt;br /&gt;
In Bascom sind [[Bascom#1WIRE_Bus|Befehle]] für die 1-Wire-Kommunikation enthalten, sodass der Programmierer sich nicht um das Protokoll und das Timing der Übertragung kümmern muss.&lt;br /&gt;
&lt;br /&gt;
Es gibt 1-Wire-Geräte mit verschiedenen Funktionen, in der Roboterwelt dürfte einer der bekanntesten der Temperatursensor DS18S20 (bzw. DS18B20) sein, deswegen wird dieser in den Beipielen verwendet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Die Beschaltung rund um den DS18B20 sieht so aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ablauf der Kommunikation ==&lt;br /&gt;
&lt;br /&gt;
Die Kommunikation mit dem 1-Wire-Gerät muss immer diesen Ablauf haben:&lt;br /&gt;
&lt;br /&gt;
* Initialisierung&lt;br /&gt;
* &amp;quot;ROM Function&amp;quot; Befehl&lt;br /&gt;
* &amp;quot;Memory Function&amp;quot; Befehl&lt;br /&gt;
* Übertragung/Daten&lt;br /&gt;
&lt;br /&gt;
Aus diesem Ablauf ergeben sich die beiden folgenden Programmabläufe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit nur einem Gerät ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich nur ein einziges Gerät am Bus befindet kann man diese kurze Version der Kommunikation verwenden. Ein ROM-Befehl ist dabei nicht notwendig und kann übersprungen werden, dies muss aber dem Gerät mitgeteilt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 {{vbcomment|Minimalprogramm für Temperaturmessung}}&lt;br /&gt;
 Config 1wire = Portc.7 &lt;br /&gt;
 &lt;br /&gt;
 Dim Sp(9) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;H44                                    {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                      {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
 1wreset                                         {{vbcomment|Initialisierung}}&lt;br /&gt;
 1wwrite &amp;amp;HCC                                    {{vbcomment|überspringe ROM-Befehl}}&lt;br /&gt;
 1wwrite &amp;amp;HBE                                    {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
 Sp(1) = 1wread(9)                               {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Sp() stehen die Daten des Gerätes die dann Anhand des Datenblattes ausgewertet werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit mehreren Geräten ==&lt;br /&gt;
&lt;br /&gt;
Wenn sich mehrere Geräte am 1-Wire-Bus befinden, müssen diese jeweils Adressiert werden um mit dem gewünschten Gerät in Kontakt zu treten. Zum Adressieren wird die Seriennummer verwendet, die in jedem 1-Wire-Gerät eindeutig vorhanden ist. Um an diese Seriennummer zu kommen gibt es zwei Strategien.&lt;br /&gt;
&lt;br /&gt;
Entweder man liest bei allen Geräten vorher einzeln diese Nr. aus, um diese in das eigentliche Programm einzutragen (kürzer), oder man sucht beim Programmstart jedesmal nach vorhandenen Geräten (flexibler).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr einzeln auslesen ===&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 1wwrite &amp;amp;H33                                            {{vbcomment|ROM-Befehl zum lesen der SerienNr}}&lt;br /&gt;
 Ar(1) = 1wread(8)                                       {{vbcomment|8 Bytes lesen}}&lt;br /&gt;
 &lt;br /&gt;
 For I = 1 To 8&lt;br /&gt;
     Print Hex(ar(i));                                   {{vbcomment|Ausgeben}}&lt;br /&gt;
     Print &amp;quot; &amp;quot;;&lt;br /&gt;
 Next&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
&lt;br /&gt;
Im Array Ar() befindet sich somit die SerienNr des Gerätes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== SerienNr aller Geräte ===&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 38400&lt;br /&gt;
 &lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                           {{vbcomment|Array für SerienNr.}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 Dim W As Word&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.7 , 400 , 450                                   {{vbcomment|BEEP bei RN-Control}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;1-Wire&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Ar(1) = 1wsearchfirst()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|gibts überhaupt ein Gerät}}&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
     For I = 1 To 8&lt;br /&gt;
         Print Hex(ar(i));                                   {{vbcomment|Ausgabe der ersten SerienNr.}}&lt;br /&gt;
         Print &amp;quot; &amp;quot;;&lt;br /&gt;
     Next&lt;br /&gt;
     Print&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Nach weiteren Geräte suchen}}&lt;br /&gt;
         Ar(1) = 1wsearchnext()&lt;br /&gt;
         {{vbcomment|war noch ein weiteres Gerät da}}&lt;br /&gt;
         If Err = 0 Then&lt;br /&gt;
             For I = 1 To 8&lt;br /&gt;
                 Print Hex(ar(i));                           {{vbcomment|Ausgabe der letzten SerienNr.}}&lt;br /&gt;
                 Print &amp;quot; &amp;quot;;&lt;br /&gt;
             Next&lt;br /&gt;
             Print&lt;br /&gt;
 &lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Err = 1                          {{vbcomment|solange bis sich kein weiteres Gerät mehr meldet.}}&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Fertig&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 W = 1wirecount()                                {{vbcomment|Anzahl der gefundenen Geräte zählen}}&lt;br /&gt;
 &lt;br /&gt;
 Print &amp;quot;Anzahl &amp;quot;;&lt;br /&gt;
 Print W&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Am ersten Byte der SerienNr ist zu erkennen um welches Gerät es sich handelt, beim DS18B20 ist es die &amp;amp;amp;H28.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bestimmtes Gerät ansprechen ===&lt;br /&gt;
&lt;br /&gt;
Um bei mehreren vorhandenen Geräten ein bestimmtes anzusprechen muss es mit der SerienNr adressiert werden.&lt;br /&gt;
&lt;br /&gt;
 Do&lt;br /&gt;
     1wverify Ar(1)                                     {{vbcomment|Gerät mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
     {{vbcomment|Gerät vorhanden}}&lt;br /&gt;
     If Err = 0 Then&lt;br /&gt;
 &lt;br /&gt;
         1wwrite &amp;amp;H44                                   {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
 &lt;br /&gt;
         Waitms 500                                     {{vbcomment|warten bis Messung fertig}}&lt;br /&gt;
 &lt;br /&gt;
         1wverify Ar(1)                                 {{vbcomment|Gerät mit der SerienNr. aus Ar() auswählen}}&lt;br /&gt;
         1wwrite &amp;amp;HBE                                   {{vbcomment|Temperatur auslesen}}&lt;br /&gt;
         Sp(1) = 1wread(9)                              {{vbcomment|Daten in ein Array lesen}}&lt;br /&gt;
 &lt;br /&gt;
         For I = 1 To 9&lt;br /&gt;
             Print Hex(sp(i));&lt;br /&gt;
         Next&lt;br /&gt;
         Print&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Nur für die Temperatur wichtige Daten ausgeben}}&lt;br /&gt;
         Print Hex(sp(2));&lt;br /&gt;
         Print Hex(sp(1))&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 1&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
&lt;br /&gt;
Die SerienNr. des gewünschten Gerätes muss im Array Ar() stehen, bevor es mit &amp;lt;tt&amp;gt;1wverify&amp;lt;/tt&amp;gt; gesucht wird, dies ist auch gleichzeitig der ROM-Befehl, diesem kann der Memory-Befehl folgen, und anschließend die Daten übertragen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Prüfsumme ==&lt;br /&gt;
&lt;br /&gt;
Da wegen der einen Datenleitung durchaus mit Störungen zu rechnen ist, wird jeder Übertragung ein Prüfbyte angehängt, mit dem sich die Korrektheit der Daten überprüfen lässt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 Config 1wire = Portc.7&lt;br /&gt;
 &lt;br /&gt;
 Dim Ar(8) As Byte                                           {{vbcomment|Array für SerienNr}}&lt;br /&gt;
 Dim I As Byte&lt;br /&gt;
 &lt;br /&gt;
 1wreset&lt;br /&gt;
 If Err = 0 Then&lt;br /&gt;
     1wwrite &amp;amp;H33                                            {{vbcomment|ROM-Befehl zum lesen der SerienNr.}}&lt;br /&gt;
     For I = 1 To 8&lt;br /&gt;
         Print Hex(ar(i));                                   {{vbcomment|Ausgabe der SerienNr.}}&lt;br /&gt;
         Print &amp;quot; &amp;quot;;&lt;br /&gt;
     Next&lt;br /&gt;
     Print&lt;br /&gt;
 &lt;br /&gt;
     Print Hex(crc8(ar(1) , 7) )                             {{vbcomment|Prüfsumme ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
     If Ar(8) = Crc8(ar(1) , 7) Then                         {{vbcomment|Prüfsumme vergleichen}}&lt;br /&gt;
         Print &amp;quot;Daten OK&amp;quot;&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End If&lt;br /&gt;
&lt;br /&gt;
Wenn das letzte Byte der Übertragung und die berechnete Prüfsumme aus den Bytes 1-7 übereinstimmt, war die Übertragung erfolgreich, und die Daten können weiterverarbeitet werden.&lt;br /&gt;
Beim auslesen der Temperatur werden 9 Bytes übertragen, deshalb müssen zum berechnen der Prüfsumme Byte 1-8 einbezogen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parasitäre Stromversorgung ==&lt;br /&gt;
&lt;br /&gt;
Da bei der Schaltung von oben eigentlich drei Leitungen benötigt werden, statt der einen wie man vermuten könnte, ist es mit der folgenden Schaltung immerhin möglich die Anzahl auf zwei Leitungen zu reduzieren.&lt;br /&gt;
&lt;br /&gt;
[[Bild:1Wire-DS1820_parasit.png]]&lt;br /&gt;
&lt;br /&gt;
Es ist aber Abhängig vom Gerät und den Umgebungsbedingungen ob es sich immer so lösen lässt. Ein Blick ins Datenblatt hilft da weiter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Bascom]]&lt;br /&gt;
* [[Bascom#1WIRE_Bus|1-Wire Bascom-Befehle]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.maxim-ic.com/quick_view2.cfm?qv_pk=2812] - Datenblatt zu DS18B20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 03:16, 23. Aug 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:1Wire-DS1820_parasit.png&amp;diff=13922</id>
		<title>Datei:1Wire-DS1820 parasit.png</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:1Wire-DS1820_parasit.png&amp;diff=13922"/>
				<updated>2008-08-22T22:32:15Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Schaltplan für 1-Wire mit DS18B20, parasitäre Stromversorgung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltplan für 1-Wire mit DS18B20, parasitäre Stromversorgung&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:1Wire-DS1820.png&amp;diff=13921</id>
		<title>Datei:1Wire-DS1820.png</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:1Wire-DS1820.png&amp;diff=13921"/>
				<updated>2008-08-22T22:13:29Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Schaltplan für 1Wire mit DS18B20&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltplan für 1Wire mit DS18B20&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PICAXE&amp;diff=13083</id>
		<title>PICAXE</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PICAXE&amp;diff=13083"/>
				<updated>2008-01-13T17:58:32Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Kategorien, optisch optimiert ;-)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Der PICAXE ist im Grunde ein &amp;quot;normaler&amp;quot; PIC - Microcontroller, auf welchem ein Interpreter des Unternehmens [http://www.picaxe.com Revolution Education] läuft. Die Programme werden mit dem &amp;quot;PICAXE Programming Editor&amp;quot; entwickelt, welcher ebenfalls einen Debugger und natürlich auch den Downloader beinhaltet.&lt;br /&gt;
&lt;br /&gt;
== verschiedene Varianten ==&lt;br /&gt;
&lt;br /&gt;
Die PICAXE-Chips sind in verschiedenen Varianten erhältlich:&lt;br /&gt;
&lt;br /&gt;
* PICAXE 08&lt;br /&gt;
* PICAXE 08M&lt;br /&gt;
* PICAXE 14M&lt;br /&gt;
* PICAXE 18&lt;br /&gt;
* PICAXE 18A&lt;br /&gt;
* PICAXE 18X&lt;br /&gt;
* PICAXE 28A&lt;br /&gt;
* PICAXE 28X1&lt;br /&gt;
* PICAXE 40X1&lt;br /&gt;
* PICAXE 08M (SMD)&lt;br /&gt;
* PICAXE 18X (SMD)&lt;br /&gt;
* PICAXE 28X1 (SMD)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Features der Standardausführung ===&lt;br /&gt;
&lt;br /&gt;
* niedriger Preis (ausgelegt für Schulen bzw. zur Ausbildung)&lt;br /&gt;
* 40 Zeilen Programmspeicher&lt;br /&gt;
* ADC mit geringer Auflösung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Features der &amp;quot;A&amp;quot;-Varianten ===&lt;br /&gt;
&lt;br /&gt;
* 80 Zeilen Programmspeicher&lt;br /&gt;
* eigener Datenspeicherbereich&lt;br /&gt;
* 8-Bit ADC&lt;br /&gt;
* Interrupts&lt;br /&gt;
* Infrarotempfänger&lt;br /&gt;
* Digitales Temperatursensorinterface&lt;br /&gt;
* Servo-Engine&lt;br /&gt;
* Keyboardinterface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Features der &amp;quot;M&amp;quot;-Varianten (&amp;quot;M&amp;quot; - Music) ===&lt;br /&gt;
&lt;br /&gt;
* 80 Zeilen Programmspeicher&lt;br /&gt;
* spielt benutzerdefinierte oder vordefinierte Sounds ab (vordefiniert sind Happy Birthday, Jingle Bells, Silent Night, Rudolf the Red Nosed Reindeer)&lt;br /&gt;
* Infrarot Sende- und Empfangsinterface&lt;br /&gt;
* 8/10-Bit ADC&lt;br /&gt;
* Temperaturlesefunktionen&lt;br /&gt;
* Interrupts&lt;br /&gt;
* Servo-Engine&lt;br /&gt;
* PWM-Engine&lt;br /&gt;
* Eingangspulsmessung&lt;br /&gt;
* Serielles Interface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Features der &amp;quot;X&amp;quot;-Varianten (&amp;quot;X&amp;quot; - Advanced) ===&lt;br /&gt;
&lt;br /&gt;
* alle Features der A - Varianten zusätzlich der folgenden&lt;br /&gt;
* 600 Zeilen Programmspeicher&lt;br /&gt;
* I2C Interface&lt;br /&gt;
* 8/10-Bit ADC&lt;br /&gt;
* 12-Bit Temperaturlesefunktion&lt;br /&gt;
* PWM-Engine&lt;br /&gt;
* Eingangspulsmessung&lt;br /&gt;
* Serielles Interface (mit höheren Baudraten)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== serielles Interface (ohne Pegelwandler!!!) ==&lt;br /&gt;
[[Bild:Serial_download.jpg|thumb|Beschaltung der serielle Schnittstelle]]&lt;br /&gt;
Beim PICAXE ist es möglich, eine serielle Schnittstelle ohne einen Pegelwandler zu betreiben. Gleichzeitig wird genau diese Schnittstelle zum Download des Programms und zu Debugzwecken aus dem Controllerprogramm verwendet!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.picaxe.com Revolution Education]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12951</id>
		<title>TWI Praxis</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12951"/>
				<updated>2007-12-26T00:47:30Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Tipp Master&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das TWI-Hardwaremodul der AVRs zu verwenden.&lt;br /&gt;
Näheres zu [[TWI]] und [[I2C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
Die Beispiele sind zwar in Bascom Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Übertragungsarten =&lt;br /&gt;
&lt;br /&gt;
Bei TWI gibt es die folgenden Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Master =&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' zuständig. Mit der Formel auf der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' Seite müssen sie den Wert für das Register ''TWBR'' berechnen&lt;br /&gt;
&lt;br /&gt;
{|{{Blaueschmaltabelle}}&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot; |'''Tipp:'''&lt;br /&gt;
|In diesem Artikel werden die Register des [[AVR]] direkt angesprochen, dies soll nur als Beispiel dienen, um zu sehen wie zum Thema [[TWI]] das bei einem AVR aussieht !&amp;lt;br&amp;gt;Wer mit [[Bascom]] progammiert, verwendet am besten die ''i2c_twi.lib'' und die vorgegebenen Bascom-[[I2C]]-Befehle um das Programm übersichtlich zu halten. Siehe Artikel [[Bascom_I2C_Master]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Transmitter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Call Twi_send_byte(&amp;amp;H40 , B)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI send_byte}}&lt;br /&gt;
 {{vbcomment|sendet ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave And &amp;amp;HFE                               {{vbcomment|slave adresse + Write}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H20 Then&lt;br /&gt;
             Twdr = Zeichen                                  {{vbcomment|Daten}}&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Zeichen wurden gesendet}}&lt;br /&gt;
             If Twi_status = &amp;amp;H28 Or Twi_status = &amp;amp;H30 Then&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Function Twi_read_byte(byval Slave As Byte) As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim X As Byte                                               {{vbcomment|Zeichen von TWI}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI Init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Receiver&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt (egal welcher Wert, wird nur als Startbutton genutzt)}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|ein Byte vom Slave holen}}&lt;br /&gt;
     X = Twi_read_byte(&amp;amp;H40)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print X ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI read_byte}}&lt;br /&gt;
 {{vbcomment|holt ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Function Twi_read_byte(slave As Byte) As Byte&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     Twi_read_byte = 0                                       {{vbcomment|Wert vorbelegen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave Or &amp;amp;H01                                {{vbcomment|slave adresse + Read}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H40 Then&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                           {{vbcomment|kein ACK (TWEA &amp;amp;#61; 0) senden, weil wir nur ein Byte lesen wollen}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
             If Twi_status = &amp;amp;H58 Or Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                 Twi_read_byte = Twdr                        {{vbcomment|Daten lesen}}&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Function&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
=== Transmit und Receive ===&lt;br /&gt;
[[Bild:RN-M8_TWI_DS1621_PCF8574.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
;Senden und Empfangen&lt;br /&gt;
Der Master (Mega8) stößt die Temperaturmessung des DS1621 an, liest die Temperatur aus, sendet den Temperaturwert anschließend an einen PCF8574 zur Anzeige an dessen LEDs.&lt;br /&gt;
&lt;br /&gt;
Zur Kontrolle werden die Daten auch per UART übertragen und an den LEDs des RN-Meaga8 angezeigt.&lt;br /&gt;
&lt;br /&gt;
Während der Übertragung wird die Busgeschwindigkeit geändert, da der DS1621 mit 400kHz kommunizieren kann, der PCF8574 nur mit 100kHz.&lt;br /&gt;
&lt;br /&gt;
Dieses Programm wird auch zum testen im Artikel [[Bascom und USI-Kommunikation]] verwendet, dort ist dann ein [[ATtiny2313|ATTiny2313]] einer der Slaves.&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Daten vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M8def.dat&amp;quot;                            {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                      {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                           {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_errorstate As Byte                        {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Anzahlbuf As Byte                             {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                   {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                     {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Config Portb.0 = Output&lt;br /&gt;
 Config Portb.1 = Output&lt;br /&gt;
 Config Portd = Output&lt;br /&gt;
 &lt;br /&gt;
 Const Device = &amp;amp;H90&lt;br /&gt;
 Const Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI initialisieren}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                 {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                          {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                         {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                        {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Sound Portb.0 , 300 , 450                         {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;TWI Master DS1621 Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Portb.0 = 1                                       {{vbcomment|Damit die LED ausgeht nach dem Beep}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
     Twbr = 12                                     {{vbcomment|Bit Rate Register 400kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                        {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                          {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate = 0 Then                    {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         Waitms 1                                  {{vbcomment|Etwas warten bis die Temperatur gemessen ist}}&lt;br /&gt;
         Messagebuf(1) = Device                    {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                      {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate = 0 Then                {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread            {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Twi_errorstate = 0 Then            {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
                 {{vbcomment|STOP senden}}&lt;br /&gt;
                 Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Wert an den LEDs anzeigen}}&lt;br /&gt;
                 Portd.7 = Not Lowtemp.5&lt;br /&gt;
                 Portd.6 = Not Lowtemp.4&lt;br /&gt;
                 Portd.5 = Not Lowtemp.3&lt;br /&gt;
                 Portd.4 = Not Lowtemp.2&lt;br /&gt;
                 Portd.3 = Not Lowtemp.1&lt;br /&gt;
                 Portd.2 = Not Lowtemp.0&lt;br /&gt;
                 Portb.1 = Not Hightemp.7&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate &amp;lt;&amp;gt; 0 Then                   {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
     Else&lt;br /&gt;
         Twbr = 72                                 {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Einem evtl. angeschlossenem PCF8574 den Temperaturwert senden}}&lt;br /&gt;
         Messagebuf(1) = &amp;amp;H40&lt;br /&gt;
         Messagebuf(2) = Not Lowtemp&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate &amp;lt;&amp;gt; 0 Then               {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
             Print &amp;quot;Error2 &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 2&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 {{vbcomment|TWI Transmit and receive function.}}&lt;br /&gt;
 Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                             {{vbcomment|TWINT, TWSTA, TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
 &lt;br /&gt;
         Rw = Messagebuf(1).0                      {{vbcomment|RW-Flag holen für Abfrage unten}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
         For Cnt = 1 To Anzahlbuf&lt;br /&gt;
             {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
             {{vbcomment|Print Cnt ; &amp;quot; &amp;quot; ; Messagebuf(cnt) ; &amp;quot; &amp;quot; ; Rw}}&lt;br /&gt;
             If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
                 {{vbcomment|Write Slaveadr}}&lt;br /&gt;
                 Twdr = Messagebuf(cnt)&lt;br /&gt;
                 Twcr = &amp;amp;B10000100                 {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Beim 1. Byte wird ein anderer Status erwartet}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     {{vbcomment|Slave hat sich gemeldet, $20 ist NACK, $18 WriteACK, $40 ReadACK !}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H40 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         {{vbcomment|kein Slave}}&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Zeichen wurde gesendet, $30 ist NACK}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H28 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             Else&lt;br /&gt;
                 {{vbcomment|Read a Byte}}&lt;br /&gt;
                 {{vbcomment|Wenn das letzte Byte gesendet wird, ein NACK mitgeben um das Ende anzuzeigen}}&lt;br /&gt;
                 If Cnt = Anzahlbuf Then&lt;br /&gt;
                     {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
                     Twcr = &amp;amp;B10000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Load ACK. TWEA ist 1}}&lt;br /&gt;
                     Twcr = &amp;amp;B11000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
                 Messagebuf(cnt) = Twdr            {{vbcomment|Daten lesen}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Byte empfangen und mit ACK quittiert, sonst Ende}}&lt;br /&gt;
                 If Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                     Twi_errorstate = 0            {{vbcomment|kein Fehler}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Beim letzten Byte auch mit NACK quittieren}}&lt;br /&gt;
                     If Cnt = Anzahlbuf And Twi_status = &amp;amp;H58 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         Next Cnt&lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Ist der Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                         {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Twi_errorstate = Twi_status               {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Stopsequenz ausgeben}}&lt;br /&gt;
 Twi_stop:&lt;br /&gt;
     Twcr = &amp;amp;B10010100                             {{vbcomment|TWINT löschen, Stop senden}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Warten bis Stop-Flag wieder gelöscht wird, dann ist die Stopsequenz abgeschlossen}}&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H10&lt;br /&gt;
     Loop Until Twi_control = 0&lt;br /&gt;
     {{vbcomment|Es muss nicht unbedingt darauf gewartet werden}}&lt;br /&gt;
     {{vbcomment|wenn die nächste Aktion nicht gleich anschliessend durchgeführt wird.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Einen speziellen STOP-Status gibt es nicht, es ist in der Regel &amp;amp;HF8}}&lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|Print Hex(twi_status)}}&lt;br /&gt;
 &lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Slave =&lt;br /&gt;
[[Bild:I2C_RN-M8_RN-control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Da der TWI-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave das [[RN-Mega8]] Board verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Count As Byte                                           {{vbcomment|Testwert, jedes mal +1}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Werte zurücksetzen}}&lt;br /&gt;
 Count = 0&lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|will der Master ein Byte haben}}&lt;br /&gt;
         If Twi_status = &amp;amp;HA8 Or Twi_status = &amp;amp;HB8 Then&lt;br /&gt;
             Twdr = Count                                    {{vbcomment|neue Daten ausgeben}}&lt;br /&gt;
             Incr Count                                      {{vbcomment|testwert +1}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, mit ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortD aus, an dem beim RN-M8 eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Config Portd = Output                                       {{vbcomment|kompletter PortD als Ausgang}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Neuesbyte As Byte                                       {{vbcomment|Bytemerker}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|alle LEDs ein}}&lt;br /&gt;
 Portd = 0&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Merker zurücksetzen}}&lt;br /&gt;
     Neuesbyte = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|wurde ein Byte geschickt}}&lt;br /&gt;
         If Twi_status = &amp;amp;H80 Or Twi_status = &amp;amp;H88 Then&lt;br /&gt;
             Twi_data = Twdr                                 {{vbcomment|neue Daten merken}}&lt;br /&gt;
             Neuesbyte = 1                                   {{vbcomment|merken das ein neues Byte da ist}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, erzeugt ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn ein neues Byte gekommen ist, dieses an PortD ausgeben}}&lt;br /&gt;
     If Neuesbyte &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
         Portd = Twi_data                                    {{vbcomment|Daten auf PortD ausgeben}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Der Slave ist hier sogar in der Lage während einer Übertragung mehr als ein Byte entgegenzunehmen, da jedes Byte den gleichen Status erzeugt.&lt;br /&gt;
&lt;br /&gt;
Wenn der Slave schnell genug getaktet wird (&amp;gt; 6.4 MHz), kann der Master auch auf einen schnelleren Bus-Takt gestellt werden. Dazu beim Master das ''TWBR'' auf 12 setzen, so wird der Bus mit 400kHz betrieben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[I2C]] - Allgemeines zu I2C&lt;br /&gt;
* [[TWI]] - Registerbeschreibungen&lt;br /&gt;
* [[TWI Praxis Multimaster]]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=246777#246777] - etwas ausführlicheres Slave-Beipiel im Forum&lt;br /&gt;
* [[Bascom I2C Master]] - Beispiele wie ein AVR als I2C-Master initialisiert werden kann.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - I2C Beispiele mit Bascom und dem USI-Modul&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= WebLinks =&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs C-Quellbibliothek für einen TWI-Master von Peter Fleury (avr-gcc)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 15:31, 15. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:Smile.png&amp;diff=12934</id>
		<title>Datei:Smile.png</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:Smile.png&amp;diff=12934"/>
				<updated>2007-12-15T15:58:46Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Bild für Hilfeseiten als Beispiel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bild für Hilfeseiten als Beispiel&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:Pilzkorb.jpg&amp;diff=12933</id>
		<title>Datei:Pilzkorb.jpg</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:Pilzkorb.jpg&amp;diff=12933"/>
				<updated>2007-12-15T15:57:04Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Bild für Hilfeseiten als Beispiel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bild für Hilfeseiten als Beispiel&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:Prisma.png&amp;diff=12932</id>
		<title>Datei:Prisma.png</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:Prisma.png&amp;diff=12932"/>
				<updated>2007-12-15T15:54:45Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Grafik für Hilfeseiten als Beispiel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Grafik für Hilfeseiten als Beispiel&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=12915</id>
		<title>Benutzer:Linux 80</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Benutzer:Linux_80&amp;diff=12915"/>
				<updated>2007-12-03T23:46:20Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: ein paar Bauteile hinzu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Seit Mai 2005 ASURO-Besitzer, und AVR-Forscher ;-)&lt;br /&gt;
&lt;br /&gt;
Will von den [[AVR]]s so viele Details wissen wie früher vom 6502 !&lt;br /&gt;
&lt;br /&gt;
Näheres auf der RN-Nickpage.&lt;br /&gt;
&lt;br /&gt;
Forschutensilien inzwischen ausgebaut um:&lt;br /&gt;
*[[RN-Control]] 2 Stück, siehe [[Verlosung]]&lt;br /&gt;
*[[RN-Mega8]]&lt;br /&gt;
*[[RN-MiniControl]]&lt;br /&gt;
*[http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=152 RN-LCD-Adapter]&lt;br /&gt;
*TextLCD mit 16*2 Zeichen&lt;br /&gt;
*TextLCD mit 20*4 Zeichen [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=80 EA-Dip204]&lt;br /&gt;
*GrafikLCD 128*64 mit KS0108 ([http://www.pollin.de/shop/downloads/D120423D.PDF Pollin 120423])&lt;br /&gt;
*GrafikLCD 128*64 mit SED1565 ([http://www.pollin.de/shop/downloads/D120292D.RAR Pollin 120292]) &amp;lt;small&amp;gt;(das hat aber sich aber aufgelöst, und eine Art Lochfrass in der Scheibe, sieht aus als wenn immer Pixel gesetzt sind, obwohl keine Power auf dem LCD, vom Prinzip her funktionierts aber noch)&amp;lt;/small&amp;gt;&lt;br /&gt;
*und weitere AT-Megas und -Tinys&lt;br /&gt;
*Schachtelweise elektronisches kleinzeugs, das gelegentlich ausprobiert werden muss&lt;br /&gt;
&lt;br /&gt;
Seit Dezember 2005 im besitz eines Renesas R8C/13 Controllers (samt selbstgebautem Applicationboard), der durch eine bekannte Zeitschrift unters Volk gebracht wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.roboternetz.de/phpBB2/nickpage.php?user=linux_80 Linux_80] - RN-Nickpage&lt;br /&gt;
*http://roboter.net-con.net/asuro/ - Homepage&lt;br /&gt;
&amp;lt;!-- *http://www.elektor.de/ - Zeitschrift elektor --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12897</id>
		<title>Bascom I2C Master</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12897"/>
				<updated>2007-11-18T21:31:17Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen verschiedene Programmbeispiele um einen [[AVR]] mit [[Bascom]] zu einem [[I2C]]-Master zu schlumpfen.&lt;br /&gt;
&lt;br /&gt;
In allen Beispielen wird einem PCF8574 jeweils der Wert &amp;amp;HAA nach einer Pause &amp;amp;H55 gesendet, was als Blinken, evtl. auch als Lauflicht zu erkennen sein kann, falls LEDs an dessen Ports angeschlossen sind.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software I2C ==&lt;br /&gt;
&lt;br /&gt;
Die Softwareversion der I2C-Implementierung kann auf allen AVR programmiert werden, man kann sich die Ports auf denen Data (SDA) und Clock (SCL) angeschlossen werden selbst aussuchen.&lt;br /&gt;
&lt;br /&gt;
Standardmäßig wird von Bascom die Software-Version verwendet um auf den I2C-Bus zuzugreifen, d.H. die einzelnen Bits der zu übertragenden Daten werden per Software auf High- oder Low-Pegel an den Ports ausgegeben. Der AVR kann in dieser Zeit keine anderen Aufgaben erledigen.&lt;br /&gt;
&lt;br /&gt;
Bei dieser Art I2C zu implementieren wird eine aktuelle Aktivität auf dem Bus nicht beachtet, dies kann zu Problemen führen falls mehr als ein Master am Bus hängt. Siehe Links unter &amp;quot;[[#Siehe_auch|Siehe auch]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 Config Scl = Portb.0                              {{vbcomment|Ports fuer IIC-Bus, nicht Standard !}}&lt;br /&gt;
 Config Sda = Portb.1&lt;br /&gt;
&amp;lt;!-- das &amp;quot;=&amp;quot; immer mit &amp;amp;#061; angeben, sonst gibts keinen Kommentar !! --&amp;gt;&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 10                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-Soft Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Falls mehr als nur ein Byte an einen Slave gesendet werden sollte, und nach dem letzten Byte ERR=1 ist, sollte anschließend ein I2Cstop folgen, da der Slave kein weiteres Byte haben will !&lt;br /&gt;
&lt;br /&gt;
== Hardware TWI ==&lt;br /&gt;
&lt;br /&gt;
AVR Controller, die [[I2C]] hardwaremäßig Unterstützen, haben das [[TWI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. TWI ist bei den meisten ATMegas vorhanden, z.B. dem [[ATMega32]].&lt;br /&gt;
&lt;br /&gt;
Damit Bascom das TWI-Modul verwendet muss die &amp;lt;tt&amp;gt;i2c_twi.lib&amp;lt;/tt&amp;gt; (bzw. &amp;lt;tt&amp;gt;.lbx&amp;lt;/tt&amp;gt;, bei der Bascom-Demo) eingebunden werden, ansonsten ist, bis auf die Initialisierung, alles genauso wie bei Software-I2C.&lt;br /&gt;
Bei Verwendung der Bascom-I2C-Befehle macht es Performancemäßig keinen großen Unterschied, ob man Software-I2C oder TWI verwendet, denn bei beiden Versionen wird solange darauf gewartet, bis das Byte über den Bus gesendet ist, und ein ACK oder NACK empfangen ist.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil von TWI ist aber, das es in Multimasterumgebungen besser verträglich ist (z.B. I2CStart). Gibt es nur einen Master, kann man sich für eine der beiden Versionen entscheiden.&lt;br /&gt;
&lt;br /&gt;
Der Master bestimmt wie schnell die Daten auf dem Bus übertragen werden (Ausnahme: [[Clock_Stretching]] ).&lt;br /&gt;
Dafür ist hier die Zeile mit '''&amp;lt;tt&amp;gt;Config TWI&amp;lt;/tt&amp;gt;''' zuständig, Bascom berechnet aus der angegebenen Taktfrequenz den richtigen Wert für TWBR um an den gewünschten I2C-Takt zu kommen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = &amp;amp;B00000100                                 {{vbcomment|nur TWEN setzen}}&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Mit der TWI-Lib wird zwar die Hardware benutzt um die Bytes auf den I2C-Bus auszugeben bzw. von dort einzulesen, es wird aber kein Status von TWSR abgefragt, ob die erwartete Reaktion eingetreten ist !&lt;br /&gt;
&lt;br /&gt;
Unter Zuhilfenahme des Datenblattes könnte eine Highend-Version so aussehen:&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI High-Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;HAA                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
 &lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;H55                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Die Printausgaben im Else-Teil sind natürlich nur in der Demo nützlich, in der Praxis entweder den Else-Teil ganz weglassen, oder entsprechende Variablen setzen um den Fehler später zu bearbeiten.&lt;br /&gt;
&lt;br /&gt;
Eine einfachere Version einen Fehler frühzeitig zu erkennen, ist statt TWSR nur ERR auf 0 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware USI ==&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR Controller, die zwar kein TWI-Modul haben, aber [[I2C]] hardwaremäßig Unterstützen, haben das [[USI (Avr)|USI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. USI ist bei den meisten ATTinys und einigen ATMegas vorhanden, z.B. dem [[ATtiny2313|ATTiny2313]].&lt;br /&gt;
&lt;br /&gt;
Das [[USI (Avr)|USI]]-Modul kann evtl. als eine Art von TWI-Light angesehen werden, denn es ist nicht so komfortabel wie TWI, es muss intern noch viel in Software erledigt werden, weshalb es Performancemäßig auch keinen großen unterschied macht, ob man Software-I2C oder USI beim Master verwendet.&lt;br /&gt;
&lt;br /&gt;
Am einfachsten benutzt man die Lib, die unter [[#Weblinks|Weblinks]] aufgeführt ist, denn dann kann man die von Bascom vorgegebenen Befehle benutzen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;                       {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_usi.lbx&amp;quot;                                {{vbcomment|Für Hardware USI-I2C}}&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.7                              {{vbcomment|Ports fuer IIC-Bus}}&lt;br /&gt;
 Config Sda = Portb.5&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 5                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
  &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-USI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Nach I2Cstart (auch I2CStop) kann ERR kontrolliert werden, ob das Start (bzw. Stop) auch auf den Bus abgesetzt werden konnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beispiele für Hardware USI&lt;br /&gt;
* [[Bascom Soft-I2c Library]] - weitere Tipps zu I2C mit Bascom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:08, 28. Okt 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12892</id>
		<title>TWI Praxis</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12892"/>
				<updated>2007-11-15T21:02:37Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Siehe auch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das TWI-Hardwaremodul der AVRs zu verwenden.&lt;br /&gt;
Näheres zu [[TWI]] und [[I2C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
Die Beispiele sind zwar in Bascom Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Übertragungsarten =&lt;br /&gt;
&lt;br /&gt;
Bei TWI gibt es die folgenden Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Master =&lt;br /&gt;
[[Bild:I2C_PCF8574_RN-Control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' zuständig. Mit der Formel auf der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' Seite müssen sie den Wert für das Register ''TWBR'' berechnen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Transmitter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Call Twi_send_byte(&amp;amp;H40 , B)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI send_byte}}&lt;br /&gt;
 {{vbcomment|sendet ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave And &amp;amp;HFE                               {{vbcomment|slave adresse + Write}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H20 Then&lt;br /&gt;
             Twdr = Zeichen                                  {{vbcomment|Daten}}&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Zeichen wurden gesendet}}&lt;br /&gt;
             If Twi_status = &amp;amp;H28 Or Twi_status = &amp;amp;H30 Then&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Function Twi_read_byte(byval Slave As Byte) As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim X As Byte                                               {{vbcomment|Zeichen von TWI}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI Init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Receiver&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt (egal welcher Wert, wird nur als Startbutton genutzt)}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|ein Byte vom Slave holen}}&lt;br /&gt;
     X = Twi_read_byte(&amp;amp;H40)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print X ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI read_byte}}&lt;br /&gt;
 {{vbcomment|holt ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Function Twi_read_byte(slave As Byte) As Byte&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     Twi_read_byte = 0                                       {{vbcomment|Wert vorbelegen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave Or &amp;amp;H01                                {{vbcomment|slave adresse + Read}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H40 Then&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                           {{vbcomment|kein ACK (TWEA &amp;amp;#61; 0) senden, weil wir nur ein Byte lesen wollen}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
             If Twi_status = &amp;amp;H58 Or Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                 Twi_read_byte = Twdr                        {{vbcomment|Daten lesen}}&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Function&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
=== Transmit und Receive ===&lt;br /&gt;
[[Bild:RN-M8_TWI_DS1621_PCF8574.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
;Senden und Empfangen&lt;br /&gt;
Der Master (Mega8) stößt die Temperaturmessung des DS1621 an, liest die Temperatur aus, sendet den Temperaturwert anschließend an einen PCF8574 zur Anzeige an dessen LEDs.&lt;br /&gt;
&lt;br /&gt;
Zur Kontrolle werden die Daten auch per UART übertragen und an den LEDs des RN-Meaga8 angezeigt.&lt;br /&gt;
&lt;br /&gt;
Während der Übertragung wird die Busgeschwindigkeit geändert, da der DS1621 mit 400kHz kommunizieren kann, der PCF8574 nur mit 100kHz.&lt;br /&gt;
&lt;br /&gt;
Dieses Programm wird auch zum testen im Artikel [[Bascom und USI-Kommunikation]] verwendet, dort ist dann ein [[ATtiny2313|ATTiny2313]] einer der Slaves.&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Daten vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M8def.dat&amp;quot;                            {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                      {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                           {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_errorstate As Byte                        {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Anzahlbuf As Byte                             {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                   {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                     {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Config Portb.0 = Output&lt;br /&gt;
 Config Portb.1 = Output&lt;br /&gt;
 Config Portd = Output&lt;br /&gt;
 &lt;br /&gt;
 Const Device = &amp;amp;H90&lt;br /&gt;
 Const Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI initialisieren}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                 {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                          {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                         {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                        {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Sound Portb.0 , 300 , 450                         {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;TWI Master DS1621 Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Portb.0 = 1                                       {{vbcomment|Damit die LED ausgeht nach dem Beep}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
     Twbr = 12                                     {{vbcomment|Bit Rate Register 400kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                        {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                          {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate = 0 Then                    {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         Waitms 1                                  {{vbcomment|Etwas warten bis die Temperatur gemessen ist}}&lt;br /&gt;
         Messagebuf(1) = Device                    {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                      {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate = 0 Then                {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread            {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Twi_errorstate = 0 Then            {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
                 {{vbcomment|STOP senden}}&lt;br /&gt;
                 Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Wert an den LEDs anzeigen}}&lt;br /&gt;
                 Portd.7 = Not Lowtemp.5&lt;br /&gt;
                 Portd.6 = Not Lowtemp.4&lt;br /&gt;
                 Portd.5 = Not Lowtemp.3&lt;br /&gt;
                 Portd.4 = Not Lowtemp.2&lt;br /&gt;
                 Portd.3 = Not Lowtemp.1&lt;br /&gt;
                 Portd.2 = Not Lowtemp.0&lt;br /&gt;
                 Portb.1 = Not Hightemp.7&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate &amp;lt;&amp;gt; 0 Then                   {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
     Else&lt;br /&gt;
         Twbr = 72                                 {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Einem evtl. angeschlossenem PCF8574 den Temperaturwert senden}}&lt;br /&gt;
         Messagebuf(1) = &amp;amp;H40&lt;br /&gt;
         Messagebuf(2) = Not Lowtemp&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate &amp;lt;&amp;gt; 0 Then               {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
             Print &amp;quot;Error2 &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 2&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 {{vbcomment|TWI Transmit and receive function.}}&lt;br /&gt;
 Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                             {{vbcomment|TWINT, TWSTA, TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
 &lt;br /&gt;
         Rw = Messagebuf(1).0                      {{vbcomment|RW-Flag holen für Abfrage unten}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
         For Cnt = 1 To Anzahlbuf&lt;br /&gt;
             {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
             {{vbcomment|Print Cnt ; &amp;quot; &amp;quot; ; Messagebuf(cnt) ; &amp;quot; &amp;quot; ; Rw}}&lt;br /&gt;
             If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
                 {{vbcomment|Write Slaveadr}}&lt;br /&gt;
                 Twdr = Messagebuf(cnt)&lt;br /&gt;
                 Twcr = &amp;amp;B10000100                 {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Beim 1. Byte wird ein anderer Status erwartet}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     {{vbcomment|Slave hat sich gemeldet, $20 ist NACK, $18 WriteACK, $40 ReadACK !}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H40 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         {{vbcomment|kein Slave}}&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Zeichen wurde gesendet, $30 ist NACK}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H28 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             Else&lt;br /&gt;
                 {{vbcomment|Read a Byte}}&lt;br /&gt;
                 {{vbcomment|Wenn das letzte Byte gesendet wird, ein NACK mitgeben um das Ende anzuzeigen}}&lt;br /&gt;
                 If Cnt = Anzahlbuf Then&lt;br /&gt;
                     {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
                     Twcr = &amp;amp;B10000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Load ACK. TWEA ist 1}}&lt;br /&gt;
                     Twcr = &amp;amp;B11000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
                 Messagebuf(cnt) = Twdr            {{vbcomment|Daten lesen}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Byte empfangen und mit ACK quittiert, sonst Ende}}&lt;br /&gt;
                 If Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                     Twi_errorstate = 0            {{vbcomment|kein Fehler}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Beim letzten Byte auch mit NACK quittieren}}&lt;br /&gt;
                     If Cnt = Anzahlbuf And Twi_status = &amp;amp;H58 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         Next Cnt&lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Ist der Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                         {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Twi_errorstate = Twi_status               {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Stopsequenz ausgeben}}&lt;br /&gt;
 Twi_stop:&lt;br /&gt;
     Twcr = &amp;amp;B10010100                             {{vbcomment|TWINT löschen, Stop senden}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Warten bis Stop-Flag wieder gelöscht wird, dann ist die Stopsequenz abgeschlossen}}&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H10&lt;br /&gt;
     Loop Until Twi_control = 0&lt;br /&gt;
     {{vbcomment|Es muss nicht unbedingt darauf gewartet werden}}&lt;br /&gt;
     {{vbcomment|wenn die nächste Aktion nicht gleich anschliessend durchgeführt wird.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Einen speziellen STOP-Status gibt es nicht, es ist in der Regel &amp;amp;HF8}}&lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|Print Hex(twi_status)}}&lt;br /&gt;
 &lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Slave =&lt;br /&gt;
[[Bild:I2C_RN-M8_RN-control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Da der TWI-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave das [[RN-Mega8]] Board verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Count As Byte                                           {{vbcomment|Testwert, jedes mal +1}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Werte zurücksetzen}}&lt;br /&gt;
 Count = 0&lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|will der Master ein Byte haben}}&lt;br /&gt;
         If Twi_status = &amp;amp;HA8 Or Twi_status = &amp;amp;HB8 Then&lt;br /&gt;
             Twdr = Count                                    {{vbcomment|neue Daten ausgeben}}&lt;br /&gt;
             Incr Count                                      {{vbcomment|testwert +1}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, mit ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortD aus, an dem beim RN-M8 eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Config Portd = Output                                       {{vbcomment|kompletter PortD als Ausgang}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Neuesbyte As Byte                                       {{vbcomment|Bytemerker}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|alle LEDs ein}}&lt;br /&gt;
 Portd = 0&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Merker zurücksetzen}}&lt;br /&gt;
     Neuesbyte = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|wurde ein Byte geschickt}}&lt;br /&gt;
         If Twi_status = &amp;amp;H80 Or Twi_status = &amp;amp;H88 Then&lt;br /&gt;
             Twi_data = Twdr                                 {{vbcomment|neue Daten merken}}&lt;br /&gt;
             Neuesbyte = 1                                   {{vbcomment|merken das ein neues Byte da ist}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, erzeugt ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn ein neues Byte gekommen ist, dieses an PortD ausgeben}}&lt;br /&gt;
     If Neuesbyte &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
         Portd = Twi_data                                    {{vbcomment|Daten auf PortD ausgeben}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Der Slave ist hier sogar in der Lage während einer Übertragung mehr als ein Byte entgegenzunehmen, da jedes Byte den gleichen Status erzeugt.&lt;br /&gt;
&lt;br /&gt;
Wenn der Slave schnell genug getaktet wird (&amp;gt; 6.4 MHz), kann der Master auch auf einen schnelleren Bus-Takt gestellt werden. Dazu beim Master das ''TWBR'' auf 12 setzen, so wird der Bus mit 400kHz betrieben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]]&lt;br /&gt;
* [[TWI Praxis Multimaster]]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=246777#246777] - etwas ausführlicheres Slave-Beipiel im Forum&lt;br /&gt;
* [[Bascom I2C Master]] - Beispiele wie ein AVR als I2C-Master initialisiert werden kann.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - I2C Beispiele mit Bascom und dem USI-Modul&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= WebLinks =&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs C-Quellbibliothek für einen TWI-Master von Peter Fleury (avr-gcc)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 15:31, 15. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12854</id>
		<title>Bascom I2C Master</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12854"/>
				<updated>2007-10-28T10:45:52Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Im Detail optimiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen verschiedene Programmbeispiele um einen [[AVR]] mit [[Bascom]] zu einem [[I2C]]-Master zu schlumpfen.&lt;br /&gt;
&lt;br /&gt;
In allen Beispielen wird einem PCF8574 jeweils der Wert &amp;amp;HAA nach einer Pause &amp;amp;H55 gesendet, was als Blinken, evtl. auch als Lauflicht zu erkennen sein kann, falls LEDs an dessen Ports angeschlossen sind.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software I2C ==&lt;br /&gt;
&lt;br /&gt;
Die Softwareversion der I2C-Implmentierung kann auf allen AVR programmiert werden, man kann sich die Ports auf denen Data (SDA) und Clock (SCL) angeschlossen werden selbst aussuchen.&lt;br /&gt;
&lt;br /&gt;
Standardmäßig wird von Bascom die Software-Version verwendet um auf den I2C-Bus zuzugreifen, d.H. die einzelnen Bits der zu übertragenden Daten werden per Software auf High- oder Low-Pegel an den Ports ausgegeben. Der AVR kann in dieser Zeit keine anderen Aufgaben erledigen.&lt;br /&gt;
&lt;br /&gt;
Bei dieser Art I2C zu implementieren wird eine aktuelle Aktivität auf dem Bus nicht beachtet, dies kann zu Problemen führen falls mehr als ein Master am Bus hängt. Siehe Links unter &amp;quot;[[#Siehe_auch|Siehe auch]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 Config Scl = Portb.0                              {{vbcomment|Ports fuer IIC-Bus, nicht Standard !}}&lt;br /&gt;
 Config Sda = Portb.1&lt;br /&gt;
&amp;lt;!-- das &amp;quot;=&amp;quot; immer mit &amp;amp;#061; angeben, sonst gibts keinen Kommentar !! --&amp;gt;&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 10                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-Soft Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Falls mehr als nur ein Byte an einen Slave gesendet werden sollte, und nach dem letzten Byte ERR=1 ist, sollte anschließend ein I2Cstop folgen, da der Slave kein weiteres Byte haben will !&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware TWI ==&lt;br /&gt;
&lt;br /&gt;
AVR Controller, die [[I2C]] hardwaremäßig Unterstützen, haben das [[TWI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. TWI ist bei den meisten ATMegas vorhanden, z.B. dem [[ATMega32]].&lt;br /&gt;
&lt;br /&gt;
Damit Bascom das TWI-Modul verwendet muss die &amp;lt;tt&amp;gt;i2c_twi.lib&amp;lt;/tt&amp;gt; (bzw. &amp;lt;tt&amp;gt;.lbx&amp;lt;/tt&amp;gt;, bei der Bascom-Demo) eingebunden werden, ansonsten ist, bis auf die Initialisierung, alles genauso wie bei Software-I2C.&lt;br /&gt;
Bei Verwendung der Bascom-I2C-Befehle macht es Performancemäßig keinen großen Unterschied, ob man Software-I2C oder TWI verwendet, denn bei beiden Versionen wird solange darauf gewartet, bis das Byte über den Bus gesendet ist, und ein ACK oder NACK empfangen ist.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil von TWI ist aber, das es in Multimasterumgebungen besser verträglich ist (z.B. I2CStart). Gibt es nur einen Master, kann man sich für eine der beiden Versionen entscheiden.&lt;br /&gt;
&lt;br /&gt;
Der Master bestimmt wie schnell die Daten auf dem Bus übertragen werden (Ausnahme: [[Clock_Stretching]] ).&lt;br /&gt;
Dafür ist hier die Zeile mit '''&amp;lt;tt&amp;gt;Config TWI&amp;lt;/tt&amp;gt;''' zuständig, Bascom berechnet aus der angegebenen Taktfrequenz den richtigen Wert für TWBR um an den gewünschten I2C-Takt zu kommen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN  &lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Mit der TWI-Lib wird zwar die Hardware benutzt um die Bytes auf den I2C-Bus auszugeben bzw. von dort einzulesen, es wird aber kein Status von TWSR abgefragt, ob die erwartete Reaktion eingetreten ist !&lt;br /&gt;
&lt;br /&gt;
Unter Zuhilfenahme des Datenblattes könnte eine Highend-Version so aussehen:&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI High-Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;HAA                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
 &lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;H55                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Die Printausgaben im Else-Teil sind natürlich nur in der Demo nützlich, in der Praxis entweder den Else-Teil ganz weglassen, oder entsprechende Variablen setzen um den Fehler später zu bearbeiten.&lt;br /&gt;
&lt;br /&gt;
Eine einfachere Version einen Fehler frühzeitig zu erkennen, ist statt TWSR nur ERR auf 0 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware USI ==&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR Controller, die zwar kein TWI-Modul haben, aber [[I2C]] hardwaremäßig Unterstützen, haben das [[USI (Avr)|USI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. USI ist bei den meisten ATTinys und einigen ATMegas vorhanden, z.B. dem [[ATtiny2313|ATTiny2313]].&lt;br /&gt;
&lt;br /&gt;
Das [[USI (Avr)|USI]]-Modul kann evtl. als eine Art von TWI-Light angesehen werden, denn es ist nicht so komfortabel wie TWI, es muss intern noch viel in Software erledigt werden, weshalb es Performancemäßig auch keinen großen unterschied macht, ob man Software-I2C oder USI beim Master verwendet.&lt;br /&gt;
&lt;br /&gt;
Am einfachsten benutzt man die Lib, die unter [[#Weblinks|Weblinks]] aufgeführt ist, denn dann kann man die von Bascom vorgegebenen Befehle benutzen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;                       {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &amp;lt;font color=&amp;quot;#a01010&amp;quot;&amp;gt;&lt;br /&gt;
 $lib &amp;quot;i2c_usi.lbx&amp;quot;                                {{vbcomment|Für Hardware USI-I2C}}&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.7                              {{vbcomment|Ports fuer IIC-Bus}}&lt;br /&gt;
 Config Sda = Portb.5&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 5                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &amp;lt;/font&amp;gt;&lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
  &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-USI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Nach I2Cstart (auch I2CStop) kann ERR kontrolliert werden, ob das Start (bzw. Stop) auch auf den Bus abgesetzt werden konnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beispiele für Hardware USI&lt;br /&gt;
* [[Bascom Soft-I2c Library]] - weitere Tipps zu I2C mit Bascom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:08, 28. Okt 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12850</id>
		<title>Bascom I2C Master</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_I2C_Master&amp;diff=12850"/>
				<updated>2007-10-28T00:08:09Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Neu angelegt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen verschiedene Programmbeispiele um einen [[AVR]] mit [[Bascom]] zu einem [[I2C]]-Master zu schlumpfen.&lt;br /&gt;
&lt;br /&gt;
In allen Beispielen wird einem PCF8574 jeweils der Wert &amp;amp;HAA nach einer Pause &amp;amp;H55 gesendet, was als Blinken, evtl. auch als Lauflicht zu erkennen sein kann, falls LEDs an dessen Ports angeschlossen sind.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RN-Control_PCF8574.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Software I2C ==&lt;br /&gt;
&lt;br /&gt;
Die Softwareversion der I2C-Implmentierung kann auf allen AVR programmiert werden, man kann sich die Ports auf denen Data (SDA) und Clock (SCL) angeschlossen werden selbst aussuchen.&lt;br /&gt;
&lt;br /&gt;
Bei dieser Art I2C zu implementieren wird eine aktuelle Aktivität auf dem Bus nicht beachtet, dies kann zu Problemen führen falls mehr als ein Master am Bus hängt. Siehe Links unter &amp;quot;[[#Siehe_auch|Siehe auch]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.0                              {{vbcomment|Ports fuer IIC-Bus, nicht Standard !}}&lt;br /&gt;
 Config Sda = Portb.1&lt;br /&gt;
&amp;lt;!-- das &amp;quot;=&amp;quot; immer mit &amp;amp;#061; angeben, sonst gibts keinen Kommentar !! --&amp;gt;&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 10                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-Soft Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Falls mehr als nur ein Byte an einen Slave gesendet werden sollte, und nach dem letzten Byte ERR=1 ist, sollte anschließend ein I2Cstop folgen, da der Slave kein weiteres Byte haben will !&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware TWI ==&lt;br /&gt;
&lt;br /&gt;
AVR Controller, die [[I2C]] hardwaremäßig Unterstützen, haben das [[TWI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. TWI ist bei den meisten ATMegas vorhanden, z.B. dem [[ATMega32]].&lt;br /&gt;
&lt;br /&gt;
Der Master bestimmt wie schnell die Daten auf dem Bus übertragen werden (Ausnahme: [[Clock_Stretching]] ).&lt;br /&gt;
Dafür ist hier die Zeile mit '''&amp;lt;tt&amp;gt;Config TWI&amp;lt;/tt&amp;gt;''' zuständig, Bascom berechnet aus der angegebenen Taktfrequenz den richtigen Wert für TWBR um an den gewünschten I2C-Takt zu kommen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN  &lt;br /&gt;
 &lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Mit der TWI-Lib wird zwar die Hardware benutzt um die Bytes auf den I2C-Bus auszugeben bzw. von dort einzulesen, es wird aber kein Status von TWSR abgefragt, ob die erwartete Reaktion eingetreten ist !&lt;br /&gt;
&lt;br /&gt;
Unter Zuhilfenahme des Datenblattes könnte eine Highend-Version so aussehen:&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                           {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 $lib &amp;quot;i2c_twi.lbx&amp;quot;                                {{vbcomment|Für Hardware TWI}}&lt;br /&gt;
 &lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
 &lt;br /&gt;
 Config Twi = 400000                               {{vbcomment|Init TWBR und TWSR}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI gleich einschalten, das macht Bascom ansonsten erst beim I2CStart !}}&lt;br /&gt;
 TWCR = TWEN&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-TWI High-Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;HAA                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
 &lt;br /&gt;
     If TWSR = &amp;amp;H08 Then                           {{vbcomment|Start wurde abgesetzt}}&lt;br /&gt;
         I2cwbyte Pcf_write                        {{vbcomment|Slaveadresse ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
         If TWSR = &amp;amp;H18 Then                       {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
             I2cwbyte &amp;amp;H55                         {{vbcomment|Datenbyte ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
             If TWSR &amp;lt;&amp;gt; &amp;amp;H28 Then                  {{vbcomment|Byte erfolgreich übertragen}}&lt;br /&gt;
                 Print &amp;quot;Byte mit NACK quittiert !&amp;quot;&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             Print &amp;quot;kein Slave !&amp;quot;&lt;br /&gt;
         End If&lt;br /&gt;
     Else&lt;br /&gt;
         Print &amp;quot;Fehler bei Start&amp;quot;&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Immer Stop, damit die Buspegel wieder stimmen}}&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print &amp;quot;E &amp;quot; ; Err                              {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 1500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Die Printausgaben im Else-Teil sind natürlich nur in der Demo nützlich, in der Praxis entweder den Else-Teil ganz weglassen, oder entsprechende Variablen setzen um den Fehler später zu bearbeiten.&lt;br /&gt;
&lt;br /&gt;
Eine einfachere Version einen Fehler frühzeitig zu erkennen, ist statt TWSR nur ERR auf 0 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware USI ==&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR Controller, die zwar kein TWI-Modul haben, aber [[I2C]] hardwaremäßig Unterstützen, haben das [[USI (Avr)|USI]]-Modul, die Ports für Data und Clock sind dabei vorgegeben. USI ist bei den meisten ATTinys und einigen ATMegas vorhanden, z.B. dem [[ATtiny2313|ATTiny2313]].&lt;br /&gt;
&lt;br /&gt;
Am einfachsten benutzt man die Lib, die unter Weblinks aufgeführt ist, denn dann kann man die von Bascom vorgegebenen Befehle benutzen.&lt;br /&gt;
&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;                       {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 $lib &amp;quot;i2c_usi.lbx&amp;quot;                                {{vbcomment|Für Hardware USI-I2C}}&lt;br /&gt;
 &lt;br /&gt;
 Config Scl = Portb.7                              {{vbcomment|Ports fuer IIC-Bus}}&lt;br /&gt;
 Config Sda = Portb.5&lt;br /&gt;
 {{vbcomment|Config I2cdelay &amp;amp;#061; 5                  ' je höher der Wert umso langsamer der Bus}}&lt;br /&gt;
 &lt;br /&gt;
 I2cinit&lt;br /&gt;
 &lt;br /&gt;
 Const Pcf_write = &amp;amp;H40                            {{vbcomment|Slaveadresse}}&lt;br /&gt;
 Const Pcf_read = &amp;amp;H41&lt;br /&gt;
  &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;I2C-USI Demo mit PCF 8574&amp;quot;&lt;br /&gt;
 Print&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;HAA&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
     I2cstart&lt;br /&gt;
     I2cwbyte Pcf_write&lt;br /&gt;
     I2cwbyte &amp;amp;H55&lt;br /&gt;
     I2cstop&lt;br /&gt;
 &lt;br /&gt;
     Print Err                                     {{vbcomment|Err &amp;amp;#061; 0 -&amp;gt; kein Fehler !}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 500&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
Mit ERR kann nach jedem gesendeten Byte abgefragt werden, ob es mit ACK quittiert wurde (=0), oder nicht (=1).&lt;br /&gt;
&lt;br /&gt;
Nach I2Cstart (auch I2CStop) kann ERR kontrolliert werden, ob das Start (bzw. Stop) auch auf den Bus abgesetzt werden konnte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beispiele für Hardware USI&lt;br /&gt;
* [[Bascom Soft-I2c Library]] - weitere Tipps zu I2C mit Bascom&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:08, 28. Okt 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:RN-Control_PCF8574.JPG&amp;diff=12849</id>
		<title>Datei:RN-Control PCF8574.JPG</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:RN-Control_PCF8574.JPG&amp;diff=12849"/>
				<updated>2007-10-27T23:46:20Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: RN-Control mit Zusatzboard, auf dem ein PCF8574 ist, das mit I2C Verbunden ist.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;RN-Control mit Zusatzboard, auf dem ein PCF8574 ist, das mit I2C Verbunden ist.&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Leiterplatten_Entwicklung_-_Programme&amp;diff=12803</id>
		<title>Leiterplatten Entwicklung - Programme</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Leiterplatten_Entwicklung_-_Programme&amp;diff=12803"/>
				<updated>2007-10-11T22:38:44Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: /* Siehe auch */  komischen Link entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorwort ==&lt;br /&gt;
Leiterplatten Entwicklung war früher ein, für den Hobbyanwender, recht mühsames unterfangen.&lt;br /&gt;
Entweder wurden die Leiterbahnen und &amp;quot;Pad's&amp;quot; direkt auf die Kupferschicht, mit einem ätzfesten Stift gezeichnet oder zunächst auf Folie/Papier gezeichnet und dann mittels Fototransfer auf die Platine übertragen.&lt;br /&gt;
&lt;br /&gt;
Heute stehen hierfür sehr umfangreiche aber dennoch mehr oder weniger leicht bedienbare Programme zur Verfügung, welche einen Entwurf von Leiterplatten erleichtern.&lt;br /&gt;
&lt;br /&gt;
Oft stehen verschiedene Versionen z.T. auch kostenlose Testversionen oder Versionen für den Hobby-Anwender zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Hier eine Liste von freien und kommerziellen Programmen welche es erlauben Leiterplatten mit dem Computer zu designen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
: '''Hier soll nicht der Umgang (Bedienungsanleitung) mit den beschriebenen Programmen sondern die Verfügbarkeit von verschiedenen Programmen und deren Usability im Vordergrund stehen.'''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Die wohl bekanntesten PCB Programme: ==&lt;br /&gt;
:* EAGLE&lt;br /&gt;
:* TARGET&lt;br /&gt;
:* Sprint-Layout&lt;br /&gt;
:* PCB-POOL®Edition&lt;br /&gt;
:* ORCAD&lt;br /&gt;
:* KiCAD&lt;br /&gt;
=== Weitere Programme ===&lt;br /&gt;
'''z.T. kommerzielle, limitierte, freie und z.T nicht mehr verfügbare Cad Programme'''&lt;br /&gt;
:* Protel &lt;br /&gt;
:: nicht mehr verfügbar (jetzt Altium)&lt;br /&gt;
:* Altium Designer&lt;br /&gt;
:* PROTEUS&lt;br /&gt;
:* ULTIBOARD&lt;br /&gt;
:* EASY PC&lt;br /&gt;
:* EDWIN&lt;br /&gt;
:* QUICK ROUTE&lt;br /&gt;
:* ARIADNE&lt;br /&gt;
:* AUTOENGINEER&lt;br /&gt;
:* BPECS32&lt;br /&gt;
:* CADSTAR&lt;br /&gt;
:* CADint&lt;br /&gt;
:* CIRCUIT LAYOUT&lt;br /&gt;
:* CIRCUIT CREATOR&lt;br /&gt;
:* CIRCAD&lt;br /&gt;
&lt;br /&gt;
Diese Liste kann noch weitergeführt werden, was allerdings leicht dazu führt den Überblick zu verlieren.&lt;br /&gt;
Diese Liste wird/kann im Laufe der Zeit mit Kommentaren und Erfahrungswerten versehen bzw. aktualisiert werden.&lt;br /&gt;
Auch Streichungen und Erweiterungen sind gestattet (bitte nicht übertreiben).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== AddOns für diese Programme ==&lt;br /&gt;
:* Eagle3D&lt;br /&gt;
:: ein kostenloses 3D Zusatzprogramm für Eagle&lt;br /&gt;
&lt;br /&gt;
== Bewertungen und Infos zu den gelisteten Programmen ==&lt;br /&gt;
''Info, Empfehlungen und Kritik zu den vorgestellten Programmen''&lt;br /&gt;
&lt;br /&gt;
::* EAGLE&lt;br /&gt;
::** Dieses Programm kann man hier im Roboternetz wohl als 1. Wahl bezeichnen, da die meisten Anwender hier hiermit arbeiten. Die kostenlose Version erlaubt Platinen bis zu 80mm x 100mm mit Schaltplan und Autorouter auf zwei Signal-Ebenen (Dual-Layer) zu erstellen. Auch eine sog. Studenten-Version (aber nicht nur diese) ist zu sehr guten Konditionen zu erwerben.&lt;br /&gt;
::** Nachdem die Einarbeitungsphase überwunden wurde, sehr gut zu bedienendes Tool.&lt;br /&gt;
::** Der Autorouter liefert (wie viele andere Programme auch) nur teilweise brauchbare Ergebnisse.&lt;br /&gt;
::** Gut ist die Verlinkung von Schaltplan und Board. Änderungen, die man im Schaltplan macht, werden automatisch auch in der Board-Ansicht vorgenommen. Dadurch bleiben Schaltplan und Board konsistent (funktioniert aber nur, wenn beide Ansichten geöffnet sind).&lt;br /&gt;
::* Eagle3D&lt;br /&gt;
::** bereits in der Entwurfsphase kann einem dieses Tool bei Design-Fehlern (LookOut) gute Dienste leisten&lt;br /&gt;
::** leider ist das erstellen von eigenen Bauteilen (noch) etwas aufwendig.&lt;br /&gt;
::** Auch eine Animation (Flug über die Platte) soll möglich sein ...&lt;br /&gt;
::** Sieht einfach klasse aus und macht auch Spaß damit zu 'Spielen'&lt;br /&gt;
::: '''INFO:''' Benötigt weitere Zusatzsoftware (auch als Freeware/GNU), mehr dazu auf der Homepage&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
'''Programme'''&lt;br /&gt;
* [http://www.cadsoft.de/ Eagle Homepage von CadSoft]&lt;br /&gt;
* [http://www.ibfriedrich.com/home.htm Target 3001 Homepage von Ing.-Büro FRIEDRICH]&lt;br /&gt;
* [http://www.abacom-online.de/html/demoversionen.html Sprint-Layout Homepage von ABACOM Ingenieurbüro GbR]&lt;br /&gt;
* [http://www.pcb-pool.de/html_de/de_service_1.htm free PCB-POOL Homepage von Beta LAYOUT GmbH]&lt;br /&gt;
* [http://www.altium.com/Products/AltiumDesigner/ AltiumDesigner Homepage von Altium Limited]&lt;br /&gt;
* [http://www.lis.inpg.fr/realise_au_lis/kicad/ KiCAD-Homepage]&lt;br /&gt;
'''AddOn's'''&lt;br /&gt;
* [http://www.matwei.de/doku.php?id=de:eagle3d:eagle3d Eagle3D Homepage von Matthias Weißer]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- unsichtbarer Kommentar: http://www.pcb-pool.de/html_de/de_service_1.htm --&amp;gt;&lt;br /&gt;
--[[Benutzer:Darwin.nuernberg|Darwin.nuernberg]] 12:39, 3. Feb 2007 (CET)&lt;br /&gt;
{{Ausbauwunsch|Was Euch noch dazu einfällt, Erfahrungen mit diesen Programmen usw., Kommentare}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Leiterplatten herstellen]]&lt;br /&gt;
* [[CAD]]&lt;br /&gt;
* [[PCB]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12683</id>
		<title>HEX-Datei</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12683"/>
				<updated>2007-09-02T12:07:36Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: keien Details in der Einleitung !&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die sogenannte '''Hex-Datei''' (auch Intel-Hex-Format) wird von einigen [[Compiler]]n als Ausgabedatei erzeugt (z.B. [[Bascom|Bascom Basic]]). Die HEX-Datei enthält das compilierte Programm in binärer Form und wird verwendet, wenn es in den [[Mikrocontroller]] übertragen werden soll.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll hauptsächlich auf die für die Mikrocontrollerprogrammierung (davon für [[AVR]]) wichtigen Infos eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Was hat es damit auf sich? ===&lt;br /&gt;
&lt;br /&gt;
* Wird von der Programmiersoftware verwendet zum Übertragen des Codes in den Controller (flashen)&lt;br /&gt;
* Hex steht als Abkürzung für Hexadezimal&lt;br /&gt;
* In der Datei kommen nur die druckbaren (ASCII-)Zeichen 0-9, A-F, : und Leerzeichen vor und könnte deshalb mit jedem Texteditor geöffnet und bearbeitet werden&lt;br /&gt;
* In jeder Zeile ist eine Prüfsumme angefügt zum einfachen Erkennen von Übertragungsfehlern&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Historisches ==&lt;br /&gt;
&lt;br /&gt;
Ein von Intel eingeführtes Dateiformat zum besseren Verarbeiten binärer Daten.&lt;br /&gt;
Ursprünglich War das Format wegen des 16Bit-Adressraumes bis max. 64 KByte Daten ausgelegt. Erst später wurde durch Hinzufügen weiterer ''[[#Datensatz-Typen|Datensatz-Typen]]'' der Adressraum erweitert.&lt;br /&gt;
Unter Anlehnung an die Struktur der Intel-CPUs wurden die zusätzlichen Datensatz-Typen für 20-Bit- und 32-Bit-Adressierung aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Da nur lesbare Zeichen zur Darstellung verwendet werden, können binäre Daten auf Bildschirm und Drucker ausgegeben werden, was bei Einführung dieses Formats (19xx, wenig bis garkeine el. Massenspeicher) noch von Bedeutung war.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Internes ==&lt;br /&gt;
&lt;br /&gt;
Wer eine Hex-Datei schon einmal mit einem Texteditor geöffnet hat, sieht eine Zeile wie diese:&lt;br /&gt;
&lt;br /&gt;
 :1000B000526F626F7465726E65747A2E646520206B&lt;br /&gt;
&lt;br /&gt;
Eine Zeile wird als Record (Datensatz) bezeichnet.&lt;br /&gt;
&lt;br /&gt;
Jedes Byte wird in hexadezimaler Schreibweise dargestellt.&lt;br /&gt;
&lt;br /&gt;
Bedeutung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Start || Anzahl || Adresse || Typ || Daten || Prüfsumme&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|:||10||00 B0||00||52 6F 62 6F 74 65 72 6E 65 74 7A 2E 64 65 20 20||6B&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start ===&lt;br /&gt;
&lt;br /&gt;
Es steht immer ein &amp;quot;:&amp;quot; (Doppelpunkt) am Zeilenanfang.&lt;br /&gt;
&lt;br /&gt;
=== Anzahl ===&lt;br /&gt;
&lt;br /&gt;
Gibt die Anzahl der effektiven Datenbytes an, kann von 0 - 255 (0x00 - 0xFF) Bytes enthalten&lt;br /&gt;
&lt;br /&gt;
=== Adresse  ===&lt;br /&gt;
&lt;br /&gt;
Adresse im 16-Bit Format an der die folgenden Daten gespeichert werden sollen. Mit 16 Bit können max. 64KByte an Daten Adressiert werden. Wer einen [[ATmega128]] (oder größer) voll ausnutzt, wird auch weitere Datensatztypen als üblich in der Hex-Datei finden.&lt;br /&gt;
&lt;br /&gt;
=== Datensatz-Typen ===&lt;br /&gt;
&lt;br /&gt;
==== 00 - Daten ====&lt;br /&gt;
:Ein Ausschnitt der Beispielzeile von oben:&lt;br /&gt;
&lt;br /&gt;
 :1000B0'''00'''52....6B&lt;br /&gt;
&lt;br /&gt;
:Die Zeile enthält 0x10 (dez 16) Bytes an Nutzdaten, diese sollen ab Adresse 0x00B0 (dez 176) gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==== 01 - letzte Zeile ====&lt;br /&gt;
:Die letzte Zeile sieht so aus:&lt;br /&gt;
&lt;br /&gt;
 :000000'''01'''FF&lt;br /&gt;
&lt;br /&gt;
:Danach folgt entweder das Dateiende, oder die Übertragung wird abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
==== 02 - erweiterte Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''02'''1000EC&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten den Adressraum von 64KByte überschreiten (ab [[ATmega128]]).&lt;br /&gt;
:Im Datenbereich wird der oberer Teil (Bits 4-19) einer 20-Bit-Adresse im 16-Bit-Format angegeben. Zu dieser muss dann die Offset-Adresse jeder Zeile hinzuaddiert werden, um die eigentliche Adresse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
==== 03 - Start Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''03'''20000000D9&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten an einer Adresse abgelegt werden sollen, der außerhalb eines 64KByte-Adressraums liegt.&lt;br /&gt;
:Im Datenbereich wird die Adresse im 2&amp;amp;times;16-Bit-Format (Segment und Adresse) angegeben. Ergibt eine 20-Bit Adresse. Ist für die Struktur der Intel-CPUs ausgelegt.&lt;br /&gt;
&lt;br /&gt;
==== 04 - erweiterte Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''04'''3000CA&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird der obere Teil (Bits 16-31) einer 32-Bit-Adresse im 16-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
==== 05 - Start Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''05'''00100000E7&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird die Adresse im 32-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
=== Daten/Info ===&lt;br /&gt;
&lt;br /&gt;
Die eigentlichen Daten, bzw. Infos je nach Datensatztyp, max. 255 Byte pro Zeile&lt;br /&gt;
&lt;br /&gt;
=== Prüfsumme ===&lt;br /&gt;
&lt;br /&gt;
In die Prüfsumme fließen alle Bytes der Zeile ein, incl. der Anzahl, Adresse und Typ, aber nicht die Startmarkierung.&lt;br /&gt;
&lt;br /&gt;
==== erzeugen ====&lt;br /&gt;
&lt;br /&gt;
:Zum Erzeugen der Prüfsumme werden alle Bytes der Zeile als Zweier-Komplement summiert, sieht mit den Daten der Beispielzeile in verständlicher Schreibweise so aus:&lt;br /&gt;
&lt;br /&gt;
 '''0x00''' - 0x10 - 0x00 - 0xB0 - 0x00 - 0x52 - 0x6F - 0x62 - 0x6F - 0x74 - 0x65 - 0x72 - 0x6E - &lt;br /&gt;
  0x65 - 0x74 - 0x7A - 0x2E - 0x64 - 0x65 - 0x20 - 0x20 = 0xF9'''6B'''&lt;br /&gt;
:Da nur das Low-Byte als Prüfsumme angegeben wird (Modulo-256-Summe), wird der Wert &amp;lt;tt&amp;gt;0x6B&amp;lt;/tt&amp;gt; angehängt.&lt;br /&gt;
&lt;br /&gt;
==== überprüfen ====&lt;br /&gt;
&lt;br /&gt;
:Zum Überprüfen der Daten muss die Summe aller Bytes, incl. der Prüfsumme, das (Modulo-256)-Ergebnis &amp;lt;tt&amp;gt;0x00&amp;lt;/tt&amp;gt; ergeben.&lt;br /&gt;
&lt;br /&gt;
:Die Beispielzeile wird so berechnet:&lt;br /&gt;
 0x10 + 0x00 + 0xB0 + 0x00 + 0x52 + 0x6F + 0x62 + 0x6F + 0x74 + 0x65 + 0x72 + 0x6E + &lt;br /&gt;
  0x65 + 0x74 + 0x7A + 0x2E + 0x64 + 0x65 + 0x20 + 0x20 + 0x'''6B''' = 0x7'''00'''&lt;br /&gt;
:Da nur das Low-Byte überprüft wird (Modulo-256), dieses hier &amp;lt;tt&amp;gt;0x00&amp;lt;/tt&amp;gt; ist, kann die Zeile als erfolgreich übertragen angesehen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anwendungen ==&lt;br /&gt;
Software zum Umgang mit Hex-Dateien:&lt;br /&gt;
&lt;br /&gt;
=== avr-objcopy ===&lt;br /&gt;
&lt;br /&gt;
Wer die Tools zur AVR-Programmierung installiert hat (unter Windose [[WinAVR]]), hat Zugriff auf das Consolen-Tool ''avr-objcopy''.&lt;br /&gt;
&lt;br /&gt;
Damit ist es möglich, diverse Dateiformate, u.a. Hex-Dateien, in andere Formate zu übertragen.&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Anweisung wird die Datei &amp;quot;test.bin&amp;quot;, welche im Format ''binary'' (&amp;lt;tt&amp;gt;-I&amp;lt;/tt&amp;gt;) vorliegt, im Format ''ihex'' (&amp;lt;tt&amp;gt;-O&amp;lt;/tt&amp;gt;) gespeichert, unter dem neuen Dateinamen &amp;quot;test.hex&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -O ihex -I binary test.bin test.hex&lt;br /&gt;
&lt;br /&gt;
In die andere Richtung geht das natürlich auch, (Hex-Datei in Binär-Datei übertragen):&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -I ihex -O binary test.hex test.bin&lt;br /&gt;
&lt;br /&gt;
Beim Compilieren eines C-Quellcodes wird dieses Tool üblicherweise über das [[Makefile]] aufgerufen, so dass die Hex-Datei bei &amp;quot;make all&amp;quot; automatisch erstellt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bascom-Programmer ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:BascomOptionsHexFile.jpg|thumb|Compiler/Output]]&lt;br /&gt;
Für das Bascom-interne Programmiertool ist die Hex-Datei nicht zwingend notwendig, da dies mit der Binärdatei auskommt. Falls aber eine andere Anwendung dafür eingesetzt werden muss, gibt es in den Optionen (unter Compiler/Output) ein Auswahlfeld, das beim Compilieren eine Hex-Datei erzeugen lässt (standardmäßig schon ausgewählt).&lt;br /&gt;
&lt;br /&gt;
Mit dem Bascom Programmiertool können vom AVR ausgelesene Daten als Binär- oder Hex-Datei gespeichert werden. &amp;lt;small&amp;gt;(Das scheint aber z.Zt. einen kleinen Bug zu haben, denn ab 64KByte stimmt die Adresse nicht mehr :-)&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Programmer]]&lt;br /&gt;
* [[HEX Beispiel-Dateien für AVR]]&lt;br /&gt;
* [[Bascom - Erstes Programm in den AVR Controller übertragen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quellen ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.google.de/search?hl=de&amp;amp;q=intelhex] u.a. :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12659</id>
		<title>HEX-Datei</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12659"/>
				<updated>2007-08-27T01:09:24Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: /* 00 - Daten */  typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die sogenannte Hex-Datei (auch Intel-Hex-Format) wird üblicherweise beim compilieren eines Quellcodes (z.B. [[C-Tutorial|C]] oder [[Bascom|Bascom Basic]]) für einen Mikrocontroller erzeugt.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll Hauptsächlich auf die für die Mikrocontrollerprogrammierung (davon für AVR) wichtigen Infos eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Was hat es damit auf sich ? ===&lt;br /&gt;
&lt;br /&gt;
* Wird von der Programmiersoftware verwendet zum übertragen des Codes in den Controller (flashen)&lt;br /&gt;
* Hex steht als Abkürzung für Hexadezimal&lt;br /&gt;
* In der Datei kommen nur druckbare (ASCII-)Zeichen vor (0-9, A-F), und könnte deshalb mit jedem Texteditor geöffnet und bearbeitet werden&lt;br /&gt;
* In jeder Zeile ist eine Prüfsumme angefügt zum einfachen erkennen von Übertragungsfehlern&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Historisches ==&lt;br /&gt;
&lt;br /&gt;
Ein von Intel eingeführtes Dateiformat zum besseren verarbeiten binärer Daten.&lt;br /&gt;
Ursprünglich, wegen der 16Bit-Adressangabe, bis max. 64KByte Daten ausgelegt. Erst später wurde durch hinzufügen weiterer ''[[#Datensatz-Typen|Datensatz-Typen]]'' der Adressraum erweitert.&lt;br /&gt;
Unter Anlehnung an die Struktur der Intel-CPUs wurden die zusätzlichen Datensatz-Typen aufgebaut (20-Bit- und 32-Bit-Adressierung).&lt;br /&gt;
&lt;br /&gt;
Durch die Verwendung der hexadezimalen Schreibweise können binäre Daten auf Bildschirm und Drucker ausgegeben werden da nur lesbare Zeichen vorkommen, was bei Einführung dieses Formats (19xx, wenig bis garkeine el. Massenspeicher) noch von Bedeutung war.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Internes ==&lt;br /&gt;
&lt;br /&gt;
Wer eine Hex-Datei schon einmal mit einem Texteditor geöffnet hat, sieht eine Zeile wie diese:&lt;br /&gt;
&lt;br /&gt;
 :1000B000526F626F7465726E65747A2E646520206B&lt;br /&gt;
&lt;br /&gt;
Eine Zeile wird als Record (Datensatz) bezeichnet.&lt;br /&gt;
&lt;br /&gt;
Jedes Byte wird in hexadezimaler Schreibweise dargestellt.&lt;br /&gt;
&lt;br /&gt;
Bedeutung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Start || Anzahl || Adresse || Typ || Daten || Prüfsumme&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|:||10||00 B0||00||52 6F 62 6F 74 65 72 6E 65 74 7A 2E 64 65 20 20||6B&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start ===&lt;br /&gt;
&lt;br /&gt;
Immer ein &amp;quot;:&amp;quot; (Doppelpunkt) am Zeilenanfang.&lt;br /&gt;
&lt;br /&gt;
=== Anzahl ===&lt;br /&gt;
&lt;br /&gt;
Gibt die Anzahl der effektiven Datenbytes an, kann von 0 - 255 (0x00 - 0xFF) Bytes enthalten&lt;br /&gt;
&lt;br /&gt;
=== Adresse  ===&lt;br /&gt;
&lt;br /&gt;
Adresse im 16-Bit Format an der die folgenden Daten gespeichert werden sollen. Mit 16 Bit können max. 64KByte an Daten Adressiert werden. Wer einen Mega128 (oder größer) voll ausnutzt, wird auch weitere Datensatztypen als üblich in der Hex-Datei finden.&lt;br /&gt;
&lt;br /&gt;
=== Datensatz-Typen ===&lt;br /&gt;
&lt;br /&gt;
==== 00 - Daten ====&lt;br /&gt;
:Ein Ausschnitt der Beispielzeile von oben:&lt;br /&gt;
&lt;br /&gt;
 :1000B0'''00'''52....6B&lt;br /&gt;
&lt;br /&gt;
:Die Zeile enthält 0x10 (dez 16) Bytes an Nutzdaten, diese sollen ab Adresse 0x00B0 (dez 176) gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==== 01 - letzte Zeile ====&lt;br /&gt;
:Die letzte Zeile sieht so aus:&lt;br /&gt;
&lt;br /&gt;
 :000000'''01'''FF&lt;br /&gt;
&lt;br /&gt;
:Danach folgt entweder das Dateiende, oder die Übertragung wird abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
==== 02 - erweiterte Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''02'''1000EC&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten den Adressraum von 64KByte überschreiten (Ab [[ATmega128|ATMega128]]).&lt;br /&gt;
:Im Datenbereich wird der oberer Teil (Bits 4 - 19) einer 20-Bit-Adresse im 16-Bit-Format angegeben. Zu dieser muss dann die Offset-Adresse jeder Zeile hinzuaddiert werden, um die eigentliche Adresse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
==== 03 - Start Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''03'''20000000D9&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten an einer Adresse abgelegt werden sollen, der außerhalb eines 64KByte-Adressraums liegt.&lt;br /&gt;
:Im Datenbereich wird die Adresse im 2x16-Bit-Format (Segment und Adresse) angegeben. Ergibt eine 20-Bit Adresse. Ist für die Struktur der Intel-CPUs ausgelegt.&lt;br /&gt;
&lt;br /&gt;
==== 04 - erweiterte Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''04'''3000CA&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird der obere Teil (Bits 16-31) einer 32-Bit-Adresse im 16-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
==== 05 - Start Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''05'''00100000E7&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird die Adresse im 32-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
=== Daten/Info ===&lt;br /&gt;
&lt;br /&gt;
:Die eigentlichen Daten, bzw. Infos je nach Datensatztyp, max. 255 Byte pro Zeile&lt;br /&gt;
&lt;br /&gt;
=== Prüfsumme ===&lt;br /&gt;
&lt;br /&gt;
In die Prüfsumme fließen alle Bytes der Zeile ein, incl. der Anzahl, Adresse und Typ, aber nicht die Startmarkierung.&lt;br /&gt;
&lt;br /&gt;
==== erzeugen ====&lt;br /&gt;
&lt;br /&gt;
:Zum erzeugen der Prüfsumme werden alle Bytes der Zeile als Zweier-Komplement summiert, sieht mit den Daten der Beispielzeile in verständlicher Schreibweise so aus:&lt;br /&gt;
&lt;br /&gt;
 '''0x00''' - 0x10 - 0x00 - 0xB0 - 0x00 - 0x52 - 0x6F - 0x62 - 0x6F - 0x74 - 0x65 - 0x72 - 0x6E - &lt;br /&gt;
  0x65 - 0x74 - 0x7A - 0x2E - 0x64 - 0x65 - 0x20 - 0x20 = 0xF9'''6B'''&lt;br /&gt;
:Da nur das Low-Byte als Prüfsumme angegeben wird (Modulo-256-Summe), wird der Wert 0x6B angehängt.&lt;br /&gt;
&lt;br /&gt;
==== überprüfen ====&lt;br /&gt;
&lt;br /&gt;
:Zum überprüfen der Daten muss die Summe aller Bytes, incl. der Prüfsumme, das (Modulo-256)-Ergebnis 0x00 ergeben.&lt;br /&gt;
&lt;br /&gt;
:Die Beispielzeile wird so berechnet:&lt;br /&gt;
 0x10 + 0x00 + 0xB0 + 0x00 + 0x52 + 0x6F + 0x62 + 0x6F + 0x74 + 0x65 + 0x72 + 0x6E + &lt;br /&gt;
  0x65 + 0x74 + 0x7A + 0x2E + 0x64 + 0x65 + 0x20 + 0x20 + 0x'''6B''' = 0x7'''00'''&lt;br /&gt;
:Da nur das Low-Byte überprüft wird (Modulo-256), dieses hier 0x00 ist, kann die Zeile als erfolgreich übertragen angesehen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anwendungen ==&lt;br /&gt;
Software zum Umgang mit Hex-Dateien:&lt;br /&gt;
&lt;br /&gt;
=== avr-objcopy ===&lt;br /&gt;
&lt;br /&gt;
Wer die Tools zur AVR-Programmierung installiert hat (unter Windose WinAVR), hat zugriff auf das Consolen-Tool ''avr-objcopy''.&lt;br /&gt;
&lt;br /&gt;
Damit ist es möglich diverse Dateiformat, u.a. Hex-Dateien, in andere Formate zu übertragen.&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Anweisung wird die Datei &amp;quot;test.bin&amp;quot;, welche im Format ''binary'' (-I) vorliegt, im Format ''ihex'' (-O) gespeichert, unter dem neuen Dateinamen &amp;quot;test.hex&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -O ihex -I binary test.bin test.hex&lt;br /&gt;
&lt;br /&gt;
In die andere Richtung geht das natürlich auch, (Hex-Datei in Binär-Datei übertragen):&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -I ihex -O binary test.hex test.bin&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beim Compilieren eines C-Quellcodes wird dieses Tool über das ''makefile'' aufgerufen, sodass die Hex-Datei bei &amp;quot;make all&amp;quot; automatisch erstellt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bascom-Programmer ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:BascomOptionsHexFile.jpg|thumb|Compiler/Output]]&lt;br /&gt;
Für das Bascom interne Programmiertool ist die Hex-Datei nicht zwingend notwendig, da dies mit der Binärdatei auskommt. Falls aber eine andere Anwendung dafür eingesetzt werden muss, gibt es in den Optionen (unter Compiler/Output) ein Auswahlfeld, das beim compilieren eine Hex-Datei erzeugen lässt (Standardmäßig schon ausgewählt).&lt;br /&gt;
&lt;br /&gt;
Mit dem Bascom Programmiertool können vom AVR ausgelesene Daten als Binär- oder Hex-Datei gespeichert werden. &amp;lt;small&amp;gt;(Das scheint aber z.Zt. einen kleinen Bug zu haben, denn ab 64KByte stimmt die Adresse nicht mehr :-)&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Programmer]]&lt;br /&gt;
* [[HEX_Beispiel-Dateien_f%C3%BCr_AVR]]&lt;br /&gt;
* [[Bascom_-_Erstes_Programm_in_den_AVR_Controller_%C3%BCbertragen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quellen ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.google.de/search?hl=de&amp;amp;q=intelhex] u.a. :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12658</id>
		<title>HEX-Datei</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=HEX-Datei&amp;diff=12658"/>
				<updated>2007-08-27T01:05:48Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Neu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die sogenannte Hex-Datei (auch Intel-Hex-Format) wird üblicherweise beim compilieren eines Quellcodes (z.B. [[C-Tutorial|C]] oder [[Bascom|Bascom Basic]]) für einen Mikrocontroller erzeugt.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll Hauptsächlich auf die für die Mikrocontrollerprogrammierung (davon für AVR) wichtigen Infos eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Was hat es damit auf sich ? ===&lt;br /&gt;
&lt;br /&gt;
* Wird von der Programmiersoftware verwendet zum übertragen des Codes in den Controller (flashen)&lt;br /&gt;
* Hex steht als Abkürzung für Hexadezimal&lt;br /&gt;
* In der Datei kommen nur druckbare (ASCII-)Zeichen vor (0-9, A-F), und könnte deshalb mit jedem Texteditor geöffnet und bearbeitet werden&lt;br /&gt;
* In jeder Zeile ist eine Prüfsumme angefügt zum einfachen erkennen von Übertragungsfehlern&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Historisches ==&lt;br /&gt;
&lt;br /&gt;
Ein von Intel eingeführtes Dateiformat zum besseren verarbeiten binärer Daten.&lt;br /&gt;
Ursprünglich, wegen der 16Bit-Adressangabe, bis max. 64KByte Daten ausgelegt. Erst später wurde durch hinzufügen weiterer ''[[#Datensatz-Typen|Datensatz-Typen]]'' der Adressraum erweitert.&lt;br /&gt;
Unter Anlehnung an die Struktur der Intel-CPUs wurden die zusätzlichen Datensatz-Typen aufgebaut (20-Bit- und 32-Bit-Adressierung).&lt;br /&gt;
&lt;br /&gt;
Durch die Verwendung der hexadezimalen Schreibweise können binäre Daten auf Bildschirm und Drucker ausgegeben werden da nur lesbare Zeichen vorkommen, was bei Einführung dieses Formats (19xx, wenig bis garkeine el. Massenspeicher) noch von Bedeutung war.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Internes ==&lt;br /&gt;
&lt;br /&gt;
Wer eine Hex-Datei schon einmal mit einem Texteditor geöffnet hat, sieht eine Zeile wie diese:&lt;br /&gt;
&lt;br /&gt;
 :1000B000526F626F7465726E65747A2E646520206B&lt;br /&gt;
&lt;br /&gt;
Eine Zeile wird als Record (Datensatz) bezeichnet.&lt;br /&gt;
&lt;br /&gt;
Jedes Byte wird in hexadezimaler Schreibweise dargestellt.&lt;br /&gt;
&lt;br /&gt;
Bedeutung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Start || Anzahl || Adresse || Typ || Daten || Prüfsumme&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|:||10||00 B0||00||52 6F 62 6F 74 65 72 6E 65 74 7A 2E 64 65 20 20||6B&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Start ===&lt;br /&gt;
&lt;br /&gt;
Immer ein &amp;quot;:&amp;quot; (Doppelpunkt) am Zeilenanfang.&lt;br /&gt;
&lt;br /&gt;
=== Anzahl ===&lt;br /&gt;
&lt;br /&gt;
Gibt die Anzahl der effektiven Datenbytes an, kann von 0 - 255 (0x00 - 0xFF) Bytes enthalten&lt;br /&gt;
&lt;br /&gt;
=== Adresse  ===&lt;br /&gt;
&lt;br /&gt;
Adresse im 16-Bit Format an der die folgenden Daten gespeichert werden sollen. Mit 16 Bit können max. 64KByte an Daten Adressiert werden. Wer einen Mega128 (oder größer) voll ausnutzt, wird auch weitere Datensatztypen als üblich in der Hex-Datei finden.&lt;br /&gt;
&lt;br /&gt;
=== Datensatz-Typen ===&lt;br /&gt;
&lt;br /&gt;
==== 00 - Daten ====&lt;br /&gt;
:Ein Auschnitt der Beispielzeile von oben:&lt;br /&gt;
&lt;br /&gt;
 :1000B0'''00'''52....6B&lt;br /&gt;
&lt;br /&gt;
:Die Zeile enthalt 0x10 (dez 16) Bytes an Nutzdaten, diese sollen ab Adresse 0x00B0 (dez 176) gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
==== 01 - letzte Zeile ====&lt;br /&gt;
:Die letzte Zeile sieht so aus:&lt;br /&gt;
&lt;br /&gt;
 :000000'''01'''FF&lt;br /&gt;
&lt;br /&gt;
:Danach folgt entweder das Dateiende, oder die Übertragung wird abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
==== 02 - erweiterte Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''02'''1000EC&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten den Adressraum von 64KByte überschreiten (Ab [[ATmega128|ATMega128]]).&lt;br /&gt;
:Im Datenbereich wird der oberer Teil (Bits 4 - 19) einer 20-Bit-Adresse im 16-Bit-Format angegeben. Zu dieser muss dann die Offset-Adresse jeder Zeile hinzuaddiert werden, um die eigentliche Adresse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
==== 03 - Start Segment-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Segment-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''03'''20000000D9&lt;br /&gt;
&lt;br /&gt;
:Sie wird benötigt, wenn die Daten an einer Adresse abgelegt werden sollen, der außerhalb eines 64KByte-Adressraums liegt.&lt;br /&gt;
:Im Datenbereich wird die Adresse im 2x16-Bit-Format (Segment und Adresse) angegeben. Ergibt eine 20-Bit Adresse. Ist für die Struktur der Intel-CPUs ausgelegt.&lt;br /&gt;
&lt;br /&gt;
==== 04 - erweiterte Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;erweiterte Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :020000'''04'''3000CA&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird der obere Teil (Bits 16-31) einer 32-Bit-Adresse im 16-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
==== 05 - Start Linear-Adresse ====&lt;br /&gt;
:Eine &amp;quot;Start Linear-Adress&amp;quot;-Zeile kann so aussehen:&lt;br /&gt;
&lt;br /&gt;
 :040000'''05'''00100000E7&lt;br /&gt;
&lt;br /&gt;
:Im Datenbereich wird die Adresse im 32-Bit-Format angegeben.&lt;br /&gt;
&lt;br /&gt;
=== Daten/Info ===&lt;br /&gt;
&lt;br /&gt;
:Die eigentlichen Daten, bzw. Infos je nach Datensatztyp, max. 255 Byte pro Zeile&lt;br /&gt;
&lt;br /&gt;
=== Prüfsumme ===&lt;br /&gt;
&lt;br /&gt;
In die Prüfsumme fließen alle Bytes der Zeile ein, incl. der Anzahl, Adresse und Typ, aber nicht die Startmarkierung.&lt;br /&gt;
&lt;br /&gt;
==== erzeugen ====&lt;br /&gt;
&lt;br /&gt;
:Zum erzeugen der Prüfsumme werden alle Bytes der Zeile als Zweier-Komplement summiert, sieht mit den Daten der Beispielzeile in verständlicher Schreibweise so aus:&lt;br /&gt;
&lt;br /&gt;
 '''0x00''' - 0x10 - 0x00 - 0xB0 - 0x00 - 0x52 - 0x6F - 0x62 - 0x6F - 0x74 - 0x65 - 0x72 - 0x6E - &lt;br /&gt;
  0x65 - 0x74 - 0x7A - 0x2E - 0x64 - 0x65 - 0x20 - 0x20 = 0xF9'''6B'''&lt;br /&gt;
:Da nur das Low-Byte als Prüfsumme angegeben wird (Modulo-256-Summe), wird der Wert 0x6B angehängt.&lt;br /&gt;
&lt;br /&gt;
==== überprüfen ====&lt;br /&gt;
&lt;br /&gt;
:Zum überprüfen der Daten muss die Summe aller Bytes, incl. der Prüfsumme, das (Modulo-256)-Ergebnis 0x00 ergeben.&lt;br /&gt;
&lt;br /&gt;
:Die Beispielzeile wird so berechnet:&lt;br /&gt;
 0x10 + 0x00 + 0xB0 + 0x00 + 0x52 + 0x6F + 0x62 + 0x6F + 0x74 + 0x65 + 0x72 + 0x6E + &lt;br /&gt;
  0x65 + 0x74 + 0x7A + 0x2E + 0x64 + 0x65 + 0x20 + 0x20 + 0x'''6B''' = 0x7'''00'''&lt;br /&gt;
:Da nur das Low-Byte überprüft wird (Modulo-256), dieses hier 0x00 ist, kann die Zeile als erfolgreich übertragen angesehen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Anwendungen ==&lt;br /&gt;
Software zum Umgang mit Hex-Dateien:&lt;br /&gt;
&lt;br /&gt;
=== avr-objcopy ===&lt;br /&gt;
&lt;br /&gt;
Wer die Tools zur AVR-Programmierung installiert hat (unter Windose WinAVR), hat zugriff auf das Consolen-Tool ''avr-objcopy''.&lt;br /&gt;
&lt;br /&gt;
Damit ist es möglich diverse Dateiformat, u.a. Hex-Dateien, in andere Formate zu übertragen.&lt;br /&gt;
&lt;br /&gt;
Mit der folgenden Anweisung wird die Datei &amp;quot;test.bin&amp;quot;, welche im Format ''binary'' (-I) vorliegt, im Format ''ihex'' (-O) gespeichert, unter dem neuen Dateinamen &amp;quot;test.hex&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -O ihex -I binary test.bin test.hex&lt;br /&gt;
&lt;br /&gt;
In die andere Richtung geht das natürlich auch, (Hex-Datei in Binär-Datei übertragen):&lt;br /&gt;
&lt;br /&gt;
 avr-objcopy -I ihex -O binary test.hex test.bin&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beim Compilieren eines C-Quellcodes wird dieses Tool über das ''makefile'' aufgerufen, sodass die Hex-Datei bei &amp;quot;make all&amp;quot; automatisch erstellt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bascom-Programmer ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:BascomOptionsHexFile.jpg|thumb|Compiler/Output]]&lt;br /&gt;
Für das Bascom interne Programmiertool ist die Hex-Datei nicht zwingend notwendig, da dies mit der Binärdatei auskommt. Falls aber eine andere Anwendung dafür eingesetzt werden muss, gibt es in den Optionen (unter Compiler/Output) ein Auswahlfeld, das beim compilieren eine Hex-Datei erzeugen lässt (Standardmäßig schon ausgewählt).&lt;br /&gt;
&lt;br /&gt;
Mit dem Bascom Programmiertool können vom AVR ausgelesene Daten als Binär- oder Hex-Datei gespeichert werden. &amp;lt;small&amp;gt;(Das scheint aber z.Zt. einen kleinen Bug zu haben, denn ab 64KByte stimmt die Adresse nicht mehr :-)&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Programmer]]&lt;br /&gt;
* [[HEX_Beispiel-Dateien_f%C3%BCr_AVR]]&lt;br /&gt;
* [[Bascom_-_Erstes_Programm_in_den_AVR_Controller_%C3%BCbertragen]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Quellen ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.google.de/search?hl=de&amp;amp;q=intelhex] u.a. :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:BascomOptionsHexFile.jpg&amp;diff=12657</id>
		<title>Datei:BascomOptionsHexFile.jpg</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:BascomOptionsHexFile.jpg&amp;diff=12657"/>
				<updated>2007-08-26T22:35:32Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Bascom Optionen, zeigt Einstellungen zum Compiler-Output&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bascom Optionen, zeigt Einstellungen zum Compiler-Output&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12014</id>
		<title>TWI Praxis</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=12014"/>
				<updated>2007-05-17T14:08:21Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: /* Transmit und Receive */  typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das TWI-Hardwaremodul der AVRs zu verwenden.&lt;br /&gt;
Näheres zu [[TWI]] und [[I2C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
Die Beispiele sind zwar in Bascom Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Übertragungsarten =&lt;br /&gt;
&lt;br /&gt;
Bei TWI gibt es die folgenden Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Master =&lt;br /&gt;
[[Bild:I2C_PCF8574_RN-Control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' zuständig. Mit der Formel auf der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' Seite müssen sie den Wert für das Register ''TWBR'' berechnen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Transmitter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Call Twi_send_byte(&amp;amp;H40 , B)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI send_byte}}&lt;br /&gt;
 {{vbcomment|sendet ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave And &amp;amp;HFE                               {{vbcomment|slave adresse + Write}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H20 Then&lt;br /&gt;
             Twdr = Zeichen                                  {{vbcomment|Daten}}&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Zeichen wurden gesendet}}&lt;br /&gt;
             If Twi_status = &amp;amp;H28 Or Twi_status = &amp;amp;H30 Then&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Function Twi_read_byte(byval Slave As Byte) As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim X As Byte                                               {{vbcomment|Zeichen von TWI}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI Init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Receiver&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt (egal welcher Wert, wird nur als Startbutton genutzt)}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|ein Byte vom Slave holen}}&lt;br /&gt;
     X = Twi_read_byte(&amp;amp;H40)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print X ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI read_byte}}&lt;br /&gt;
 {{vbcomment|holt ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Function Twi_read_byte(slave As Byte) As Byte&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     Twi_read_byte = 0                                       {{vbcomment|Wert vorbelegen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave Or &amp;amp;H01                                {{vbcomment|slave adresse + Read}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H40 Then&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                           {{vbcomment|kein ACK (TWEA &amp;amp;#61; 0) senden, weil wir nur ein Byte lesen wollen}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
             If Twi_status = &amp;amp;H58 Or Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                 Twi_read_byte = Twdr                        {{vbcomment|Daten lesen}}&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Function&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
=== Transmit und Receive ===&lt;br /&gt;
[[Bild:RN-M8_TWI_DS1621_PCF8574.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
;Senden und Empfangen&lt;br /&gt;
Der Master (Mega8) stößt die Temperaturmessung des DS1621 an, liest die Temperatur aus, sendet den Temperaturwert anschließend an einen PCF8574 zur Anzeige an dessen LEDs.&lt;br /&gt;
&lt;br /&gt;
Zur Kontrolle werden die Daten auch per UART übertragen und an den LEDs des RN-Meaga8 angezeigt.&lt;br /&gt;
&lt;br /&gt;
Während der Übertragung wird die Busgeschwindigkeit geändert, da der DS1621 mit 400kHz kommunizieren kann, der PCF8574 nur mit 100kHz.&lt;br /&gt;
&lt;br /&gt;
Dieses Programm wird auch zum testen im Artikel [[Bascom und USI-Kommunikation]] verwendet, dort ist dann ein [[ATtiny2313|ATTiny2313]] einer der Slaves.&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Daten vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M8def.dat&amp;quot;                            {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                      {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                           {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_errorstate As Byte                        {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Anzahlbuf As Byte                             {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                   {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                     {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Config Portb.0 = Output&lt;br /&gt;
 Config Portb.1 = Output&lt;br /&gt;
 Config Portd = Output&lt;br /&gt;
 &lt;br /&gt;
 Const Device = &amp;amp;H90&lt;br /&gt;
 Const Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI initialisieren}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                 {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                          {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                         {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                        {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Sound Portb.0 , 300 , 450                         {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;TWI Master DS1621 Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Portb.0 = 1                                       {{vbcomment|Damit die LED ausgeht nach dem Beep}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
     Twbr = 12                                     {{vbcomment|Bit Rate Register 400kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                        {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                          {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate = 0 Then                    {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         Waitms 1                                  {{vbcomment|Etwas warten bis die Temperatur gemessen ist}}&lt;br /&gt;
         Messagebuf(1) = Device                    {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                      {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate = 0 Then                {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread            {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Twi_errorstate = 0 Then            {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
                 {{vbcomment|STOP senden}}&lt;br /&gt;
                 Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Wert an den LEDs anzeigen}}&lt;br /&gt;
                 Portd.7 = Not Lowtemp.5&lt;br /&gt;
                 Portd.6 = Not Lowtemp.4&lt;br /&gt;
                 Portd.5 = Not Lowtemp.3&lt;br /&gt;
                 Portd.4 = Not Lowtemp.2&lt;br /&gt;
                 Portd.3 = Not Lowtemp.1&lt;br /&gt;
                 Portd.2 = Not Lowtemp.0&lt;br /&gt;
                 Portb.1 = Not Hightemp.7&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate &amp;lt;&amp;gt; 0 Then                   {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
     Else&lt;br /&gt;
         Twbr = 72                                 {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Einem evtl. angeschlossenem PCF8574 den Temperaturwert senden}}&lt;br /&gt;
         Messagebuf(1) = &amp;amp;H40&lt;br /&gt;
         Messagebuf(2) = Not Lowtemp&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate &amp;lt;&amp;gt; 0 Then               {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
             Print &amp;quot;Error2 &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 2&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 {{vbcomment|TWI Transmit and receive function.}}&lt;br /&gt;
 Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                             {{vbcomment|TWINT, TWSTA, TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
 &lt;br /&gt;
         Rw = Messagebuf(1).0                      {{vbcomment|RW-Flag holen für Abfrage unten}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
         For Cnt = 1 To Anzahlbuf&lt;br /&gt;
             {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
             {{vbcomment|Print Cnt ; &amp;quot; &amp;quot; ; Messagebuf(cnt) ; &amp;quot; &amp;quot; ; Rw}}&lt;br /&gt;
             If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
                 {{vbcomment|Write Slaveadr}}&lt;br /&gt;
                 Twdr = Messagebuf(cnt)&lt;br /&gt;
                 Twcr = &amp;amp;B10000100                 {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Beim 1. Byte wird ein anderer Status erwartet}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     {{vbcomment|Slave hat sich gemeldet, $20 ist NACK, $18 WriteACK, $40 ReadACK !}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H40 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         {{vbcomment|kein Slave}}&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Zeichen wurde gesendet, $30 ist NACK}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H28 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             Else&lt;br /&gt;
                 {{vbcomment|Read a Byte}}&lt;br /&gt;
                 {{vbcomment|Wenn das letzte Byte gesendet wird, ein NACK mitgeben um das Ende anzuzeigen}}&lt;br /&gt;
                 If Cnt = Anzahlbuf Then&lt;br /&gt;
                     {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
                     Twcr = &amp;amp;B10000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Load ACK. TWEA ist 1}}&lt;br /&gt;
                     Twcr = &amp;amp;B11000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
                 Messagebuf(cnt) = Twdr            {{vbcomment|Daten lesen}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Byte empfangen und mit ACK quittiert, sonst Ende}}&lt;br /&gt;
                 If Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                     Twi_errorstate = 0            {{vbcomment|kein Fehler}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Beim letzten Byte auch mit NACK quittieren}}&lt;br /&gt;
                     If Cnt = Anzahlbuf And Twi_status = &amp;amp;H58 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         Next Cnt&lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Ist der Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                         {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Twi_errorstate = Twi_status               {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Stopsequenz ausgeben}}&lt;br /&gt;
 Twi_stop:&lt;br /&gt;
     Twcr = &amp;amp;B10010100                             {{vbcomment|TWINT löschen, Stop senden}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Warten bis Stop-Flag wieder gelöscht wird, dann ist die Stopsequenz abgeschlossen}}&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H10&lt;br /&gt;
     Loop Until Twi_control = 0&lt;br /&gt;
     {{vbcomment|Es muss nicht unbedingt darauf gewartet werden}}&lt;br /&gt;
     {{vbcomment|wenn die nächste Aktion nicht gleich anschliessend durchgeführt wird.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Einen speziellen STOP-Status gibt es nicht, es ist in der Regel &amp;amp;HF8}}&lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|Print Hex(twi_status)}}&lt;br /&gt;
 &lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
= Slave =&lt;br /&gt;
[[Bild:I2C_RN-M8_RN-control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Da der TWI-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave das [[RN-Mega8]] Board verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Count As Byte                                           {{vbcomment|Testwert, jedes mal +1}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Werte zurücksetzen}}&lt;br /&gt;
 Count = 0&lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|will der Master ein Byte haben}}&lt;br /&gt;
         If Twi_status = &amp;amp;HA8 Or Twi_status = &amp;amp;HB8 Then&lt;br /&gt;
             Twdr = Count                                    {{vbcomment|neue Daten ausgeben}}&lt;br /&gt;
             Incr Count                                      {{vbcomment|testwert +1}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, mit ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortD aus, an dem beim RN-M8 eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Config Portd = Output                                       {{vbcomment|kompletter PortD als Ausgang}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Neuesbyte As Byte                                       {{vbcomment|Bytemerker}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|alle LEDs ein}}&lt;br /&gt;
 Portd = 0&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Merker zurücksetzen}}&lt;br /&gt;
     Neuesbyte = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|wurde ein Byte geschickt}}&lt;br /&gt;
         If Twi_status = &amp;amp;H80 Or Twi_status = &amp;amp;H88 Then&lt;br /&gt;
             Twi_data = Twdr                                 {{vbcomment|neue Daten merken}}&lt;br /&gt;
             Neuesbyte = 1                                   {{vbcomment|merken das ein neues Byte da ist}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, erzeugt ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn ein neues Byte gekommen ist, dieses an PortD ausgeben}}&lt;br /&gt;
     If Neuesbyte &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
         Portd = Twi_data                                    {{vbcomment|Daten auf PortD ausgeben}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Der Slave ist hier sogar in der Lage während einer Übertragung mehr als ein Byte entgegenzunehmen, da jedes Byte den gleichen Status erzeugt.&lt;br /&gt;
&lt;br /&gt;
Wenn der Slave schnell genug getaktet wird (&amp;gt; 6.4 MHz), kann der Master auch auf einen schnelleren Bus-Takt gestellt werden. Dazu beim Master das ''TWBR'' auf 12 setzen, so wird der Bus mit 400kHz betrieben.&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]]&lt;br /&gt;
* [[TWI Praxis Multimaster]]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=246777#246777] - etwas ausführlicheres Slave-Beipiel im Forum&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - I2C Beispiele mit Bascom und dem USI-Modul&lt;br /&gt;
&lt;br /&gt;
= WebLinks =&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs C-Quellbibliothek für einen TWI-Master von Peter Fleury (avr-gcc)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 15:31, 15. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=10473</id>
		<title>TWI Praxis</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=10473"/>
				<updated>2007-03-23T19:19:29Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Link zum Forum unter *Siehe auch*&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das TWI-Hardwaremodul der AVRs zu verwenden.&lt;br /&gt;
Näheres zu [[TWI]] und [[I2C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
Die Beispiele sind zwar in Bascom Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Übertragungsarten =&lt;br /&gt;
&lt;br /&gt;
Bei TWI gibt es die folgenden Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Master =&lt;br /&gt;
[[Bild:I2C_PCF8574_RN-Control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' zuständig. Mit der Formel auf der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' Seite müssen sie den Wert für das Register ''TWBR'' berechnen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Transmitter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Call Twi_send_byte(&amp;amp;H40 , B)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI send_byte}}&lt;br /&gt;
 {{vbcomment|sendet ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave And &amp;amp;HFE                               {{vbcomment|slave adresse + Write}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H20 Then&lt;br /&gt;
             Twdr = Zeichen                                  {{vbcomment|Daten}}&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Zeichen wurden gesendet}}&lt;br /&gt;
             If Twi_status = &amp;amp;H28 Or Twi_status = &amp;amp;H30 Then&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Function Twi_read_byte(byval Slave As Byte) As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim X As Byte                                               {{vbcomment|Zeichen von TWI}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI Init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Receiver&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt (egal welcher Wert, wird nur als Startbutton genutzt)}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|ein Byte vom Slave holen}}&lt;br /&gt;
     X = Twi_read_byte(&amp;amp;H40)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print X ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI read_byte}}&lt;br /&gt;
 {{vbcomment|holt ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Function Twi_read_byte(slave As Byte) As Byte&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     Twi_read_byte = 0                                       {{vbcomment|Wert vorbelegen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave Or &amp;amp;H01                                {{vbcomment|slave adresse + Read}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H40 Then&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                           {{vbcomment|kein ACK (TWEA &amp;amp;#61; 0) senden, weil wir nur ein Byte lesen wollen}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
             If Twi_status = &amp;amp;H58 Or Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                 Twi_read_byte = Twdr                        {{vbcomment|Daten lesen}}&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Function&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
=== Transmit und Receive ===&lt;br /&gt;
[[Bild:RN-M8_TWI_DS1621_PCF8574.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
;Senden und Empfangen&lt;br /&gt;
Der Master (Mega8) stösst die Temperaturmessung des DS1621 an, liest die Tempetatur aus, sendet den Temperaturwert anschliessend an einen PCF8574 zur Anzeige an dessen LEDs.&lt;br /&gt;
&lt;br /&gt;
Zur Kontrolle werden die Daten auch per UART übertragen und an den LEDs des RN-Meaga8 angezeigt.&lt;br /&gt;
&lt;br /&gt;
Während der Übertragung wird die Busgeschwindigkeit geändert, da der DS1621 mit 400kHz kommunizieren kann, der PCF8574 nur mit 100kHz.&lt;br /&gt;
&lt;br /&gt;
Dieses Programm wird auch zum testen im Artikel [[Bascom und USI-Kommunikation]] verwendet, dort ist dann ein [[ATtiny2313|ATTiny2313]] einer der Slaves.&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Daten vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M8def.dat&amp;quot;                            {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                      {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                           {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_errorstate As Byte                        {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Anzahlbuf As Byte                             {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                   {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                     {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Config Portb.0 = Output&lt;br /&gt;
 Config Portb.1 = Output&lt;br /&gt;
 Config Portd = Output&lt;br /&gt;
 &lt;br /&gt;
 Const Device = &amp;amp;H90&lt;br /&gt;
 Const Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI initialisieren}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                 {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                          {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                         {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                        {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Sound Portb.0 , 300 , 450                         {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;TWI Master DS1621 Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Portb.0 = 1                                       {{vbcomment|Damit die LED ausgeht nach dem Beep}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
     Twbr = 12                                     {{vbcomment|Bit Rate Register 400kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                        {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                          {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate = 0 Then                    {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         Waitms 1                                  {{vbcomment|Etwas warten bis die Temperatur gemessen ist}}&lt;br /&gt;
         Messagebuf(1) = Device                    {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                      {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate = 0 Then                {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread            {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Twi_errorstate = 0 Then            {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
                 {{vbcomment|STOP senden}}&lt;br /&gt;
                 Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Wert an den LEDs anzeigen}}&lt;br /&gt;
                 Portd.7 = Not Lowtemp.5&lt;br /&gt;
                 Portd.6 = Not Lowtemp.4&lt;br /&gt;
                 Portd.5 = Not Lowtemp.3&lt;br /&gt;
                 Portd.4 = Not Lowtemp.2&lt;br /&gt;
                 Portd.3 = Not Lowtemp.1&lt;br /&gt;
                 Portd.2 = Not Lowtemp.0&lt;br /&gt;
                 Portb.1 = Not Hightemp.7&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate &amp;lt;&amp;gt; 0 Then                   {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
     Else&lt;br /&gt;
         Twbr = 72                                 {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Einem evtl. angeschlossenem PCF8574 den Temperaturwert senden}}&lt;br /&gt;
         Messagebuf(1) = &amp;amp;H40&lt;br /&gt;
         Messagebuf(2) = Not Lowtemp&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate &amp;lt;&amp;gt; 0 Then               {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
             Print &amp;quot;Error2 &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 2&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 {{vbcomment|TWI Transmit and receive function.}}&lt;br /&gt;
 Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                             {{vbcomment|TWINT, TWSTA, TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
 &lt;br /&gt;
         Rw = Messagebuf(1).0                      {{vbcomment|RW-Flag holen für Abfrage unten}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
         For Cnt = 1 To Anzahlbuf&lt;br /&gt;
             {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
             {{vbcomment|Print Cnt ; &amp;quot; &amp;quot; ; Messagebuf(cnt) ; &amp;quot; &amp;quot; ; Rw}}&lt;br /&gt;
             If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
                 {{vbcomment|Write Slaveadr}}&lt;br /&gt;
                 Twdr = Messagebuf(cnt)&lt;br /&gt;
                 Twcr = &amp;amp;B10000100                 {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Beim 1. Byte wird ein anderer Status erwartet}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     {{vbcomment|Slave hat sich gemeldet, $20 ist NACK, $18 WriteACK, $40 ReadACK !}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H40 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         {{vbcomment|kein Slave}}&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Zeichen wurde gesendet, $30 ist NACK}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H28 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             Else&lt;br /&gt;
                 {{vbcomment|Read a Byte}}&lt;br /&gt;
                 {{vbcomment|Wenn das letzte Byte gesendet wird, ein NACK mitgeben um das Ende anzuzeigen}}&lt;br /&gt;
                 If Cnt = Anzahlbuf Then&lt;br /&gt;
                     {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
                     Twcr = &amp;amp;B10000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Load ACK. TWEA ist 1}}&lt;br /&gt;
                     Twcr = &amp;amp;B11000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
                 Messagebuf(cnt) = Twdr            {{vbcomment|Daten lesen}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Byte empfangen und mit ACK quittiert, sonst Ende}}&lt;br /&gt;
                 If Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                     Twi_errorstate = 0            {{vbcomment|kein Fehler}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Beim letzten Byte auch mit NACK quittieren}}&lt;br /&gt;
                     If Cnt = Anzahlbuf And Twi_status = &amp;amp;H58 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         Next Cnt&lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Ist der Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                         {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Twi_errorstate = Twi_status               {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Stopsequenz ausgeben}}&lt;br /&gt;
 Twi_stop:&lt;br /&gt;
     Twcr = &amp;amp;B10010100                             {{vbcomment|TWINT löschen, Stop senden}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Warten bis Stop-Flag wieder gelöscht wird, dann ist die Stopsequenz abgeschlossen}}&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H10&lt;br /&gt;
     Loop Until Twi_control = 0&lt;br /&gt;
     {{vbcomment|Es muss nicht unbedingt darauf gewartet werden}}&lt;br /&gt;
     {{vbcomment|wenn die nächste Aktion nicht gleich anschliessend durchgeführt wird.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Einen speziellen STOP-Status gibt es nicht, es ist in der Regel &amp;amp;HF8}}&lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|Print Hex(twi_status)}}&lt;br /&gt;
 &lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Slave =&lt;br /&gt;
[[Bild:I2C_RN-M8_RN-control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Da der TWI-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave das [[RN-Mega8]] Board verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Count As Byte                                           {{vbcomment|Testwert, jedes mal +1}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Werte zurücksetzen}}&lt;br /&gt;
 Count = 0&lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|will der Master ein Byte haben}}&lt;br /&gt;
         If Twi_status = &amp;amp;HA8 Or Twi_status = &amp;amp;HB8 Then&lt;br /&gt;
             Twdr = Count                                    {{vbcomment|neue Daten ausgeben}}&lt;br /&gt;
             Incr Count                                      {{vbcomment|testwert +1}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, mit ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortD aus, an dem beim RN-M8 eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Config Portd = Output                                       {{vbcomment|kompletter PortD als Ausgang}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Neuesbyte As Byte                                       {{vbcomment|Bytemerker}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|alle LEDs ein}}&lt;br /&gt;
 Portd = 0&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Merker zurücksetzen}}&lt;br /&gt;
     Neuesbyte = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|wurde ein Byte geschickt}}&lt;br /&gt;
         If Twi_status = &amp;amp;H80 Or Twi_status = &amp;amp;H88 Then&lt;br /&gt;
             Twi_data = Twdr                                 {{vbcomment|neue Daten merken}}&lt;br /&gt;
             Neuesbyte = 1                                   {{vbcomment|merken das ein neues Byte da ist}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, erzeugt ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn ein neues Byte gekommen ist, dieses an PortD ausgeben}}&lt;br /&gt;
     If Neuesbyte &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
         Portd = Twi_data                                    {{vbcomment|Daten auf PortD ausgeben}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Der Slave ist hier sogar in der Lage während einer Übertragung mehr als ein Byte entgegenzunehmen, da jedes Byte den gleichen Status erzeugt.&lt;br /&gt;
&lt;br /&gt;
Wenn der Slave schnell genug getaktet wird (&amp;gt; 6.4 MHz), kann der Master auch auf einen schnelleren Bus-Takt gestellt werden. Dazu beim Master das ''TWBR'' auf 12 setzen, so wird der Bus mit 400kHz betrieben.&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]]&lt;br /&gt;
* [[TWI Praxis Multimaster]]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=246777#246777] - etwas ausführlicheres Slave-Beipiel im Forum&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - I2C Beispiele mit Bascom und dem USI-Modul&lt;br /&gt;
&lt;br /&gt;
= WebLinks =&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs C-Quellbibliothek für einen TWI-Master von Peter Fleury (avr-gcc)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 15:31, 15. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=10060</id>
		<title>USI (Avr)</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=10060"/>
				<updated>2007-01-24T00:03:39Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;USI ('''U'''niversal '''S'''erial '''I'''nterface) steht für Universelle serielle Schnittstelle, die vor allem in kleineren Atmel AVR Controllern, wie zB. beim [[ATtiny2313|ATTiny2313]], aber auch in einigen ATMegas anzutreffen ist.&lt;br /&gt;
&lt;br /&gt;
Wie der Name schon aussagt, kann diese Schnittstelle universell eingestellt werden um unterschiedliche Funktionen auszuführen. Hauptsächlich gedacht um verschiedene Arten der seriellen Kommunikation auszuüben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hauptfunktionen =&lt;br /&gt;
Die Hauptfunktionen sind&lt;br /&gt;
* Three-wire Modus, bzw. [[SPI]]&lt;br /&gt;
* Two-wire Modus, bzw. [[TWI]] oder [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Alternative Funktionen =&lt;br /&gt;
Wenn die Schnittstelle nicht für die serielle Kommunikation verwendet wird, gibt es, wegen der universellen Auslegung, weitere Möglichkeiten sie trotzdem zu verwenden. Dies wären:&lt;br /&gt;
* Halb-Duplex Asynchrone Datenübertragung&lt;br /&gt;
* 4-Bit Counter (0-15) mit verschiedenen Taktquellen&lt;br /&gt;
* 12-Bit Timer/Counter in Verbindung mit Timer0&lt;br /&gt;
* externer Interrupt, löst bei jeder Flanke aus&lt;br /&gt;
* Software Interrupt, kann durch setzen in einem USI-Register ausgelöst werden&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= USI-Register =&lt;br /&gt;
Hier eine kurze Beschreibung der für den USI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== USIDR ====&lt;br /&gt;
:USI Data Register, alle 8 bit&lt;br /&gt;
:Über dieses Register wird direkt auf das serielle Register zugegriffen, ohne Puffer dazwischen, auch während gerade ein Byte übertragen wird, anders als bei ''echtem'' TWI !&lt;br /&gt;
&lt;br /&gt;
==== USISR ====&lt;br /&gt;
:USI Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIF|USIOIF|USIPF|USIDC|USICNT3|USICNT2|USICNT1|USICNT0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Das Statsregister enthält die Interruptflags, den Status der Datenleitungen und den 4-Bit Counter&lt;br /&gt;
:*'''USISIF''' Startbedingung Interrupt Flag&lt;br /&gt;
::Bei TWI: Wenn eine Startbedingung erkannt wurde, wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USISIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Anderer Modus: Bei externer Takquelle wird bei jeder Flanke an USCK dieses Flag gesetzt.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIOIF''' Counter Overflow Interrupt Flag&lt;br /&gt;
::Wenn der Counter überläuft (15 + 1), wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USIOIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Bei TWI: Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIPF''' Stopbedingung Interrupt Flag (nur bei TWI)&lt;br /&gt;
::Wenn eine Stopbedingung erkannt wurde, wird dieses Flag gesetzt, es kann kein Interrupt generiert werden. &lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIDC''' Data Output Collision (nur bei TWI)&lt;br /&gt;
::Tritt auf, wenn gleichzeitg ein anderer Busteilnehmer auf den Bus zugreift (Multimaster).&lt;br /&gt;
:*'''USICNTx''' Wert des 4-Bit-Zählers&lt;br /&gt;
::Aktueller Wert des Zählers, kann jederzeit gelesen oder neu beschrieben werden. Zählt bei jeder Flanke (fallend oder steigend) der Taktquelle um eins hoch (siehe ''USICSx'' im ''Controlregister'').&lt;br /&gt;
&lt;br /&gt;
==== USICR ====&lt;br /&gt;
:USI Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIE|USIOIE|USIWM1|USIWM0|USICS1|USICS0|USICLK|USITC}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Im Controlregister wird der Modus eingestellt, Taktquelle ausgewählt und Interruptanforderungen aktiviert&lt;br /&gt;
:*'''USISIE''' Startbedingung Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn eine Startbedingung erkannt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIOIE''' Counter Overflow Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn ein Zählerüberlauf aufgetreten ist und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIWMx''' Modus wählen:&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USIWM1 || USIWM0 || Modus&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| kein Modus&amp;lt;br&amp;gt;PortPins können normal verwendet werden.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Three-wire Modus, bzw. [[SPI]]&amp;lt;br&amp;gt;Es werden die Pins DO, DI und USCK verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Master und Slave&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Slave,&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&amp;lt;br&amp;gt;Gleicher Modus wie '''10''' bis auf diese Zusatzfunktion:&amp;lt;br&amp;gt;Die Taktleitung wird beim Zählerüberlauf gehalten&amp;lt;br&amp;gt;bis die Software dieses freigibt (''USIOIF'' = 1),&amp;lt;br&amp;gt;siehe auch [[Clock Stretching]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USICSx''' Taktquelle wählen (in Verbindung mit USICLK):&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USICS1 || USICS0 || USICLK || Takquelle&amp;lt;br&amp;gt;Schieberegister || Taktquelle&amp;lt;br&amp;gt;Counter&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 0 || keine Taktquelle || keine Taktquelle&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 1 || Software (USICLK) || Software (USICLK)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 || X || Timer/Counter0 || Timer/Counter0 &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 0 || extern, positive Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 0 || extern, negative Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 1 || extern, positive Flanke || Software (USITC)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 1 || extern, negative Flanke || Software (USITC)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::Ist der Timer0 als Taktquelle ausgewählt, kann je nach AVR ein Timerüberlauf, oder ein Comparematch den Impuls für das USI-Modul auslösen.&lt;br /&gt;
::Die Taktleitung SCL muss dabei jeweils per Software umgeschaltet (getoggelt) werden, am einfachsten  in einer Timer-ISR ''USITC'' setzen.&lt;br /&gt;
&lt;br /&gt;
:*'''USICLK''' Clock Strobe&lt;br /&gt;
::Bei Softwaretakt, wird beim setzen dieses Bits das Schieberegister (''USIDR'') um ein Bit weitergeschoben und der Counter um eins hochgezählt. Der Ausgang wechselt noch im gleichen CPU-Takt auf den neuen Bitwert.&lt;br /&gt;
::Bei externer Taktquelle siehe vorhergehende Tabelle für die Verwendung von USICLK.&lt;br /&gt;
::Das auslesen von USICLK ergibt immer 0.&lt;br /&gt;
:*'''USITC''' Toggle Clock Port Pin&lt;br /&gt;
::Beim setzen wird der Zustand von USCK/SCL gewechselt (0-&amp;gt;1 oder 1-&amp;gt;0)&lt;br /&gt;
::Bei externer Taktquelle (siehe Tabelle bei USICSx) kann der 4-Bit-Zähler um eins hochgezählt werden.&lt;br /&gt;
::Das auslesen von USITC ergibt immer 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ganz neuen AVR Tiny Controllern (wie dem ATTiny261, ATTiny24 und ATTiny25) sind weitere Register zu finden:&lt;br /&gt;
&lt;br /&gt;
==== USIBR ====&lt;br /&gt;
:USI Buffer Register, alle 8 bit&lt;br /&gt;
:Dieses Register kann nur gelesen werden, entspricht aber eigentlich dem USIDR-Register. Es hat den Vorteil, das das letzte empfangene Byte hier gehalten wird, und die zeitliche Abfolge zum auslesen der Daten aus USIDR nicht mehr so kritisch ist, da zB. nach einem ACK bei TWI das USIDR schon um ein Bit weitergeschoben wird.&lt;br /&gt;
&lt;br /&gt;
==== USIPP ====&lt;br /&gt;
:USI Pin Position&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|USIPOS}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USIPOS''' USI Pin Position&lt;br /&gt;
::Es ist möglich, die Datenleitungen auf einen alternativen Port zu legen, wenn dieses Bit gesetzt wird. Die alternative Position ist aber auch festgelegt, man schaltet nur zwischen den Möglichkeiten um.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - Bascom-Beipiele um USI als I2C zu verwenden&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25058] - Forum-Artikel, der letztendlich dazu geführt hat diesen Wiki-Artikel zu erstellen. Mit einigen Beispielprogrammen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 19:19, 18. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=10044</id>
		<title>Bascom und USI-Kommunikation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=10044"/>
				<updated>2007-01-21T22:27:29Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: By&amp;lt;ustelle weg, Slave Beispielprogramm auf das Forum verweisen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele, um das [[USI (Avr)|USI]]-Hardwaremodul der [[AVR]]s zu verwenden. Mit dem [[USI (Avr)|USI]]-Modul können die Schnittstellen [[I2C]] ([[TWI]]) und [[SPI]] nachgebildet werden. Näheres zu [[USI (Avr)|USI]], [[I2C]] und [[SPI]] finden sich in den entsprechenden Artikeln. Die Beispiele sind zwar in [[Bascom]] Basic verfasst, aber so ausgeführt, dass es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Master ==&lt;br /&gt;
[[Bild:USI-I2C_PCF8574_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Generierung der gewünschten Busgeschwindigkeit ist die Software zuständig, die Länge der Pausen zwischen den Takten muss errechnet werden, im Beispielprogramm für ca. 100 kHz bei 16 MHz CPU-Frequenz.&lt;br /&gt;
Der Takt kann auch mithilfe eines [[Timer/Counter (Avr)|Timer]]s erzeugt werden, dies wird erst zu einem späteren Zeitpunkt mit einem Beispiel gezeigt.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATtiny2313|Tiny2313]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]] verwendet, da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schließt die Übertragung anschließend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen }}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim B As Byte                                           {{vbcomment|Zeichen von UART oder Testzeichen zum senden über USI}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 B = 0&lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;Tiny2313 USI-TWI-Test&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Messagebuf(1) = &amp;amp;H40                                    {{vbcomment|Adresse von 8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
     {{vbcomment|oder automatisch zählen lassen}}&lt;br /&gt;
     {{vbcomment|Incr B}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Messagebuf(2) = Not B                               {{vbcomment|Not, weil LEDs gegen GND schalten}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     Call Usi_twi_master_stop&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; &amp;quot;&lt;br /&gt;
     Print Hex(usi_twi_errorstate);&lt;br /&gt;
     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
     Print Hex(temp_usisr)&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitms 700  ' Wenn automatisch gezählt werden soll, eine kleine Pause, damit man auch was sehen kann}}&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
==== Unterprogramm nur Senden ====&lt;br /&gt;
&lt;br /&gt;
Die restlichen Subroutinen sind im nächsten Abschnitt zu finden.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist nur zum Versenden geeignet !&lt;br /&gt;
&lt;br /&gt;
Statt dieser kann auch die Routine von unten genommen werden, die aber etwas mehr Speicherplatz benötigt.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI Transmit Funktion.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung ausgeben}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Startbedingung vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Slaveadresse und Daten ausgeben}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|Ein Byte ausgeben}}&lt;br /&gt;
         Pout_usi_scl = 0                                {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
         Usidr = Messagebuf(cnt)&lt;br /&gt;
         Temp_usisr = Temp_usisr_8bit                    {{vbcomment|8Bit ausgeben}}&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|(N)ACK vom Slave lesen}}&lt;br /&gt;
         Ddr_usi_sda = 0                                 {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
         Temp_usisr = Temp_usisr_1bit                    {{vbcomment|1Bit einlesen}}&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|kein ACK gekommen, Slave meldet sich nicht}}&lt;br /&gt;
         If Temp_usisr.0 = 1 Then&lt;br /&gt;
             Usi_twi_errorstate = &amp;amp;H05                   {{vbcomment|Slave hat mit NACK quittiert}}&lt;br /&gt;
             If Cnt = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H06               {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
             End If&lt;br /&gt;
             Exit For                                    {{vbcomment|hier wird die Schleife bei einem NACK verlasssen}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter und Receiver mit DS1621 als Slave ===&lt;br /&gt;
[[Bild:USI-I2C_DS1621_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung mit DS1621]]&lt;br /&gt;
&lt;br /&gt;
;Senden und Empfangen (Repeated Start)&lt;br /&gt;
Im Beispiel wird ein DS1621 Temperatursensor mit I2C-Schnittstelle verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
Der Master sendet dem Slave ein Kommando, stellt um auf Empfang und holt den Temperaturwert, schließt die Übertragung anschließend ab.&lt;br /&gt;
&lt;br /&gt;
Der Temperaturwert wird über [[UART]] ([[RS232]]) im Klartext ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die Subroutinen sind die gleichen wie für ''Master Transmitter''. Da der DS1621 aber mit 400 kHz kommunizieren kann, wurden die ''Waitus'' zwischen den Pegelwechseln weggelassen, da die Befehle hier sowieso nicht schnell genug sind und ein Wait unnötig machen. Sie sind aber als Kommentar eingefügt, damit zu sehen ist an welchen Stellen ansonsten gewartet werden sollte (zB bei 100kHz).&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Temperaturwert vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&amp;lt;br&amp;gt;&lt;br /&gt;
(Das Beispiel belegt 1418 Byte im Flash, das sind ca. 69% eines Tiny2313 !)&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|Temperatur von DS1621 lesen, und über UART ausgeben}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                           {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Dim Device As Byte&lt;br /&gt;
 Dim Deviceread As Byte&lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Device = &amp;amp;H90&lt;br /&gt;
 Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.5 , 300 , 450                               {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;DS1621-USI Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                              {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                                {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2                                       {{vbcomment|2 Byte ausgeben}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate = 0 Then                      {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
         Call Usi_twi_master_stop&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitms 1}}&lt;br /&gt;
         Messagebuf(1) = Device                          {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                            {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2                                   {{vbcomment|2 Byte ausgeben}}&lt;br /&gt;
         Call Usi_twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
         {{vbcomment|kein STOP an dieser Stelle !}}&lt;br /&gt;
         {{vbcomment|es folgt ein Repeated START !}}&lt;br /&gt;
 &lt;br /&gt;
         If Usi_twi_errorstate = 0 Then                  {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread                  {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3                               {{vbcomment|3 Byte ausgeben, bzw. einlesen}}&lt;br /&gt;
             Call Usi_twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Usi_twi_errorstate = 0 Then              {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
                 Call Usi_twi_master_stop&lt;br /&gt;
                 {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Gelesenen Bytes stehen ab Position 2 im Array}}&lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     {{vbcomment|.5 ?}}&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate &amp;lt;&amp;gt; 0 Then                     {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(usi_twi_errorstate)&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
     Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
     Waitms 2000&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Unterprogramme für USI-Kommunikation ===&lt;br /&gt;
&lt;br /&gt;
Hier folgen die Unterprogramme für die USI-I2C-Master Kommunikation&lt;br /&gt;
&lt;br /&gt;
==== Initialisierung ====&lt;br /&gt;
&lt;br /&gt;
USI-I2C Pins Initialisieren, und USI-Register setzen für I2C-Master.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable USI Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Statusflags löschen, und Counter auf 0 zurücksetzen.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== Senden/Empfangen ====&lt;br /&gt;
&lt;br /&gt;
Startbedingung ausgeben,&amp;lt;br&amp;gt;&lt;br /&gt;
versenden der Anzahl der angegebenen Bytes,&amp;lt;br&amp;gt;&lt;br /&gt;
und einen Status zurückgeben, ob die Daten angenommen (ACK) wurden.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI Transmit und Receive Funktion.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|RW-Bit : Messagebuf(1).0}}&lt;br /&gt;
     Rw = Messagebuf(1).0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
         If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
             {{vbcomment|Write a byte}}&lt;br /&gt;
             Pout_usi_scl = 0                            {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
             Usidr = Messagebuf(cnt)&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|kein ACK gekommen}}&lt;br /&gt;
             If Temp_usisr.0 = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H05               {{vbcomment|Der Slave hat die Daten mit NACK quittiert}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     Usi_twi_errorstate = &amp;amp;H06           {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
                 End If&lt;br /&gt;
                 Exit For                                {{vbcomment|die Schleife bei einem Fehler verlasssen}}&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|Read a Byte}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             Messagebuf(cnt) = Temp_usisr                {{vbcomment|Empfangenes Byte ins Array}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Prepare to generate ACK (or NACK in case of End Of Transmission)}}&lt;br /&gt;
             If Cnt = Anzahlbuf Then&lt;br /&gt;
                 Usidr = &amp;amp;HFF                            {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Usidr = &amp;amp;H00                            {{vbcomment|Load ACK. Set data register bit 7 (output for SDA) low.}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer                {{vbcomment|ACK oder NACK senden}}&lt;br /&gt;
 &lt;br /&gt;
         End If&lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== Ein Byte ausgeben/einlesen ====&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt die Anzahl Bit aus, wie anhand der Variablen ''Temp_usisr'' eingestellt wurde, bzw. es wird damit die Anzahl Takte angegeben, die der Counter des USI-Moduls zählt bevor er überläuft, und das Flag ''USIOIF'' im Status-Register ''USISR'' gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Getaktet wird hier per Software, pro Bit zwei Takte. Bei jedem Takt ändert sich der Zustand (High/Low) von SCL.&lt;br /&gt;
&lt;br /&gt;
Die Daten, die ausgegeben werden sollen, müssen vor dem Aufruf dieser Routine in das Datenregister ''USIDR'' geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Ob ein Bit ausgegeben oder gelesen wird, wird vor dem Aufruf im Datenrichtungsregister der Datenleitung SDA eingestellt. Im Beispiel mit dem Alias ''Ddr_usi_sda''.&lt;br /&gt;
&lt;br /&gt;
Das gelesene Byte von ''USIDR'' wird in die Variable ''Temp_usisr'' geschrieben, und kann vom Hauptprogramm weiterverarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Waitus 5}}&lt;br /&gt;
         Usicr = Temp_usisr                              {{vbcomment|SCL takten}}&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitus 4}}&lt;br /&gt;
         Usicr = Temp_usisr                              {{vbcomment|SCL takten}}&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Wenn der Zähler überläuft, sind alle Bits versendet.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitus 5}}&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Daten aus USI-Datenregister lesen.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== STOP-Bedingung ausgeben ====&lt;br /&gt;
&lt;br /&gt;
STOP-Bedingung ausgeben, und prüfen ob dies vom eigenen Modul erkannt wurde.&amp;lt;br&amp;gt;&lt;br /&gt;
Status zurückgeben, ob die STOP-Bedingung erfolgreich ausgegeben wurde.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
 &lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig, da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Fehlercodes aus den Beispielen ===&lt;br /&gt;
&lt;br /&gt;
Wenn ein unerwartetes Ereignis auftreten sollte, wird eine Zahl ausgegeben, hier ist deren Bedeutung dazu.&lt;br /&gt;
Die Fehlercodes wurden aus den Beispielen von Atmel übernommen. (siehe Weblinks)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Code || Kurzbezeichnung || Fehlerbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|02&lt;br /&gt;
| USI_TWI_UE_START_CON || Unerwartete Start Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|03&lt;br /&gt;
| USI_TWI_UE_STOP_CON || Unerwartete Stop Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|04&lt;br /&gt;
| USI_TWI_UE_DATA_COL || Unerwartete Data Collision (arbitration)&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|05&lt;br /&gt;
| USI_TWI_NO_ACK_ON_DATA || Der Slave hat die Daten nicht per ACK quittiert&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|06&lt;br /&gt;
| USI_TWI_NO_ACK_ON_ADDRESS || Es hat sich kein Slave per ACK gemeldet&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|07&lt;br /&gt;
| USI_TWI_MISSING_START_CON || Erzeugte Start Bedingung nicht erkannt&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|08&lt;br /&gt;
| USI_TWI_MISSING_STOP_CON || Erzeugte Stop Bedingung nicht erkannt&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Slave ==&lt;br /&gt;
&lt;br /&gt;
Da der I2C-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Mega8]] mit einem [[ATMega8|Mega8]], und als Slave das [[RN-Control]] Board, mit dem Adapter auf dem der [[ATtiny2313|Tiny2313]] sitzt, verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im unten angegebenen WebLink (Nr.1) zum Forum ist ein Beispielprogramm um einen USI-I2C-Slave zu programmieren, es ist noch nicht ganz ausgereift, funktioniert aber ausreichend.&lt;br /&gt;
Bei Gelegenheit wird das hier nachgeholt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=25058] - Thread im Forum der zu diesem hier geführt hat&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&amp;amp;products_id=107] - DS1621 bei Robotikhardware&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:11, 26. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=10043</id>
		<title>USI (Avr)</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=10043"/>
				<updated>2007-01-21T21:53:36Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Baustelle weg, minimale Anpassung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;USI ('''U'''niversal '''S'''erial '''I'''nterface) steht für Universelle serielle Schnittstelle, die vor allem in kleineren Atmel AVR Controllern, wie zB. beim [[ATtiny2313|ATTiny2313]], aber auch in einigen ATMegas anzutreffen ist.&lt;br /&gt;
&lt;br /&gt;
Wie der Name schon aussagt, kann diese Schnittstelle universell eingestellt werden um unterschiedliche Funktionen auszuführen. Hauptsächlich gedacht um verschiedene Arten der seriellen Kommunikation auszuüben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hauptfunktionen =&lt;br /&gt;
Die Hauptfunktionen sind&lt;br /&gt;
* Three-wire Modus, bzw. [[SPI]]&lt;br /&gt;
* Two-wire Modus, bzw. [[TWI]] oder [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Alternative Funktionen =&lt;br /&gt;
Wenn die Schnittstelle nicht für die serielle Kommunikation verwendet wird, gibt es, wegen der universellen Auslegung, weitere Möglichkeiten sie trotzdem zu verwenden. Dies wären:&lt;br /&gt;
* Halb-Duplex Asynchrone Datenübertragung&lt;br /&gt;
* 4-Bit Counter (0-15) mit verschiedenen Taktquellen&lt;br /&gt;
* 12-Bit Timer/Counter in Verbindung mit Timer0&lt;br /&gt;
* externer Interrupt, löst bei jeder Flanke aus&lt;br /&gt;
* Software Interrupt, kann durch setzen in einem USI-Register ausgelöst werden&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= USI-Register =&lt;br /&gt;
Hier eine kurze Beschreibung der für den USI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== USIDR ====&lt;br /&gt;
:USI Data Register, alle 8 bit&lt;br /&gt;
:Über dieses Register wird direkt auf das serielle Register zugegriffen, ohne Puffer dazwischen, auch während gerade ein Byte übertragen wird, anders als bei ''echtem'' TWI !&lt;br /&gt;
&lt;br /&gt;
==== USISR ====&lt;br /&gt;
:USI Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIF|USIOIF|USIPF|USIDC|USICNT3|USICNT2|USICNT1|USICNT0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Das Statsregister enthält die Interruptflags, den Status der Datenleitungen und den 4-Bit Counter&lt;br /&gt;
:*'''USISIF''' Startbedingung Interrupt Flag&lt;br /&gt;
::Bei TWI: Wenn eine Startbedingung erkannt wurde, wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USISIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Anderer Modus: Bei externer Takquelle wird bei jeder Flanke an USCK dieses Flag gesetzt.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIOIF''' Counter Overflow Interrupt Flag&lt;br /&gt;
::Wenn der Counter überläuft (15 + 1), wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USIOIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Bei TWI: Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIPF''' Stopbedingung Interrupt Flag (nur bei TWI)&lt;br /&gt;
::Wenn eine Stopbedingung erkannt wurde, wird dieses Flag gesetzt, es kann kein Interrupt generiert werden. &lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIDC''' Data Output Collision (nur bei TWI)&lt;br /&gt;
::Tritt auf, wenn gleichzeitg ein anderer Busteilnehmer auf den Bus zugreift (Multimaster).&lt;br /&gt;
:*'''USICNTx''' Wert des 4-Bit-Zählers&lt;br /&gt;
::Aktueller Wert des Zählers, kann jederzeit gelesen oder neu beschrieben werden. Zählt bei jeder Flanke (fallend oder steigend) der Taktquelle um eins hoch (siehe ''USICSx'' im ''Controlregister'').&lt;br /&gt;
&lt;br /&gt;
==== USICR ====&lt;br /&gt;
:USI Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIE|USIOIE|USIWM1|USIWM0|USICS1|USICS0|USICLK|USITC}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Im Controlregister wird der Modus eingestellt, Taktquelle ausgewählt und Interruptanforderungen aktiviert&lt;br /&gt;
:*'''USISIE''' Startbedingung Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn eine Startbedingung erkannt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIOIE''' Counter Overflow Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn ein Zählerüberlauf aufgetreten ist und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIWMx''' Modus wählen:&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USIWM1 || USIWM0 || Modus&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| kein Modus&amp;lt;br&amp;gt;PortPins können normal verwendet werden.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Three-wire Modus, bzw. [[SPI]]&amp;lt;br&amp;gt;Es werden die Pins DO, DI und USCK verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Master und Slave&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Slave,&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&amp;lt;br&amp;gt;Gleicher Modus wie '''10''' bis auf diese Zusatzfunktion:&amp;lt;br&amp;gt;Die Taktleitung wird beim Zählerüberlauf gehalten&amp;lt;br&amp;gt;bis die Software dieses freigibt (''USIOIF'' = 1),&amp;lt;br&amp;gt;siehe auch [[Clock Stretching]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USICSx''' Taktquelle wählen (in Verbindung mit USICLK):&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USICS1 || USICS0 || USICLK || Takquelle&amp;lt;br&amp;gt;Schieberegister || Taktquelle&amp;lt;br&amp;gt;Counter&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 0 || keine Taktquelle || keine Taktquelle&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 1 || Software (USICLK) || Software (USICLK)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 || X || Timer/Counter0 || Timer/Counter0 &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 0 || extern, positive Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 0 || extern, negative Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 1 || extern, positive Flanke || Software (USITC)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 1 || extern, negative Flanke || Software (USITC)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::Ist der Timer0 als Taktquelle ausgewählt, kann je nach AVR ein Timerüberlauf, oder ein Comparematch den Impuls für das USI-Modul auslösen.&lt;br /&gt;
::Die Taktleitung SCL muss dabei jeweils per Software umgeschaltet (getoggelt) werden, am einfachsten  in einer Timer-ISR ''USITC'' setzen.&lt;br /&gt;
&lt;br /&gt;
:*'''USICLK''' Clock Strobe&lt;br /&gt;
::Bei Softwaretakt, wird beim setzen dieses Bits das Schieberegister (''USIDR'') um ein Bit weitergeschoben und der Counter um eins hochgezählt. Der Ausgang wechselt noch im gleichen CPU-Takt auf den neuen Bitwert.&lt;br /&gt;
::Bei externer Taktquelle siehe vorhergehende Tabelle für die Verwendung von USICLK.&lt;br /&gt;
::Das auslesen von USICLK ergibt immer 0.&lt;br /&gt;
:*'''USITC''' Toggle Clock Port Pin&lt;br /&gt;
::Beim setzen wird der Zustand von USCK/SCL gewechselt (0-&amp;gt;1 oder 1-&amp;gt;0)&lt;br /&gt;
::Bei externer Taktquelle (siehe Tabelle bei USICSx) kann der 4-Bit-Zähler um eins hochgezählt werden.&lt;br /&gt;
::Das auslesen von USITC ergibt immer 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ganz neuen AVR Tiny Controllern (wie dem ATTiny261, ATTiny24 und ATTiny25) sind weitere Register zu finden:&lt;br /&gt;
&lt;br /&gt;
==== USIBR ====&lt;br /&gt;
:USI Buffer Register, alle 8 bit&lt;br /&gt;
:Dieses Register kann nur gelesen werden, entspricht aber eigentlich dem USIDR-Register. Es hat den Vorteil, das das letzte empfangene Byte hier gehalten wird, und die zeitliche Abfolge zum auslesen der Daten aus USIDR nicht mehr so kritisch ist, da zB. nach einem ACK bei TWI das USIDR schon um ein Bit weitergeschoben wird.&lt;br /&gt;
&lt;br /&gt;
==== USIPP ====&lt;br /&gt;
:USI Pin Position&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|USIPOS}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USIPOS''' USI Pin Position&lt;br /&gt;
::Es ist möglich, die Datenleitungen auf einen alternativen Port zu legen, wenn dieses Bit gesetzt wird. Die alternative Position ist aber auch festgelegt, man schaltet nur zwischen den Möglichkeiten um.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26774] - Forum-Artikel, in dem eine [[Bascom]]-Lib vorgestellt wird, um die Bascom-I2C-Befehle mit dem USI-Modul als Master zu verwenden.&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25058] - Forum-Artikel, der letztendlich dazu geführt hat diesen Wiki-Artikel zu erstellen. Mit einigen Beispielprogrammen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 19:19, 18. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=ADC_(Avr)&amp;diff=9925</id>
		<title>ADC (Avr)</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=ADC_(Avr)&amp;diff=9925"/>
				<updated>2006-12-30T16:06:14Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Referenzspannung, diverse Optimierungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''Für allgemeine Informationen zum Analog-Digital-Wandler siehe Artikel [[ADC]].''&lt;br /&gt;
&lt;br /&gt;
Mit einem Analog-Digital-Wandler ([[ADC]], für Analog Digital Converter) ist es mit den AVRs möglich, auf einfache Art und Weise analoge Größen in digitale Werte umzuwandeln. Dies bietet sich z.B. an, wenn man die Batteriespannung eines Roboters bestimmen möchte.&lt;br /&gt;
&lt;br /&gt;
= Kanäle =&lt;br /&gt;
Ein AVR hat normalerweise nur einen [[ADC]] integriert. Öfters muss man aber mehrere analoge Größen von verschiedenen Quellen wandeln, deswegen besitzen die AVRs Kanäle (ein ATmega32 z.B. besitzt acht Kanäle auf Port A). Diese Kanäle werden dann mithilfe eines Multiplexer auf den [[ADC]] geschaltet, der dann die anliegende analoge Spannung in einen digitalten Wert wandelt.&lt;br /&gt;
&lt;br /&gt;
= Betriebsmodi =&lt;br /&gt;
Der [[ADC]] bietet verschiedene Betriebsmodi. Diese wären:&lt;br /&gt;
* Single Conversion: Der [[ADC]] wandelt eine analoge Größe um und gibt diese zurück.&lt;br /&gt;
* Free Running: Der [[ADC]] wandelt wie in einer Endlosschleife ständig die anliegende analoge Größe in digitale Werte um und gibt diese zurück.&lt;br /&gt;
&lt;br /&gt;
= Teilungsfaktor =&lt;br /&gt;
Zum Wandeln benötigt der [[ADC]] einen eigenen Takt, der auf der Taktfrequenz des Mikrocontrollers basiert. Allerdings ist die Taktfrequenz des Mikrocontrollers zu schnell und deswegen wird diese durch den Vorteiler verkleinert. Der resultierende Takt sollte beim AVR zwischen 50kHz und 200kHz liegen. Folgende Teilungsfaktoren sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|'''Teilungsfaktoren'''&lt;br /&gt;
| &amp;amp;nbsp;2 || &amp;amp;nbsp;4 || &amp;amp;nbsp;8 || 16 || 32 || 64 || 128&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um zu bestimmen welcher Teilungsfaktor geeignet ist, kann man folgende Formel verwenden.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Taktfrequenz = 8 MHz&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Teilungsfaktor_{min} = {Taktfrequenz \over {200 kHz}} = {{8000000 Hz} \over {200000 Hz}} = 40&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Teilungsfaktor_{max} = {Taktfrequenz \over {50 kHz}} = {{8000000 Hz} \over {50000 Hz}} = 160&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deswegen kann man nun zwischen einem der folgenden Teilungsfaktor wählen: 64 und 128. Im Interesse der Geschwindigkeit sollte 64 gewählt werden.&lt;br /&gt;
&lt;br /&gt;
Siehe bitte die Registerübersicht weiter unten. Dort wird gezeigt, welches Register entsprechend eingestellt werden muss, damit man einen der oben aufgelisteten Teilungsfaktoren auswählen kann.&lt;br /&gt;
&lt;br /&gt;
= Referenzspannung =&lt;br /&gt;
Das Ergebnis der Wandlung des [[ADC]] bezieht sich auf eine bestimmte Referenzspannung. Diese Referenzspannung lässt sich bestimmen. Je nach gewählter Referenzspannung darf man nur eine zu messende Spannung an den Port anlegen, die nicht höher liegt als die Referenzspannung. Sonst würde dieser zerstört werden. Die Referenzspannung ist also gleich der maximal zu messenden Spannung. Um einzustellen welche Referenzspannung verwendet werden soll, gibt es das Register ''ADMUX''.&lt;br /&gt;
Je nach verwendetem AVR sind verschiedene Möglichkeiten als Referenzspannung vorhanden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Referenz- spannungsquelle|| Bedeutung&lt;br /&gt;
|-&lt;br /&gt;
|AREF || es wird die externe Spannung als Referenz verwendet die an Pin AREF anliegt&lt;br /&gt;
|-&lt;br /&gt;
|AVCC || besitzt der AVR eine eigene Spannungsversorgung für den ADC&amp;lt;br /&amp;gt;wird der Pin AVCC als Referenz gewählt,&amp;lt;br /&amp;gt;ansonsten wird Vcc verwendet,&amp;lt;br /&amp;gt;mit externen Kondensator am AREF Pin&lt;br /&gt;
|-&lt;br /&gt;
|Intern || Spannung 1,1V und/oder 2,56V, je nach AVR einer der beiden Spannungen, oder beide zur Auswahl, wie zB. beim [[ATmega644]], mit oder ohne (zB. beim Tiny15L) externem Kondensator am AREF Pin&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verwendet man [[Bascom]] als Programmiersprache, gibt es, je nach verwendetem AVR, folgende Möglichkeiten zur Angabe als Referenz :&lt;br /&gt;
 Config Adc = Single , Prescaler = Auto , Reference = &lt;br /&gt;
  OFF             {{vbcomment|AREF}}&lt;br /&gt;
  AVCC            {{vbcomment|AVCC oder VCC}}&lt;br /&gt;
  INTERNAL        {{vbcomment|Wenn nur eine interne Spannung möglich ist}}&lt;br /&gt;
  INTERNAL_1.1    {{vbcomment|Wenn mehr interne Spannungen auswählbar sind}}&lt;br /&gt;
  INTERNAL_2.56   {{vbcomment|Wenn mehr interne Spannungen auswählbar sind}}&lt;br /&gt;
  INTERNALEXTCAP  {{vbcomment|Wenn, zB. beim Tiny15L, ein Kondensator an AREF angeschlossen ist}}&lt;br /&gt;
&lt;br /&gt;
Siehe bitte die Registerübersicht. Dort steht genauer wie man das Register einzustellen hat.&lt;br /&gt;
&lt;br /&gt;
Man benötigt die Referenzspannung auch (oder besser deren analoge Größe) um den Wert den der ADC zurückgibt in V umzurechnen. Um den zurückgegebenen Wert des ADC umzuwandel geht man so vor:&lt;br /&gt;
&lt;br /&gt;
# Bestimmen der Auflösung des ADC. Bei den ATMegas normalerweise 10 Bit. 10 Bit entsprechen einer Stufung von 1024.&lt;br /&gt;
# Ermitteln des digitalen Wertes der analogen Größe. In der Beispielrechnung verwende ich den Wert 592.&lt;br /&gt;
# Größe der Referenzspannung. In der Beispielrechnung wird 5V verwendet.&lt;br /&gt;
Mit diesen Werten kann folgende Berechnung ausführen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = 592 * 5V&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;V = 2960 / 2 ^{Bit} = 2960 / 2 ^{10} = \underline {\underline { 2{,}9V }}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Programmbeispiele =&lt;br /&gt;
&lt;br /&gt;
=== C/C++ ===&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel ist für die [[Atmel Controller Mega16 und Mega32]] gedacht, die mit einer Taktfrequenz von 8 MHz laufen. Es ist unbedingt darauf zu achten nicht die Referenzspannung von 2,56V zu überschreiten! Sonst stirbt der Port. Je nach Einsatzart muss man das Beispielprogramm entsprechend abändern (also diese Zeile mit ADMUX |= (1&amp;lt;&amp;lt;REFS1) | (1&amp;lt;&amp;lt;REFS0);).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint16_t readADC(uint8_t channel) {&lt;br /&gt;
	uint8_t i;&lt;br /&gt;
	uint16_t result = 0;&lt;br /&gt;
	&lt;br /&gt;
	// Den ADC aktivieren und Teilungsfaktor auf 64 stellen&lt;br /&gt;
	ADCSRA = (1&amp;lt;&amp;lt;ADEN) | (1&amp;lt;&amp;lt;ADPS2) | (1&amp;lt;&amp;lt;ADPS1);&lt;br /&gt;
&lt;br /&gt;
	// Kanal des Multiplexers waehlen&lt;br /&gt;
	ADMUX = channel;&lt;br /&gt;
	// Interne Referenzspannung verwenden (also 2,56 V)&lt;br /&gt;
	ADMUX |= (1&amp;lt;&amp;lt;REFS1) | (1&amp;lt;&amp;lt;REFS0);&lt;br /&gt;
	&lt;br /&gt;
	// Den ADC initialisieren und einen sog. Dummyreadout machen&lt;br /&gt;
	ADCSRA |= (1&amp;lt;&amp;lt;ADSC);&lt;br /&gt;
	while(ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC));&lt;br /&gt;
	&lt;br /&gt;
	// Jetzt 3x die analoge Spannung and Kanal channel auslesen&lt;br /&gt;
	// und dann Durchschnittswert ausrechnen.&lt;br /&gt;
	for(i=0; i&amp;lt;3; i++) {&lt;br /&gt;
		// Eine Wandlung&lt;br /&gt;
		ADCSRA |= (1&amp;lt;&amp;lt;ADSC);&lt;br /&gt;
		// Auf Ergebnis warten...&lt;br /&gt;
		while(ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC));&lt;br /&gt;
		&lt;br /&gt;
		result += ADCW;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// ADC wieder deaktivieren&lt;br /&gt;
	ADCSRA &amp;amp;= ~(1&amp;lt;&amp;lt;ADEN);&lt;br /&gt;
	&lt;br /&gt;
	result /= 3;&lt;br /&gt;
	&lt;br /&gt;
	return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
	uint16_t result = readADC(0);	//Auslesen der analogen Spannungen an Pin 0,&lt;br /&gt;
					// also ADC0. In result steht das Ergebnis.&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bascom ===&lt;br /&gt;
&lt;br /&gt;
Dieses Programmbeispiel ist für den Atmel Controller Mega32 gedacht. Es gibt nacheinander die Spannungen der einzelnen Kanäle (ADC0..7) aus. Dazwischen macht es immer 800 ms pause.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
' Die gemessene Spannung wird in der Variablen W gespeichert.&lt;br /&gt;
' Channel ist der Pin, an dem die Spannung gemessen werden soll.&lt;br /&gt;
&lt;br /&gt;
$baud = 9600&lt;br /&gt;
$crystal = 1000000&lt;br /&gt;
$regfile &amp;quot;m32def.dat&amp;quot;&lt;br /&gt;
Config Adc = Single , Prescaler = Auto&lt;br /&gt;
Start Adc&lt;br /&gt;
Dim W As Word , Channel As Byte&lt;br /&gt;
Channel = 0&lt;br /&gt;
Do&lt;br /&gt;
  W = Getadc(channel)&lt;br /&gt;
  Print &amp;quot;ADC-Pin &amp;quot; ; Channel ; &amp;quot;: Wert &amp;quot; ; W&lt;br /&gt;
  Incr Channel&lt;br /&gt;
  If Channel &amp;gt; 7 Then Channel = 0&lt;br /&gt;
  Waitms 800&lt;br /&gt;
Loop&lt;br /&gt;
End&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Registerübersicht =&lt;br /&gt;
&lt;br /&gt;
{| {{GrauRotDesignSchmal}}&lt;br /&gt;
|-&lt;br /&gt;
|Hinweis: Diese Registertabellen wurden für den aktuellen [[Atmel Controller Mega16 und Mega32]] erstellt. Wenn Sie ein anderes Modell verwenden kann es sein, dass ein oder mehrere Register nicht existieren, oder sie eine andere Bezeichnung haben.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ADCSRA ===&lt;br /&gt;
&lt;br /&gt;
ADC Control and Status Register A&lt;br /&gt;
&lt;br /&gt;
Dieser Register dient dazu den ADC zu kontrollieren.&lt;br /&gt;
&lt;br /&gt;
{{Registertabelle8BitFix|ADEN|ADSC|ADATE|ADIF|ADIE|ADPS2|ADPS1|ADPS0}}&lt;br /&gt;
&lt;br /&gt;
*'''ADEN (ADC Enable)'''&amp;lt;br/&amp;gt;Wird dieses Bit gesetzt (also 1), dann wird der ADC aktiviert. Schreibt man eine 0 wird der ADC deaktiert. Wird der ADC während einer Wandlung deaktiviert, wird die Wandlung abgebrochen.&lt;br /&gt;
*'''ADSC (ADC Start Conversion)'''&amp;lt;br/&amp;gt;Dieses Bit startet den Messvorgang, je nachdem in welchem Betriebsmodi der ADC läuft. Wird dieses Bit nach der Aktivierung des ADC über '''ADEN''' zum ersten Mal gesetzt, wird der ADC erst eine Initialisierungswandlung durchführen und danach erst die eigentliche Wandlung. Das Schreiben einer 0 auf das Bit hat keinen Effekt.&lt;br /&gt;
*'''ADATE (ADC Auto Trigger Enable)'''&amp;lt;br/&amp;gt;Wird dieses Bit gesetzt, wird das Auto Triggering des ADC aktiviert.&lt;br /&gt;
*'''ADIF (ADC Interrupt Flag)'''&amp;lt;br/&amp;gt;Dieses Bit wird auf 1 gesetzt, wenn eine Wandlung erfolgte und das Ergebnis nun verfügbar ist. Der ADC Complete Interrupt wird ausgelöst, wenn das '''ADIE'''-Bit gesetzt ist und die Interrupts global aktiviert sind. Das Bit wird gelöscht, wenn die entsprechende [[ISR]] abgearbeitet wird. Alternativ kann man es löschen, indem man eine 1 auf das Bit schreibt.&lt;br /&gt;
*'''ADIE (ADC Interrupt Enable)'''&amp;lt;br/&amp;gt;Wird dieses Bit gesetzt und die globalen Interrupts sind aktiviert, wird der ADC Complete Interrupt aktiviert, auf den man dann in der entsprechenden [[ISR]] reagieren kann.&lt;br /&gt;
*'''ADPS2 (ADC Prescaler Select Bit 2)'''&amp;lt;br/&amp;gt;Diese Bits bestimmen den Teilungsfaktor zwischen der CPU-Frequenz und dem Eingangstakt des [[ADC]]. Zum Wandeln benötigt der [[ADC]] einen eigenen Takt, der auf der Taktfrequenz des Mikrocontrollers basiert. Allerdings ist die Taktfrequenz zu schnell und deswegen wird diese durch den Vorteiler verkleinert. Der resultierende Takt sollte zwischen 50kHz und 200kHz liegen. Siehe [[#Teilungsfaktor|Teilungsfaktor]]. Folgende Teilungsfaktoren sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|ADPS2 || ADPS1 || ADPS0 || Teilungsfaktor&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 0 || 2&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 0 || 1 || 2&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 0 || 4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|0 || 1 || 1 || 8&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 0 || 16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 0 || 1 || 32&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 0 || 64&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|1 || 1 || 1 || 128&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''ADPS1 (ADC Prescaler Select Bit 1)'''&amp;lt;br/&amp;gt;Siehe '''ADPS2''' für eine Beschreibung.&lt;br /&gt;
*'''ADPS0 (ADC Prescaler Select Bit 0)'''&amp;lt;br/&amp;gt;Siehe '''ADPS2''' für eine Beschreibung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ADMUX ===&lt;br /&gt;
&lt;br /&gt;
ADC Multiplexer Selection Register&lt;br /&gt;
&lt;br /&gt;
Mit diesem Register wird u.a. der Multiplexer gesteuert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|REFS1|REFS0|ADLAR|MUX4|MUX3|MUX2|MUX1|MUX0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''REFS1 (Reference Selection Bit 1)'''&lt;br /&gt;
Mit diesem Bit kann steuern, welche Referenzspannung der ADC verwenden soll. Die möglichen Quellen sind unten aufgelistet. Wird während einer Wandlung die Quelle für die Referenzspannung geändert, wird die aktuelle Wandlung mit der &amp;quot;alten&amp;quot; Quellen zuerste beendet, bevor die neue Einstellung übernommen wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|REFS1 || REFS0 || Referenzspannungsquelle&lt;br /&gt;
|-&lt;br /&gt;
|0 || 0&lt;br /&gt;
|AREF, internes Vref deaktiviert&lt;br /&gt;
|-&lt;br /&gt;
|0 || 1&lt;br /&gt;
|AVCC mit externen Kondensator am AREF Pin&lt;br /&gt;
|-&lt;br /&gt;
|1 || 0&lt;br /&gt;
|Keine Funktion, reserviert&lt;br /&gt;
|-&lt;br /&gt;
|1 || 1&lt;br /&gt;
|Interne 2,56V Spannungsreferenz mit externen Kondensator am AREF Pin&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''REFS0 (ADC Start Conversion)'''&amp;lt;br/&amp;gt;Siehe '''REFS1'''.&lt;br /&gt;
*'''ADLAR (ADC Left Adjust Result)'''&amp;lt;br/&amp;gt;Dieses Bit beeinflusst, wie der ermittelte Messwert im ADC Data Register abgelegt wird.&lt;br /&gt;
*'''MUX4 (Analog Channel and Gain Selection Bit 4)'''&amp;lt;br/&amp;gt;Dieses Bit wird auf 1 gesetzt, wenn eine Wandlung erfolgte und das Ergebnis nun verfügbar ist. Der ADC Complete Interrupt wird ausgelöst, wenn das '''ADIE'''-Bit gesetzt ist und die Interrupts global aktiviert sind. Das Bit wird gelöscht, wenn die entsprechende ISR abgearbeitet wird. Alternativ kann man es löschen, indem man eine 1 auf das Bit schreibt.&lt;br /&gt;
*'''MUX3 (Analog Channel and Gain Selection Bit 3)'''&amp;lt;br/&amp;gt;Mit diesen Bits ('''MUX3''' bis '''MUX0''') wird der Kanal des Multiplexers eingestellt, der mit dem ADC verbunden ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!|MUX4..0 || Pin&lt;br /&gt;
|-&lt;br /&gt;
|00000 || ADC0&lt;br /&gt;
|-&lt;br /&gt;
|00001 || ADC1&lt;br /&gt;
|-&lt;br /&gt;
|00010 || ADC2&lt;br /&gt;
|-&lt;br /&gt;
|00011 || ADC3&lt;br /&gt;
|-&lt;br /&gt;
|00100 || ADC4&lt;br /&gt;
|-&lt;br /&gt;
|00101 || ADC5&lt;br /&gt;
|-&lt;br /&gt;
|00110 || ADC6&lt;br /&gt;
|-&lt;br /&gt;
|00111 || ADC7&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es reicht also einfach die Pinnummer in ADMUX zu schreiben.&lt;br /&gt;
*'''MUX2 (Analog Channel and Gain Selection Bit 2)'''&amp;lt;br/&amp;gt;Siehe '''MUX3''' für eine Beschreibung.&lt;br /&gt;
*'''MUX1 (Analog Channel and Gain Selection Bit 1)'''&amp;lt;br/&amp;gt;Siehe '''MUX3''' für eine Beschreibung.&lt;br /&gt;
*'''MUX0 (Analog Channel and Gain Selection Bit 0)'''&amp;lt;br/&amp;gt;Siehe '''MUX3''' für eine Beschreibung.&lt;br /&gt;
&lt;br /&gt;
=== ADCL / ADCH ===&lt;br /&gt;
&lt;br /&gt;
Desweiteren gibt es noch die Register '''ADCL/ADCH''' hier steht das Ergebnis einer Wandlung. Man liest den Wert folgendermaßen aus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 uint16_t x = ADCL;&lt;br /&gt;
 x += (ADCH&amp;lt;&amp;lt;8);&lt;br /&gt;
 // oder&lt;br /&gt;
 x = ADCW;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[Atmel]]&lt;br /&gt;
* [[HEX Beispiel-Dateien für AVR]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/products/param_table.asp?family_id=607&amp;amp;OrderBy=part_no&amp;amp;Direction=ASC Aktuelle AVR Vergleichstabelle]&lt;br /&gt;
* [http://www.atmel.com/dyn/products/devices.asp?family_id=607 Die Datenblätter zu Atmel Controllern]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=9913</id>
		<title>TWI Praxis</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI_Praxis&amp;diff=9913"/>
				<updated>2006-12-26T18:03:28Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: neues Programm bei Master&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das TWI-Hardwaremodul der AVRs zu verwenden.&lt;br /&gt;
Näheres zu [[TWI]] und [[I2C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
Die Beispiele sind zwar in Bascom Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Übertragungsarten =&lt;br /&gt;
&lt;br /&gt;
Bei TWI gibt es die folgenden Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Master =&lt;br /&gt;
[[Bild:I2C_PCF8574_RN-Control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' zuständig. Mit der Formel auf der ''[[TWI#Bit Rate Generator|Bit Rate Generator]]'' Seite müssen sie den Wert für das Register ''TWBR'' berechnen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Transmitter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Call Twi_send_byte(&amp;amp;H40 , B)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI send_byte}}&lt;br /&gt;
 {{vbcomment|sendet ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Sub Twi_send_byte(byval slave As Byte , Zeichen As Byte)&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave And &amp;amp;HFE                               {{vbcomment|slave adresse + Write}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H20 Then&lt;br /&gt;
             Twdr = Zeichen                                  {{vbcomment|Daten}}&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Zeichen wurden gesendet}}&lt;br /&gt;
             If Twi_status = &amp;amp;H28 Or Twi_status = &amp;amp;H30 Then&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M32def.dat&amp;quot;                                     {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                                         {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                                {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Function Twi_read_byte(byval Slave As Byte) As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim B As Byte                                               {{vbcomment|Zeichen von UART}}&lt;br /&gt;
 Dim X As Byte                                               {{vbcomment|Zeichen von TWI}}&lt;br /&gt;
 Dim Error As Byte                                           {{vbcomment|Fehlermerker}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI Init}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                           {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                                    {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                                   {{vbcomment|Bit Rate Register, 100kHz}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print &amp;quot;TWI Master Receiver&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt (egal welcher Wert, wird nur als Startbutton genutzt)}}&lt;br /&gt;
     Input B&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|ein Byte vom Slave holen}}&lt;br /&gt;
     X = Twi_read_byte(&amp;amp;H40)&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print X ;&lt;br /&gt;
     Print &amp;quot; Error : &amp;quot; ;&lt;br /&gt;
     Print Hex(error)                                        {{vbcomment|error status Ausgeben}}&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI read_byte}}&lt;br /&gt;
 {{vbcomment|holt ein Byte und schliesst die Übertragung ab}}&lt;br /&gt;
 Function Twi_read_byte(slave As Byte) As Byte&lt;br /&gt;
     Error = 0                                               {{vbcomment|Fehler zurücksetzen}}&lt;br /&gt;
 &lt;br /&gt;
     Twi_read_byte = 0                                       {{vbcomment|Wert vorbelegen}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                                       {{vbcomment|TWINT | TWSTA | TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
         Twdr = Slave Or &amp;amp;H01                                {{vbcomment|slave adresse + Read}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
         Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Slave hat sich gemeldet}}&lt;br /&gt;
         If Twi_status = &amp;amp;H40 Then&lt;br /&gt;
             Twcr = &amp;amp;B10000100                               {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                           {{vbcomment|kein ACK (TWEA &amp;amp;#61; 0) senden, weil wir nur ein Byte lesen wollen}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
             Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
             If Twi_status = &amp;amp;H58 Or Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                 Twi_read_byte = Twdr                        {{vbcomment|Daten lesen}}&lt;br /&gt;
                 Error = 0                                   {{vbcomment|kein Fehler}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Error = Twi_status                          {{vbcomment|Fehler}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|kein slave}}&lt;br /&gt;
             Error = Twi_status                              {{vbcomment|Fehler}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|STOPbedingung kommt hier immer im Ablauf, egal welcher Status}}&lt;br /&gt;
         Twcr = &amp;amp;B10010100                                   {{vbcomment|TWINT löschen, STOP senden}}&lt;br /&gt;
         {{vbcomment|nach einem STOP wird TWINT nicht mehr gesetzt,}}&lt;br /&gt;
         {{vbcomment|man darf/kann also nicht darauf warten !}}&lt;br /&gt;
 &lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                                   {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Error = Twi_status                                  {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Function&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr And &amp;amp;HF8                              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
&lt;br /&gt;
=== Transmit und Receive ===&lt;br /&gt;
[[Bild:RN-M8_TWI_DS1621_PCF8574.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
;Senden und Empfangen&lt;br /&gt;
Der Master (Mega8) stösst die Temperaturmessung des DS1621 an, liest die Tempetatur aus, sendet den Temperaturwert anschliessend an einen PCF8574 zur Anzeige an dessen LEDs.&lt;br /&gt;
&lt;br /&gt;
Zur Kontrolle werden die Daten auch per UART übertragen und an den LEDs des RN-Meaga8 angezeigt.&lt;br /&gt;
&lt;br /&gt;
Während der Übertragung wird die Busgeschwindigkeit geändert, da der DS1621 mit 400kHz kommunizieren kann, der PCF8574 nur mit 100kHz.&lt;br /&gt;
&lt;br /&gt;
Dieses Programm wird auch zum testen im Artikel [[Bascom und USI-Kommunikation]] verwendet, dort ist dann ein [[ATtiny2313|ATTiny2313]] einer der Slaves.&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Daten vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|TWI Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|TWI ohne Interrupt}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;M8def.dat&amp;quot;                            {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 16000000                               {{vbcomment|frequency used}}&lt;br /&gt;
 $baud = 9600                                      {{vbcomment|baud rate}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                           {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_errorstate As Byte                        {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Anzahlbuf As Byte                             {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                   {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                     {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Config Portb.0 = Output&lt;br /&gt;
 Config Portb.1 = Output&lt;br /&gt;
 Config Portd = Output&lt;br /&gt;
 &lt;br /&gt;
 Const Device = &amp;amp;H90&lt;br /&gt;
 Const Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI initialisieren}}&lt;br /&gt;
 Twcr = &amp;amp;B00000100                                 {{vbcomment|erstmal nur TWI aktivieren}}&lt;br /&gt;
 Twsr = 0                                          {{vbcomment|Status und Prescaler Register}}&lt;br /&gt;
 Twbr = 72                                         {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                        {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Sound Portb.0 , 300 , 450                         {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Startausgabe}}&lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;TWI Master DS1621 Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Portb.0 = 1                                       {{vbcomment|Damit die LED ausgeht nach dem Beep}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
     Twbr = 12                                     {{vbcomment|Bit Rate Register 400kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                        {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                          {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate = 0 Then                    {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         Waitms 1                                  {{vbcomment|Etwas warten bis die Temperatur gemessen ist}}&lt;br /&gt;
         Messagebuf(1) = Device                    {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                      {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate = 0 Then                {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread            {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Twi_errorstate = 0 Then            {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
                 {{vbcomment|STOP senden}}&lt;br /&gt;
                 Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Wert an den LEDs anzeigen}}&lt;br /&gt;
                 Portd.7 = Not Lowtemp.5&lt;br /&gt;
                 Portd.6 = Not Lowtemp.4&lt;br /&gt;
                 Portd.5 = Not Lowtemp.3&lt;br /&gt;
                 Portd.4 = Not Lowtemp.2&lt;br /&gt;
                 Portd.3 = Not Lowtemp.1&lt;br /&gt;
                 Portd.2 = Not Lowtemp.0&lt;br /&gt;
                 Portb.1 = Not Hightemp.7&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Twi_errorstate &amp;lt;&amp;gt; 0 Then                   {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
     Else&lt;br /&gt;
         Twbr = 72                                 {{vbcomment|Bit Rate Register 100kHz @ 16MHz}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Einem evtl. angeschlossenem PCF8574 den Temperaturwert senden}}&lt;br /&gt;
         Messagebuf(1) = &amp;amp;H40&lt;br /&gt;
         Messagebuf(2) = Not Lowtemp&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Twi_start_transceiver&lt;br /&gt;
         {{vbcomment|STOP senden}}&lt;br /&gt;
         Gosub Twi_stop&lt;br /&gt;
 &lt;br /&gt;
         If Twi_errorstate &amp;lt;&amp;gt; 0 Then               {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
             Print &amp;quot;Error2 &amp;quot; ; Hex(twi_errorstate)&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Wait 2&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 {{vbcomment|TWI Transmit and receive function.}}&lt;br /&gt;
 Sub Twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung}}&lt;br /&gt;
     Twcr = &amp;amp;B10100100                             {{vbcomment|TWINT, TWSTA, TWEN}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
     Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben}}&lt;br /&gt;
     If Twi_status = &amp;amp;H08 Or Twi_status = &amp;amp;H10 Then&lt;br /&gt;
 &lt;br /&gt;
         Rw = Messagebuf(1).0                      {{vbcomment|RW-Flag holen für Abfrage unten}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
         For Cnt = 1 To Anzahlbuf&lt;br /&gt;
             {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
             {{vbcomment|Print Cnt ; &amp;quot; &amp;quot; ; Messagebuf(cnt) ; &amp;quot; &amp;quot; ; Rw}}&lt;br /&gt;
             If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
                 {{vbcomment|Write Slaveadr}}&lt;br /&gt;
                 Twdr = Messagebuf(cnt)&lt;br /&gt;
                 Twcr = &amp;amp;B10000100                 {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Beim 1. Byte wird ein anderer Status erwartet}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     {{vbcomment|Slave hat sich gemeldet, $20 ist NACK, $18 WriteACK, $40 ReadACK !}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H18 Or Twi_status = &amp;amp;H40 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         {{vbcomment|kein Slave}}&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Zeichen wurde gesendet, $30 ist NACK}}&lt;br /&gt;
                     If Twi_status = &amp;amp;H28 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             Else&lt;br /&gt;
                 {{vbcomment|Read a Byte}}&lt;br /&gt;
                 {{vbcomment|Wenn das letzte Byte gesendet wird, ein NACK mitgeben um das Ende anzuzeigen}}&lt;br /&gt;
                 If Cnt = Anzahlbuf Then&lt;br /&gt;
                     {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
                     Twcr = &amp;amp;B10000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Load ACK. TWEA ist 1}}&lt;br /&gt;
                     Twcr = &amp;amp;B11000100             {{vbcomment|TWINT löschen, Byte senden}}&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|warten bis TWINT gesetzt ist}}&lt;br /&gt;
                 Gosub Twi_wait_int&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|ein Byte wurde empfangen}}&lt;br /&gt;
                 Messagebuf(cnt) = Twdr            {{vbcomment|Daten lesen}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Byte empfangen und mit ACK quittiert, sonst Ende}}&lt;br /&gt;
                 If Twi_status = &amp;amp;H50 Then&lt;br /&gt;
                     Twi_errorstate = 0            {{vbcomment|kein Fehler}}&lt;br /&gt;
                 Else&lt;br /&gt;
                     {{vbcomment|Beim letzten Byte auch mit NACK quittieren}}&lt;br /&gt;
                     If Cnt = Anzahlbuf And Twi_status = &amp;amp;H58 Then&lt;br /&gt;
                         Twi_errorstate = 0        {{vbcomment|kein Fehler}}&lt;br /&gt;
                     Else&lt;br /&gt;
                         Twi_errorstate = Twi_status   {{vbcomment|Fehler}}&lt;br /&gt;
                         Exit For&lt;br /&gt;
                     End If&lt;br /&gt;
 &lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         Next Cnt&lt;br /&gt;
     Else&lt;br /&gt;
         {{vbcomment|Ist der Bus belegt, wird er wieder freigegeben}}&lt;br /&gt;
         Twcr = &amp;amp;B10000100                         {{vbcomment|TWINT löschen, Bus freigeben}}&lt;br /&gt;
         Twi_errorstate = Twi_status               {{vbcomment|Fehler}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|warten bis TWINT gesetzt ist, status auslesen}}&lt;br /&gt;
 Twi_wait_int:&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H80&lt;br /&gt;
     Loop Until Twi_control = &amp;amp;H80&lt;br /&gt;
 &lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
 {{vbcomment|   Print &amp;quot;Err &amp;quot; ; Hex(twi_status)}}&lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Stopsequenz ausgeben}}&lt;br /&gt;
 Twi_stop:&lt;br /&gt;
     Twcr = &amp;amp;B10010100                             {{vbcomment|TWINT löschen, Stop senden}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Warten bis Stop-Flag wieder gelöscht wird, dann ist die Stopsequenz abgeschlossen}}&lt;br /&gt;
     Do&lt;br /&gt;
         Twi_control = Twcr And &amp;amp;H10&lt;br /&gt;
     Loop Until Twi_control = 0&lt;br /&gt;
     {{vbcomment|Es muss nicht unbedingt darauf gewartet werden}}&lt;br /&gt;
     {{vbcomment|wenn die nächste Aktion nicht gleich anschliessend durchgeführt wird.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Einen speziellen STOP-Status gibt es nicht, es ist in der Regel &amp;amp;HF8}}&lt;br /&gt;
     Twi_status = Twsr                             {{vbcomment|status}}&lt;br /&gt;
     Twi_status = Twi_status And &amp;amp;HF8              {{vbcomment|status}}&lt;br /&gt;
     {{vbcomment|Print Hex(twi_status)}}&lt;br /&gt;
 &lt;br /&gt;
 Return&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Slave =&lt;br /&gt;
[[Bild:I2C_RN-M8_RN-control.jpg|thumb|Beispielumgebung]]&lt;br /&gt;
Da der TWI-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATMega32|Mega32]], und als Slave das [[RN-Mega8]] Board verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Count As Byte                                           {{vbcomment|Testwert, jedes mal +1}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Werte zurücksetzen}}&lt;br /&gt;
 Count = 0&lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|will der Master ein Byte haben}}&lt;br /&gt;
         If Twi_status = &amp;amp;HA8 Or Twi_status = &amp;amp;HB8 Then&lt;br /&gt;
             Twdr = Count                                    {{vbcomment|neue Daten ausgeben}}&lt;br /&gt;
             Incr Count                                      {{vbcomment|testwert +1}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, mit ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortD aus, an dem beim RN-M8 eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 $regfile = &amp;quot;m8def.dat&amp;quot;                                      {{vbcomment|the used chip}}&lt;br /&gt;
 $crystal = 7372800                                          {{vbcomment|frequency used}}&lt;br /&gt;
 {{vbcomment|$baud &amp;amp;#61; 9600                                              ' keine baud rate angeben !}}&lt;br /&gt;
 &lt;br /&gt;
 Config Portd = Output                                       {{vbcomment|kompletter PortD als Ausgang}}&lt;br /&gt;
 &lt;br /&gt;
 Dim Twi_control As Byte                                     {{vbcomment|Controlregister lokale kopie}}&lt;br /&gt;
 Dim Twi_status As Byte&lt;br /&gt;
 Dim Twi_data As Byte&lt;br /&gt;
 &lt;br /&gt;
 Dim Neuesbyte As Byte                                       {{vbcomment|Bytemerker}}&lt;br /&gt;
 &lt;br /&gt;
 Declare Sub Twi_init_slave&lt;br /&gt;
 &lt;br /&gt;
 Twi_data = 0&lt;br /&gt;
 Call Twi_init_slave                                         {{vbcomment|TWI aktivieren}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|alle LEDs ein}}&lt;br /&gt;
 Portd = 0&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptschleife}}&lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|hier könnte ihr Code stehen}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Merker zurücksetzen}}&lt;br /&gt;
     Neuesbyte = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|schauen ob TWINT gesetzt ist}}&lt;br /&gt;
     Twi_control = Twcr And &amp;amp;H80                             {{vbcomment|Bit7 von Controlregister}}&lt;br /&gt;
 &lt;br /&gt;
     If Twi_control = &amp;amp;H80 Then&lt;br /&gt;
         Twi_status = Twsr And &amp;amp;HF8                          {{vbcomment|Status}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|wurde ein Byte geschickt}}&lt;br /&gt;
         If Twi_status = &amp;amp;H80 Or Twi_status = &amp;amp;H88 Then&lt;br /&gt;
             Twi_data = Twdr                                 {{vbcomment|neue Daten merken}}&lt;br /&gt;
             Neuesbyte = 1                                   {{vbcomment|merken das ein neues Byte da ist}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht}}&lt;br /&gt;
         Twcr = &amp;amp;B11000100                                   {{vbcomment|TWINT löschen, erzeugt ACK}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|wenn ein neues Byte gekommen ist, dieses an PortD ausgeben}}&lt;br /&gt;
     If Neuesbyte &amp;lt;&amp;gt; 0 Then&lt;br /&gt;
         Portd = Twi_data                                    {{vbcomment|Daten auf PortD ausgeben}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme}}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|TWI als slave aktivieren}}&lt;br /&gt;
 Sub Twi_init_slave&lt;br /&gt;
     Twsr = 0                                                {{vbcomment|status und Prescaler auf 0}}&lt;br /&gt;
     Twdr = &amp;amp;HFF                                             {{vbcomment|default}}&lt;br /&gt;
     Twar = &amp;amp;H40                                             {{vbcomment|Slaveadresse setzen}}&lt;br /&gt;
     Twcr = &amp;amp;B01000100                                       {{vbcomment|TWI aktivieren, ACK einschalten}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
Der Slave ist hier sogar in der Lage während einer Übertragung mehr als ein Byte entgegenzunehmen, da jedes Byte den gleichen Status erzeugt.&lt;br /&gt;
&lt;br /&gt;
Wenn der Slave schnell genug getaktet wird (&amp;gt; 6.4 MHz), kann der Master auch auf einen schnelleren Bus-Takt gestellt werden. Dazu beim Master das ''TWBR'' auf 12 setzen, so wird der Bus mit 400kHz betrieben.&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
* [[I2C]]&lt;br /&gt;
* [[TWI]]&lt;br /&gt;
* [[TWI Praxis Multimaster]]&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[Bascom und USI-Kommunikation]] - I2C Beispiele mit Bascom und dem USI-Modul&lt;br /&gt;
&lt;br /&gt;
= WebLinks =&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs C-Quellbibliothek für einen TWI-Master von Peter Fleury (avr-gcc)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 15:31, 15. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:RN-M8_TWI_DS1621_PCF8574.jpg&amp;diff=9912</id>
		<title>Datei:RN-M8 TWI DS1621 PCF8574.jpg</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:RN-M8_TWI_DS1621_PCF8574.jpg&amp;diff=9912"/>
				<updated>2006-12-26T17:01:53Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Testumgebung für I2C.
Mit RN-Mega8 über I2C einen DS1621 abfragen und den PCF8574 ansteuern.
TWI eines AVR verwenden.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Testumgebung für I2C.&lt;br /&gt;
Mit RN-Mega8 über I2C einen DS1621 abfragen und den PCF8574 ansteuern.&lt;br /&gt;
TWI eines AVR verwenden.&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=9911</id>
		<title>USI (Avr)</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=USI_(Avr)&amp;diff=9911"/>
				<updated>2006-12-26T16:27:02Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: USICR Taktquelle Timer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;USI ('''U'''niversal '''S'''erial '''I'''nterface) steht für Universelle serielle Schnittstelle, die vor allem in kleineren Atmel AVR Controllern, wie zB. beim [[ATtiny2313|ATTiny2313]], aber auch in einigen ATMegas anzutreffen ist.&lt;br /&gt;
&lt;br /&gt;
Wie der Name schon aussagt, kann diese Schnittstelle universell eingestellt werden um unterschiedliche Funktionen auszuführen. Hauptsächlich gedacht um verschiedene Arten der seriellen Kommunikation auszuüben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Hauptfunktionen =&lt;br /&gt;
Die Hauptfunktionen sind&lt;br /&gt;
* Three-wire Modus, bzw. [[SPI]]&lt;br /&gt;
* Two-wire Modus, bzw. [[TWI]] oder [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Alternative Funktionen =&lt;br /&gt;
Wenn die Schnittstelle nicht für die serielle Kommunikation verwendet wird, gibt es, wegen der universellen Auslegung, weitere Möglichkeiten sie trotzdem zu verwenden. Dies wären:&lt;br /&gt;
* Halb-Duplex Asynchrone Datenübertragung&lt;br /&gt;
* 4-Bit Counter (0-15) mit verschiedenen Taktquellen&lt;br /&gt;
* 12-Bit Timer/Counter in Verbindung mit Timer0&lt;br /&gt;
* externer Interrupt, löst bei jeder Flanke aus&lt;br /&gt;
* Software Interrupt, kann durch setzen in einem USI-Register ausgelöst werden&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= USI-Register =&lt;br /&gt;
Hier eine kurze Beschreibung der für den USI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== USIDR ====&lt;br /&gt;
:USI Data Register, alle 8 bit&lt;br /&gt;
:Über dieses Register wird direkt auf das serielle Register zugegriffen, ohne Puffer dazwischen, auch während gerade ein Byte übertragen wird, anders als bei ''echtem'' TWI !&lt;br /&gt;
&lt;br /&gt;
==== USISR ====&lt;br /&gt;
:USI Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIF|USIOIF|USIPF|USIDC|USICNT3|USICNT2|USICNT1|USICNT0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Das Statsregister enthält die Interruptflags, den Status der Datenleitungen und den 4-Bit Counter&lt;br /&gt;
:*'''USISIF''' Startbedingung Interrupt Flag&lt;br /&gt;
::Bei TWI: Wenn eine Startbedingung erkannt wurde, wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USISIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Anderer Modus: Bei externer Takquelle wird bei jeder Flanke an USCK dieses Flag gesetzt.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIOIF''' Counter Overflow Interrupt Flag&lt;br /&gt;
::Wenn der Counter überläuft (15 + 1), wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''USIOIE'' im ''Controlregister'' gesetzt ist.&lt;br /&gt;
::Bei TWI: Die Taktleitung wird solange gehalten, bis das Flag zurückgesetzt wird, siehe auch [[Clock Stretching]].&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIPF''' Stopbedingung Interrupt Flag (nur bei TWI)&lt;br /&gt;
::Wenn eine Stopbedingung erkannt wurde, wird dieses Flag gesetzt, es kann kein Interrupt generiert werden. &lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
:*'''USIDC''' Data Output Collision (nur bei TWI)&lt;br /&gt;
::Tritt auf, wenn gleichzeitg ein anderer Busteilnehmer auf den Bus zugreift (Multimaster).&lt;br /&gt;
:*'''USICNTx''' Wert des 4-Bit-Zählers&lt;br /&gt;
::Aktueller Wert des Zählers, kann jederzeit gelesen oder neu beschrieben werden. Zählt bei jeder Flanke (fallend oder steigend) der Taktquelle um eins hoch (siehe ''USICSx'' im ''Controlregister'').&lt;br /&gt;
&lt;br /&gt;
==== USICR ====&lt;br /&gt;
:USI Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|USISIE|USIOIE|USIWM1|USIWM0|USICS1|USICS0|USICLK|USITC}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Im Controlregister wird der Modus eingestellt, Taktquelle ausgewählt und Interruptanforderungen aktiviert&lt;br /&gt;
:*'''USISIE''' Startbedingung Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn eine Startbedingung erkannt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIOIE''' Counter Overflow Interrupt ermöglichen (nur bei TWI)&lt;br /&gt;
::Wenn ein Zählerüberlauf aufgetreten ist und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
:*'''USIWMx''' Modus wählen:&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USIWM1 || USIWM0 || Modus&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| kein Modus&amp;lt;br&amp;gt;PortPins können normal verwendet werden.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| Three-wire Modus, bzw. [[SPI]]&amp;lt;br&amp;gt;Es werden die Pins DO, DI und USCK verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Master und Slave&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 &lt;br /&gt;
|align=&amp;quot;left&amp;quot;| [[TWI]] für Slave,&amp;lt;br&amp;gt;Es werden die Pins SDA und SCL verwendet.&amp;lt;br&amp;gt;Gleicher Modus wie '''10''' bis auf diese Zusatzfunktion:&amp;lt;br&amp;gt;Die Taktleitung wird beim Zählerüberlauf gehalten&amp;lt;br&amp;gt;bis die Software dieses freigibt (''USIOIF'' = 1),&amp;lt;br&amp;gt;siehe auch [[Clock Stretching]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USICSx''' Taktquelle wählen (in Verbindung mit USICLK):&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| USICS1 || USICS0 || USICLK || Takquelle&amp;lt;br&amp;gt;Schieberegister || Taktquelle&amp;lt;br&amp;gt;Counter&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 0 || keine Taktquelle || keine Taktquelle&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 0 || 1 || Software (USICLK) || Software (USICLK)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 1 || X || Timer/Counter0 || Timer/Counter0 &lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 0 || extern, positive Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 0 || extern, negative Flanke || extern, beide Flanken&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 0 || 1 || extern, positive Flanke || Software (USITC)&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 1 || 1 || extern, negative Flanke || Software (USITC)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::Ist der Timer0 als Taktquelle ausgewählt, kann je nach AVR ein Timerüberlauf, oder ein Comparematch den Impuls für das USI-Modul auslösen.&lt;br /&gt;
::Die Taktleitung SCL muss dabei jeweils per Software umgeschaltet (getoggelt) werden, am einfachsten  in einer Timer-ISR ''USITC'' setzen.&lt;br /&gt;
&lt;br /&gt;
:*'''USICLK''' Clock Strobe&lt;br /&gt;
::Bei Softwaretakt, wird beim setzen dieses Bits das Schieberegister (''USIDR'') um ein Bit weitergeschoben und der Counter um eins hochgezählt. Der Ausgang wechselt noch im gleichen CPU-Takt auf den neuen Bitwert.&lt;br /&gt;
::Bei externer Taktquelle siehe vorhergehende Tabelle für die Verwendung von USICLK.&lt;br /&gt;
::Das auslesen von USICLK ergibt immer 0.&lt;br /&gt;
:*'''USITC''' Toggle Clock Port Pin&lt;br /&gt;
::Beim setzen wird der Zustand von USCK/SCL gewechselt (0-&amp;gt;1 oder 1-&amp;gt;0)&lt;br /&gt;
::Bei externer Taktquelle (siehe Tabelle bei USICSx) kann der 4-Bit-Zähler um eins hochgezählt werden.&lt;br /&gt;
::Das auslesen von USITC ergibt immer 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ganz neuen AVR Tiny Controllern (wie dem ATTiny261) sind zwei weitere Register zu finden:&lt;br /&gt;
&lt;br /&gt;
==== USIBR ====&lt;br /&gt;
:USI Buffer Register, alle 8 bit&lt;br /&gt;
:Dieses Register kann nur gelesen werden, entspricht aber eigentlich dem USIDR-Register. Es hat den Vorteil, das das letzte empfangene Byte hier gehalten wird, und die zeitliche Abfolge zum auslesen der Daten aus USIDR nicht mehr so kritisch ist, da zB. nach einem ACK bei TWI das USIDR schon um ein Bit weitergeschoben wird.&lt;br /&gt;
&lt;br /&gt;
==== USIPP ====&lt;br /&gt;
:USI Pin Position&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|&amp;amp;ndash;|USIPOS}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''USIPOS''' USI Pin Position&lt;br /&gt;
::Es ist möglich, die Datenleitungen auf einen alternativen Port zu legen, wenn dieses Bit gesetzt wird. Die alternative Position ist aber auch festgelegt, man schaltet nur zwischen den Möglichkeiten um.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Baustelle =&lt;br /&gt;
{{Baustelle|Linux_80}}&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 19:19, 18. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=9910</id>
		<title>TWI</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=TWI&amp;diff=9910"/>
				<updated>2006-12-26T15:03:03Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: im Detail optimiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TWI ('''T'''wo-'''w'''ire Serial '''I'''nterface) ist eine Bezeichnung von [[Atmel|Atmel]] für die auf vielen [[AVR|AVR]] Megas vorhandene  [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Hardware.&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel soll nur auf Besonderheiten der [[AVR]]-[[Microcontroller]] eingegangen werden, Einzelheiten zu [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] finden sich in den entsprechenden Artikeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
= Merkmale =&lt;br /&gt;
&lt;br /&gt;
* Master- und Slavemodus&lt;br /&gt;
* Multimaster&lt;br /&gt;
* 7-Bit Adressierung (als Master möglicherweise auch 10-Bit Adressierung)&lt;br /&gt;
* Übertragungsrate von bis zu 400kBit/s&lt;br /&gt;
&lt;br /&gt;
= TWI verwenden =&lt;br /&gt;
Um TWI mit dem [[AVR]] verwenden zu können sind einige Einstellungen nötig, die hier in Abhängigkeit der Anwendung aufgezeigt werden.&lt;br /&gt;
&lt;br /&gt;
== TWI-Register ==&lt;br /&gt;
Hier eine kurze Beschreibung der für den TWI Betrieb notwendigen Register&lt;br /&gt;
&lt;br /&gt;
==== TWBR ====&lt;br /&gt;
:Bit Rate Register, alle 8 bit&lt;br /&gt;
:dient zum einstellen des Bus-Taktes als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWCR ====&lt;br /&gt;
:Control Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWINT|TWEA|TWSTA|TWSTO|TWWC|TWEN|&amp;amp;ndash;|TWIE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:die Hauptschaltstelle befindet sich hier,&lt;br /&gt;
:*'''TWINT''' TWI Interrupt Flag&lt;br /&gt;
::Nach Abarbeitung der letzten Aktion wird dieses Flag gesetzt, und ein Interrupt ausgelöst falls ''TWIE'' gesetzt ist.&lt;br /&gt;
::Es sollte anschliessend das Datenregister und das Statusregister ausgelesen werden und darauf entsprechend reagiert werden.&lt;br /&gt;
::Um das Flag zurückzusetzen muss es gesetzt werden.&lt;br /&gt;
::Mit dem zurücksetzen (löschen) von ''TWINT'' wird die nächste Aktion ausgelöst, es müssen deshalb vorher alle notwendigen Flags und Register (zB. ''TWDR'') entsprechend gesetzt werden.&lt;br /&gt;
:*'''TWEA''' TWI Enable Acknowledge Bit&lt;br /&gt;
::Sendet ein ACK nach einer Übertragung wenn&lt;br /&gt;
:::*als Slave die eigene Slaveadresse (''TWAR'') erkannt wurde,&lt;br /&gt;
:::*ein General Call erkannt wurde und das ''TWGCE''-Flag in ''TWAR'' gesetzt ist,&lt;br /&gt;
:::*ein ganz normales Byte als Slave oder als Master empfangen wurde.&lt;br /&gt;
:*'''TWSTA''' TWI Start Sequenz senden&lt;br /&gt;
::Die TWI-Hardware überprüft ob der Bus frei ist, und gibt die Startsequenz aus.&lt;br /&gt;
::Ist der Bus nicht frei, wartet das TWI-Modul bis eine Stopsequenz erkannt wurde und sendet die Startsequenz erneut.&lt;br /&gt;
::Dieses Flag muss per Software wieder gelöscht werden.&lt;br /&gt;
:*'''TWSTO''' TWI Stop Sequenz senden&lt;br /&gt;
::Als Master wird durch setzen eine Stopsequenz ausgegeben. Ist die Stopsequenz gesendet wird das Flag automatisch gelöscht.&lt;br /&gt;
::Als Slave kann dieses Flag zum zurücksetzen nach einem Fehler verwendet werden. Es wird keine Stopsequenz ausgegeben, aber das Modul beeinflusst anschliessend nicht mehr die Leitungen SCL oder SDA, das TWI-Modul befindet sich in einem definierten unadressierten Zustand.&lt;br /&gt;
:*'''TWWC''' TWI Write Collision Flag&lt;br /&gt;
::In das Datenregister ''TWDR'' sollte man nur schreiben, wenn ''TWINT'' High ist, ist ''TWINT'' Low, wird dieses Flag gesetzt und zeigt einen Fehler an.&lt;br /&gt;
:*'''TWEN''' TWI Enable&lt;br /&gt;
::Aktivieren des TWI-Moduls. Das TWI-Modul übernimmt u.a. die Steuerung über die Leitungen SCL und SDA.&lt;br /&gt;
:*'''TWIE''' TWI Interrupt Anforderung erlauben&lt;br /&gt;
::Interruptanforderung aktivieren, wenn eine Aktion durchgeführt wurde und global Interrupts erlaubt sind, wird ein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==== TWSR ====&lt;br /&gt;
:Status Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWS7|TWS6|TWS5|TWS4|TWS3|&amp;amp;ndash;|TWPS1|TWPS0}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWSx''' TWI Status&lt;br /&gt;
::die oberen 5 Bit geben den Status der letzten Aktion wieder&lt;br /&gt;
:*'''TWPSx''' TWI Prescaler&lt;br /&gt;
::die zwei niederwertigen Bit zum einstellen des Prescaler als Master, siehe [[#Bit_Rate_Generator|Bit Rate Generator]]&lt;br /&gt;
&lt;br /&gt;
==== TWDR ====&lt;br /&gt;
:Data Register, alle 8 bit&lt;br /&gt;
:Beim Senden: nächstes Byte, das auf den Bus ausgegeben werden soll&lt;br /&gt;
:Beim Empfangen: letztes Byte, das über den Bus gekommen ist&lt;br /&gt;
:Die Daten sind gültig, solange das Bit ''TWINT'' in ''TWCR'' gesetzt ist&lt;br /&gt;
&lt;br /&gt;
==== TWAR ====&lt;br /&gt;
:Slave Address Register&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWA6|TWA5|TWA4|TWA3|TWA2|TWA1|TWA0|TWGCE}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:*'''TWAx''' Slave Adresse&lt;br /&gt;
::Wird der [[AVR]] als Slave eingesetzt, wird in den oberen 7 Bit die Adresse eingetragen, auf die reagiert werden soll.&lt;br /&gt;
:*'''TWGCE''' General Call Enable&lt;br /&gt;
::Setzt man Bit0, kann zusätzlich auf einen ''General Call'' reagiert werden.&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
==== TWAMR ====&lt;br /&gt;
:Slave Address Mask Register&lt;br /&gt;
:Zus&amp;amp;auml;tzlich zu den schon geannten Registern, kann es bei einigen ATMegas, wie dem [[ATMega168]], dieses Register geben, in der Regel hat es aber den Standardwert von $00, wobei sich das TWI-Modul verh&amp;amp;auml;lt wie bei den anderen ATMegas.&lt;br /&gt;
:Mit dem setzen von einzelnen Bits werden beim vergleich der Slaveadresse (die vom Master gesendet wurde) mit ''TWAR'' diese Bits ausmaskiert, dH. treffen immer zu, was bedeutet, dass der ATMega auf mehr als nur einer bestimmten Slaveadresse (''TWAR'') angesprochen werden kann.&lt;br /&gt;
:Werden zB. alle Bits gesetzt, fühlt sich der [[AVR]] immer angesprochen, egal welche Slaveadresse über den Bus gesendet wurde.&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;{{Registertabelle8BitFix|TWAM6|TWAM5|TWAM4|TWAM3|TWAM2|TWAM1|TWAM0|&amp;amp;ndash;}}&amp;lt;/div&amp;gt;&lt;br /&gt;
:Wird der [[AVR]] als Slave eingesetzt, kann in den oberen 7 Bit die Adressmaske eingetragen werden,&lt;br /&gt;
:als Master ist es unbenutzt&lt;br /&gt;
&lt;br /&gt;
== Übertragungsarten ==&lt;br /&gt;
Bei TWI gibt es diese Übertragungsarten&lt;br /&gt;
* Master Transmitter (nur Senden)&lt;br /&gt;
* Master Receiver (nur Empfangen)&lt;br /&gt;
* Slave Transmitter (auf Abruf Senden)&lt;br /&gt;
* Slave Receiver (nur Empfangen)&lt;br /&gt;
Abhängig von der Anwendung kann der [[AVR]] alle Arten der Übertragung im gleichen Programm ausführen.&lt;br /&gt;
&lt;br /&gt;
== Master ==&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Bestimmung der Bus-Geschwindigkeit ist der ''Bit Rate Generator'' zuständig.&lt;br /&gt;
&lt;br /&gt;
=== Bit Rate Generator ===&lt;br /&gt;
Zur Übertragung gibt es die Bitraten ''Standard'', mit bis zu 100kBit/s, und ''FastMode'', mit bis zu 400kBit/s.&lt;br /&gt;
Der Master muss immer den Takt erzeugen, der bei Bedarf auf der Leitung SCL angelegt wird.&lt;br /&gt;
Der SCL-Takt ist beim AVR abhängig von der CPU-Frequenz.&lt;br /&gt;
Da [[I2C]], im Gegensatz zu [[RS232]], ein synchrones Protokoll ist, das mit dem Taktsignal SCL arbeitet, muss man nicht exakt auf eine Frequenz von 100kHz bzw. 400kHz kommen.&lt;br /&gt;
&lt;br /&gt;
Im TWI-Modul des AVR gibt es zwei Stellen, an denen man die Teilung der Frequenz einstellen kann:&lt;br /&gt;
* die ''Prescaler Bits'' (TWPS), diese 2 Bits befinden sich im ''TWI Status Register'' (TWSR)&lt;br /&gt;
* für die genauere Einstellung das ''TWI Bit Rate Register'' (TWBR)&lt;br /&gt;
&lt;br /&gt;
'''Formel zur Berechnung der SCL-Frequenz:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{SCL{-}Frequenz =  \frac{CPU{-}Frequenz}{16 + 2 \cdot TWBR \cdot 4^{TWPS} } }&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da ein AVR zur Zeit max. mit 20MHz getaktet werden kann, ist es nicht nötig, den Prescaler zu benutzen, bzw. er wird auf den Teiler 1 gestellt, was keiner Teilung entspricht. Mit diesem Teiler können alle CPU-Frequenzen und TWI-Takte abgedeckt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|+ '''Mögliche&amp;amp;nbsp;Prescaler-Werte'''&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bit-Wert || Teiler&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|00 ||1&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|01 ||4&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|10 ||16&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|11 ||64&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die Werte von TWBR gehen von theoretisch 0 bis 255. Laut [[Atmel]] soll der Wert aber mind. 10 Betragen, da es sonst zu Problemen bei der Übertragung kommen kann.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel-Berechnung''':&lt;br /&gt;
&lt;br /&gt;
Es soll eine SCL-Frequenz von 100kHz erzeugt werden, die CPU-Frequenz beträgt 8MHz, der Teiler (Prescaler) ist &amp;amp;ndash; wie oben erwähnt &amp;amp;ndash; auf 1 (TWPS = 0).&lt;br /&gt;
&lt;br /&gt;
Laut der Formel ergibt das dann:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100kHz = 8.0MHz / (16 + 2 * x * 4^0 )    / 1 fällt weg&lt;br /&gt;
100kHz = 8.0MHz / (16 + 2 * x )          / *(16 + 2 * x )&lt;br /&gt;
100kHz * (16 + 2 * x ) = 8000kHz         / kürzen  / : 100&lt;br /&gt;
16 + 2 * x  = 80                         / -16&lt;br /&gt;
2 * x  = 64                              / :2&lt;br /&gt;
x = 32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
;Ergebnis: Der Wert für TWBR muss 32 sein, damit die SCL-Frequenz 100kHz ergibt, bei 8MHz CPU-Frequenz.&lt;br /&gt;
&lt;br /&gt;
'''Es Ergibt sich somit folgende Formel zum Berechnen von TWBR:'''&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\mathrm{TWBR = \frac{ \frac {CPU{-}Frequenz}{SCL{-}Frequenz} - 16}{2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kommt ein Wert kleiner 10 heraus, kann ein höherer CPU-Takt gewählt werden, oder falls das nicht möglich ist, wird der Bus mit einem geringeren Takt betrieben, was trotzdem innerhalb der Spezifikation liegt. Wird eine krumme CPU-Frequenz verwendet, die kein ganzzahliges Ergebnis zur Folge hat, kann man mit der ersten Formel überprüfen, ob der Wert auf- oder abgerundet wird. Auf der sicheren Seite ist man, wenn der Wert aufgerundet wird. Das entspricht einer grösseren Teilung, also eine geringfügig kleinere Bitrate und liegt deshalb im Standard.&lt;br /&gt;
&lt;br /&gt;
== Slave ==&lt;br /&gt;
Um den AVR als Slave zu konfigurieren sind nur diese wenigen Schritte notwendig:&lt;br /&gt;
*gewünschte Slaveadresse im ''Address Register'' (TWAR) setzen&lt;br /&gt;
*im ''Control Register'' (TWCR)&lt;br /&gt;
**mit TWEN das TWI Modul aktivieren&lt;br /&gt;
**mit TWEA das Senden des Bestätigungsbits (ACK) zulassen&lt;br /&gt;
&lt;br /&gt;
anschliessend als Slave&lt;br /&gt;
*warten, bis im ''Control Register'' (TWCR) das Bit TWINT gesetzt ist, welches anzeigt, daß auf dem Bus was los ist&lt;br /&gt;
*das ''Status Register'' (TWSR) abfragen und entsprechend darauf reagieren&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung zur CPU-Frequenz ===&lt;br /&gt;
&lt;br /&gt;
Da der Master den Takt vorgibt, muss der Slave nur mit dessen Takt am Bus mitlauschen. Um zu gewährleisten, daß der Slave dem Takt folgen kann sollte laut [[Atmel]] die CPU-Frequenz eines ATMega-Slave mind. das 16-fache der Bus-Frequenz betragen.&lt;br /&gt;
&lt;br /&gt;
das ergibt folgende Werte :&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Bus-Frequenz || minimale CPU-Frequenz&lt;br /&gt;
|-&lt;br /&gt;
|100 kHz || 1,6 MHz&lt;br /&gt;
|-&lt;br /&gt;
|400 kHz || 6,4 MHz&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
[http://www.atmel.com/dyn/products/devices.asp?family_id=607 Atmel-AVR-Datenblätter]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[RS232]] - serielle Schnittstelle&lt;br /&gt;
* [[RS485]] - serieller (asynchroner) Bus&lt;br /&gt;
* [[TWI Praxis]] - Programmbeispiele&lt;br /&gt;
* [[USI (Avr)]] - USI Modul mit dem TWI nachgebildet werden kann, ist bei den meisten ATTinys und einigen ATMegas vorhanden.&lt;br /&gt;
* [[RN-Slave ID Übersicht]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 00:52, 6. Jan 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9760</id>
		<title>Bascom und USI-Kommunikation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9760"/>
				<updated>2006-12-03T14:57:18Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: ein wenig umstellen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das [[USI (Avr)|USI]]-Hardwaremodul der [[AVR]]s zu verwenden. Mit dem [[USI (Avr)|USI]]-Modul können die Schnittstellen [[I2C]] ([[TWI]]) und [[SPI]] nachgebildet werden. Näheres zu [[USI (Avr)|USI]], [[I2C]] und [[SPI]] finden sich in den entsprechenden Artikeln. Die Beispiele sind zwar in [[Bascom]] Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Master ==&lt;br /&gt;
[[Bild:USI-I2C_PCF8574_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung mit PCF8574]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Generierung der gewünschten Busgeschwindigkeit ist die Software zuständig, die länge der Pausen zwischen den Takten muss erechnet werden, im Beispielprogramm für ca. 100kHz bei 16MHz CPU-Frequenz.&lt;br /&gt;
Der Takt kann auch mithilfe eines [[Timer/Counter (Avr)|Timer]]s erzeugt werden, dies wird erst zu einem späteren Zeitpunkt mit einem Beispiel gezeigt.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATtiny2313|Tiny2313]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen }}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim B As Byte                                           {{vbcomment|Zeichen von UART oder Testzeichen zum senden über USI}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 B = 0&lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;Tiny2313 USI-TWI-Test&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Messagebuf(1) = &amp;amp;H40                                    {{vbcomment|Adresse von 8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
     {{vbcomment|oder automatisch zählen lassen}}&lt;br /&gt;
     {{vbcomment|Incr B}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Messagebuf(2) = Not B                               {{vbcomment|Not, weil LEDs gegen GND schalten}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     Call Usi_twi_master_stop&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; &amp;quot;&lt;br /&gt;
     Print Hex(usi_twi_errorstate);&lt;br /&gt;
     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
     Print Hex(temp_usisr)&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitms 700  ' Wenn automatisch gezählt werden soll, eine kleine Pause, damit man auch was sehen kann}}&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
==== Unterprogramm nur Senden ====&lt;br /&gt;
&lt;br /&gt;
Die restlichen Subroutinen sind im nächsten Abschnitt zu finden.&lt;br /&gt;
&lt;br /&gt;
Diese Funktion ist nur zum versenden geeignet !&lt;br /&gt;
&lt;br /&gt;
Statt dieser kann auch die Routine von unten genommen werden, die aber etwas mehr Speicherplatz benötigt.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI Transmit Funktion.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Startbedingung ausgeben}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Startbedingung vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Slaveadresse und Daten ausgeben}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|Ein Byte ausgeben}}&lt;br /&gt;
         Pout_usi_scl = 0                                {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
         Usidr = Messagebuf(cnt)&lt;br /&gt;
         Temp_usisr = Temp_usisr_8bit                    {{vbcomment|8Bit ausgeben}}&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|(N)ACK vom Slave lesen}}&lt;br /&gt;
         Ddr_usi_sda = 0                                 {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
         Temp_usisr = Temp_usisr_1bit                    {{vbcomment|1Bit einlesen}}&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|kein ACK gekommen, Slave meldet sich nicht}}&lt;br /&gt;
         If Temp_usisr.0 = 1 Then&lt;br /&gt;
             Usi_twi_errorstate = &amp;amp;H05                   {{vbcomment|Slave hat mit NACK quittiert}}&lt;br /&gt;
             If Cnt = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H06               {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
             End If&lt;br /&gt;
             Exit For                                    {{vbcomment|hier wird die Schleife bei einem NACK verlasssen}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter und Receiver mit DS1621 als Slave ===&lt;br /&gt;
[[Bild:USI-I2C_DS1621_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung mit DS1621]]&lt;br /&gt;
&lt;br /&gt;
;Senden und Empfangen (Repeated Start)&lt;br /&gt;
Im Beispiel wird ein DS1621 Temperatursensor mit I2C-Schnittstelle verwendet.&amp;lt;br&amp;gt;&lt;br /&gt;
Der Master sendet dem Slave ein Kommando, stellt um auf Empfang und holt den Temperaturwert, schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Der Temperaturwert wird über [[UART]] ([[RS232]]) im Klartext ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die Subroutinen sind die gleichen wie für ''Master Transmitter''. Da der DS1621 aber mit 400kHz kommunizieren kann, wurden die ''Waitus'' zwischen den Pegelwechseln weggelassen da die Befehle hier sowieso nicht schnell genug sind, und ein Wait unnötig machen. Sie sind aber als Kommentar eingefügt, damit zu sehen ist an welchen Stellen ansonsten gewartet werden sollte (zB. bei 100kHz).&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Temperaturwert vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&amp;lt;br&amp;gt;&lt;br /&gt;
(Das Beispiel belegt 1418 Byte im Flash, das sind ca. 69% eines Tiny2313 !)&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|Temperatur von DS1621 lesen, und über UART ausgeben}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                           {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Dim Device As Byte&lt;br /&gt;
 Dim Deviceread As Byte&lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Device = &amp;amp;H90&lt;br /&gt;
 Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.5 , 300 , 450                               {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;DS1621-USI Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                              {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                                {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2                                       {{vbcomment|2 Byte ausgeben}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate = 0 Then                      {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
         Call Usi_twi_master_stop&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitms 1}}&lt;br /&gt;
         Messagebuf(1) = Device                          {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                            {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2                                   {{vbcomment|2 Byte ausgeben}}&lt;br /&gt;
         Call Usi_twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
         {{vbcomment|kein STOP an dieser Stelle !}}&lt;br /&gt;
         {{vbcomment|es folgt ein Repeated START !}}&lt;br /&gt;
 &lt;br /&gt;
         If Usi_twi_errorstate = 0 Then                  {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread                  {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3                               {{vbcomment|3 Byte ausgeben, bzw. einlesen}}&lt;br /&gt;
             Call Usi_twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Usi_twi_errorstate = 0 Then              {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
                 Call Usi_twi_master_stop&lt;br /&gt;
                 {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Gelesenen Bytes stehen ab Position 2 im Array}}&lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 {{vbcomment|Negativer Wert ?}}&lt;br /&gt;
                 If Lowtemp.7 = 1 Then&lt;br /&gt;
                     Lowtemp = Not Lowtemp&lt;br /&gt;
                     {{vbcomment|.5 ?}}&lt;br /&gt;
                     If &amp;amp;H80 &amp;gt; Hightemp Then&lt;br /&gt;
                         Incr Lowtemp&lt;br /&gt;
                     End If&lt;br /&gt;
                     Print &amp;quot;-&amp;quot; ;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate &amp;lt;&amp;gt; 0 Then                     {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(usi_twi_errorstate)&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
     Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
     Waitms 2000&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Unterprogramme für USI-Kommunikation ===&lt;br /&gt;
&lt;br /&gt;
Hier folgen die Unterprogramme für die USI-I2C-Master Kommunikation&lt;br /&gt;
&lt;br /&gt;
==== Initialisierung ====&lt;br /&gt;
&lt;br /&gt;
USI-I2C Pins Initialisieren, und USI-Register setzen für I2C-Master.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable USI Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Statusflags löschen, und Counter auf 0 zurücksetzen.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== Senden/Empfangen ====&lt;br /&gt;
&lt;br /&gt;
Startbedingung ausgeben,&amp;lt;br&amp;gt;&lt;br /&gt;
versenden der Anzahl der angegebenen Bytes,&amp;lt;br&amp;gt;&lt;br /&gt;
und einen Status zurückgeben, ob die Daten angenommen (ACK) wurden.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI Transmit und Receive Funktion.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|RW-Bit : Messagebuf(1).0}}&lt;br /&gt;
     Rw = Messagebuf(1).0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
         If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
             {{vbcomment|Write a byte}}&lt;br /&gt;
             Pout_usi_scl = 0                            {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
             Usidr = Messagebuf(cnt)&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|kein ACK gekommen}}&lt;br /&gt;
             If Temp_usisr.0 = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H05               {{vbcomment|Der Slave hat die Daten mit NACK quittiert}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     Usi_twi_errorstate = &amp;amp;H06           {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
                 End If&lt;br /&gt;
                 Exit For                                {{vbcomment|die Schleife bei einem Fehler verlasssen}}&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|Read a Byte}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             Messagebuf(cnt) = Temp_usisr                {{vbcomment|Empfangenes Byte ins Array}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Prepare to generate ACK (or NACK in case of End Of Transmission)}}&lt;br /&gt;
             If Cnt = Anzahlbuf Then&lt;br /&gt;
                 Usidr = &amp;amp;HFF                            {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Usidr = &amp;amp;H00                            {{vbcomment|Load ACK. Set data register bit 7 (output for SDA) low.}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer                {{vbcomment|ACK oder NACK senden}}&lt;br /&gt;
 &lt;br /&gt;
         End If&lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== Ein Byte ausgeben/einlesen ====&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt die Anzahl Bit aus, wie anhand der Variablen ''Temp_usisr'' eingestellt wurde, bzw. es wird damit die Anzahl Takte angegeben, die der Counter des USI-Moduls zählt bevor er überläuft, und das Flag ''USIOIF'' im Status-Register ''USISR'' gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Getaktet wird hier per Software, pro Bit zwei Takte. Bei jedem Takt andert sich der Zustand (High/Low) von SCL.&lt;br /&gt;
&lt;br /&gt;
Die Daten die ausgegeben werden sollen, müssen vor dem Aufruf dieser Routine in das Datenregister ''USIDR'' geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Ob ein Bit ausgegeben oder gelesen wird, wird vor dem Aufruf im Datenrichtungsregister der Datenleitung SDA eingestellt. Im Beispiel mit dem Alias ''Ddr_usi_sda''.&lt;br /&gt;
&lt;br /&gt;
Das gelesene Byte von ''USIDR'' wird in die Variable ''Temp_usisr'' geschrieben, und kann vom Hauptprogramm weiterverarbeitet werden.&lt;br /&gt;
&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Waitus 5}}&lt;br /&gt;
         Usicr = Temp_usisr                              {{vbcomment|SCL takten}}&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitus 4}}&lt;br /&gt;
         Usicr = Temp_usisr                              {{vbcomment|SCL takten}}&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Wenn der Zähler überläuft, sind alle Bits versendet.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitus 5}}&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Daten aus USI-Datenregister lesen.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
==== STOP-Bedingung ausgeben ====&lt;br /&gt;
&lt;br /&gt;
STOP-Bedingung ausgeben, und prüfen ob dies vom eigenen Modul erkannt wurde.&amp;lt;br&amp;gt;&lt;br /&gt;
Status zurückgeben, ob die STOP-Bedingung erfolgreiche ausgegeben wurde.&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
 &lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|prüfen ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Fehlercodes aus den Beispielen ===&lt;br /&gt;
&lt;br /&gt;
Wenn ein unerwartetes Ereignis auftreten sollte, wird eine Zahl ausgegeben, hier ist deren Bedeutung dazu.&lt;br /&gt;
Die Fehlercodes wurden aus den Beispielen von Atmel übernommen. (siehe Weblinks)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Code || Kurzbezeichnung || Fehlerbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|02&lt;br /&gt;
| USI_TWI_UE_START_CON || Unerwartete Start Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|03&lt;br /&gt;
| USI_TWI_UE_STOP_CON || Unerwartete Stop Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|04&lt;br /&gt;
| USI_TWI_UE_DATA_COL || Unerwartete Data Collision (arbitration)&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|05&lt;br /&gt;
| USI_TWI_NO_ACK_ON_DATA || Der Slave hat die Daten nicht per ACK quittiert&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|06&lt;br /&gt;
| USI_TWI_NO_ACK_ON_ADDRESS || Es hat sich kein Slave per ACK gemeldet&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|07&lt;br /&gt;
| USI_TWI_MISSING_START_CON || Erzeugte Start Bedingung nicht erkannt&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|08&lt;br /&gt;
| USI_TWI_MISSING_STOP_CON || Erzeugte Stop Bedingung nicht erkannt&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Slave ==&lt;br /&gt;
&lt;br /&gt;
Da der I2C-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Mega8]] mit einem [[ATMega8|Mega8]], und als Slave das [[RN-Control]] Board, mit dem Adapter auf dem der [[ATtiny2313|Tiny2313]] sitzt, verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|USI-I2C-Slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortC aus (aber nur die oberen 6 bit, da die beiden unteren für I2C verwendet werden), an dem beim RN-Control eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=25058] - Thread im Forum der zu diesem hier geführt hat&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&amp;amp;products_id=107] - DS1621 bei Robotikhardware&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
= Baustelle =&lt;br /&gt;
{{Baustelle|Linux_80}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:11, 26. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Datei:USI-I2C_DS1621_RN-Control_Tiny2313.JPG&amp;diff=9759</id>
		<title>Datei:USI-I2C DS1621 RN-Control Tiny2313.JPG</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Datei:USI-I2C_DS1621_RN-Control_Tiny2313.JPG&amp;diff=9759"/>
				<updated>2006-12-03T14:24:12Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Testumgebung für USI-I2C.
Mit RN-Control(Tiny2313) über I2C den DS1621 (Temperatursensor) ansteuern.
USI eines AVR verwenden.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Testumgebung für USI-I2C.&lt;br /&gt;
Mit RN-Control(Tiny2313) über I2C den DS1621 (Temperatursensor) ansteuern.&lt;br /&gt;
USI eines AVR verwenden.&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9757</id>
		<title>Bascom und USI-Kommunikation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9757"/>
				<updated>2006-12-03T01:00:06Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Fehlercodetabelle dazu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das [[USI (Avr)|USI]]-Hardwaremodul der [[AVR]]s zu verwenden. Mit dem [[USI (Avr)|USI]]-Modul können die Schnittstellen [[I2C]] ([[TWI]]) und [[SPI]] nachgebildet werden. Näheres zu [[USI (Avr)|USI]], [[I2C]] und [[SPI]] finden sich in den entsprechenden Artikeln. Die Beispiele sind zwar in [[Bascom]] Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Master ==&lt;br /&gt;
[[Bild:USI-I2C_PCF8574_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Generierung der gewünschten Busgeschwindigkeit ist die Software zuständig, die länge der Pausen zwischen den Takten muss erechnet werden, im Beispielprogramm für ca. 100kHz bei 16MHz CPU-Frequenz.&lt;br /&gt;
Der Takt kann auch mithilfe eines [[Timer/Counter (Avr)|Timer]]s erzeugt werden, dies wird erst zu einem späteren Zeitpunkt mit einem Beispiel gezeigt.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATtiny2313|Tiny2313]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen }}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim B As Byte                                           {{vbcomment|Zeichen von UART oder Testzeichen zum senden über USI}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 B = 0&lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;Tiny2313 USI-TWI-Test&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Messagebuf(1) = &amp;amp;H40                                    {{vbcomment|Adresse von 8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
     {{vbcomment|oder automatisch zählen lassen}}&lt;br /&gt;
     {{vbcomment|Incr B}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Messagebuf(2) = Not B                               {{vbcomment|not, weil andersrum}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; &amp;quot;&lt;br /&gt;
     Print Hex(usi_twi_errorstate);&lt;br /&gt;
     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
     Print Hex(temp_usisr)&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitms 700  ' Wenn automatisch gezählt werden soll, eine kleine Pause, damit man auch was sehen kann}}&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Clear flags, and reset counter.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI Transmit and receive function.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|Write a byte}}&lt;br /&gt;
         Pout_usi_scl = 0                                {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
         Usidr = Messagebuf(cnt)&lt;br /&gt;
         Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
         Ddr_usi_sda = 0                                 {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
         Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|kein ACK gekommen, Slave meldet sich nicht}}&lt;br /&gt;
         If Temp_usisr.0 = 1 Then&lt;br /&gt;
             Usi_twi_errorstate = &amp;amp;H05&lt;br /&gt;
             If Cnt = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H06               {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
             End If&lt;br /&gt;
             Exit For                                    {{vbcomment|hier wird die Schleife bei einem NACK verlasssen}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_stop&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
  &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Core function for shifting data in and out from the USI.}}&lt;br /&gt;
 {{vbcomment|Data to be sent has to be placed into the USIDR prior to calling}}&lt;br /&gt;
 {{vbcomment|this function. Data read, will be return'ed from the function.}}&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         Waitus 5&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         Waitus 4&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Check for transfer complete.}}&lt;br /&gt;
 &lt;br /&gt;
     Waitus 5&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Read out data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter und Receiver mit DS1621 als Slave ===&lt;br /&gt;
&lt;br /&gt;
;Senden und Empfangen (Repeated Start)&lt;br /&gt;
Im Beispiel wird ein DS1621 Temperatursensor mit I2C-Schnittstelle verwendet&lt;br /&gt;
Der Master sendet einem Slave ein Kommando, stellt um auf Empfang und holt den Temperaturwert, schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Der Temperaturwert wird über [[UART]] ([[RS232]]) im Klartext ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die Subroutinen sind im Prinzip die gleichen wie bei ''Master Transmitter''. Da der DS1621 aber mit 400kHz kommunizieren kann, wurden die ''Waitus'' zwischen den Pegelwechseln weggelassen da die Befehle hier sowieso nicht schnell genug sind, und ein Wait unnötig machen. Sie sind aber als Kommentar eingefügt, damit zu sehen ist an welchen Stellen ansonsten gewartet werden sollte. &lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Temperaturwert vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&amp;lt;br&amp;gt;&lt;br /&gt;
(Das Beispiel belegt 1348 Byte im Flash, das sind ca. 65% eines Tiny2313 !)&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|Temperatur von DS1621 lesen, und über UART ausgeben}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                           {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Dim Device As Byte&lt;br /&gt;
 Dim Deviceread As Byte&lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Device = &amp;amp;H90&lt;br /&gt;
 Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.5 , 300 , 450                               {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;DS1621-USI Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                              {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                                {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate = 0 Then                      {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
         Call Usi_twi_master_stop&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitms 1}}&lt;br /&gt;
         Messagebuf(1) = Device                          {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                            {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Usi_twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
         {{vbcomment|kein STOP an dieser Stelle !}}&lt;br /&gt;
         {{vbcomment|es folgt ein Repeated START !}}&lt;br /&gt;
 &lt;br /&gt;
         If Usi_twi_errorstate = 0 Then                  {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread                  {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Usi_twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Usi_twi_errorstate = 0 Then              {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
                 Call Usi_twi_master_stop&lt;br /&gt;
                 {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate &amp;lt;&amp;gt; 0 Then                     {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(usi_twi_errorstate)&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 2000&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Clear flags, and reset counter.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI Transmit and receive function.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Rw = Messagebuf(1).0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
         {{vbcomment|RW-Bit : Messagebuf(1).0 ist 1}}&lt;br /&gt;
         If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
             {{vbcomment|Write a byte}}&lt;br /&gt;
             Pout_usi_scl = 0                            {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
             Usidr = Messagebuf(cnt)&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|kein ACK gekommen}}&lt;br /&gt;
             If Temp_usisr.0 = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H05               {{vbcomment|Der Slave hat die Daten mit NACK quittiert}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     Usi_twi_errorstate = &amp;amp;H06           {{vbcomment|Es hat sich kein Slave gemeldet}}&lt;br /&gt;
                 End If&lt;br /&gt;
                 Exit For                                {{vbcomment|die Schleife bei einem Fehler verlasssen}}&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|Read a Byte}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             Messagebuf(cnt) = Temp_usisr                {{vbcomment|Empfangenes Byte ins Array}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Prepare to generate ACK (or NACK in case of End Of Transmission)}}&lt;br /&gt;
             If Cnt = Anzahlbuf Then&lt;br /&gt;
                 Usidr = &amp;amp;HFF                            {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Usidr = &amp;amp;H00                            {{vbcomment|Load ACK. Set data register bit 7 (output for SDA) low.}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer                {{vbcomment|ACK oder NACK senden}}&lt;br /&gt;
 &lt;br /&gt;
         End If&lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
 &lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Core function for shifting data in and out from the USI.}}&lt;br /&gt;
 {{vbcomment|Data to be sent has to be placed into the USIDR prior to calling}}&lt;br /&gt;
 {{vbcomment|this function. Data read, will be return'ed from the function.}}&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Waitus 5}}&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitus 4}}&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Check for transfer complete.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitus 5}}&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Read out data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Fehlercodes aus den Beispielen ===&lt;br /&gt;
&lt;br /&gt;
Wenn ein unerwartetes Ereignis auftreten sollte, wird eine Zahl ausgegeben, hier ist deren Bedeutung dazu.&lt;br /&gt;
Die Fehlercodes wurden aus den Beispielen von Atmel übernommen. (siehe Weblinks)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|- {{Hintergrund1}}&lt;br /&gt;
!| Code || Kurzbezeichnung || Fehlerbeschreibung&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|02&lt;br /&gt;
| USI_TWI_UE_START_CON || Unerwartete Start Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|03&lt;br /&gt;
| USI_TWI_UE_STOP_CON || Unerwartete Stop Bedingung aufgetreten&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|04&lt;br /&gt;
| USI_TWI_UE_DATA_COL || Unerwartete Data Collision (arbitration)&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|05&lt;br /&gt;
| USI_TWI_NO_ACK_ON_DATA || Der Slave hat die Daten nicht per ACK quittiert&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|06&lt;br /&gt;
| USI_TWI_NO_ACK_ON_ADDRESS || Es hat sich kein Slave per ACK gemeldet&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|07&lt;br /&gt;
| USI_TWI_MISSING_START_CON || Erzeugte Start Bedingung nicht erkannt&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|08&lt;br /&gt;
| USI_TWI_MISSING_STOP_CON || Erzeugte Stop Bedingung nicht erkannt&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Slave ==&lt;br /&gt;
&lt;br /&gt;
Da der I2C-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Mega8]] mit einem [[ATMega8|Mega8]], und als Slave das [[RN-Control]] Board, mit dem Adapter auf dem der [[ATtiny2313|Tiny2313]] sitzt, verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|USI-I2C-Slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortC aus (aber nur die oberen 6 bit, da die beiden unteren für I2C verwendet werden), an dem beim RN-Control eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=25058] - Thread im Forum der zu diesem hier geführt hat&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&amp;amp;products_id=107] - DS1621 bei Robotikhardware&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
= Baustelle =&lt;br /&gt;
{{Baustelle|Linux_80}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:11, 26. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9756</id>
		<title>Bascom und USI-Kommunikation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9756"/>
				<updated>2006-12-03T00:29:59Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Master Transmitter &amp;amp; Receiver mit DS1621&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das [[USI (Avr)|USI]]-Hardwaremodul der [[AVR]]s zu verwenden. Mit dem [[USI (Avr)|USI]]-Modul können die Schnittstellen [[I2C]] ([[TWI]]) und [[SPI]] nachgebildet werden. Näheres zu [[USI (Avr)|USI]], [[I2C]] und [[SPI]] finden sich in den entsprechenden Artikeln. Die Beispiele sind zwar in [[Bascom]] Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Master ==&lt;br /&gt;
[[Bild:USI-I2C_PCF8574_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Generierung der gewünschten Busgeschwindigkeit ist die Software zuständig, die länge der Pausen zwischen den Takten muss erechnet werden, im Beispielprogramm für ca. 100kHz bei 16MHz CPU-Frequenz.&lt;br /&gt;
Der Takt kann auch mithilfe eines [[Timer/Counter (Avr)|Timer]]s erzeugt werden, dies wird erst zu einem späteren Zeitpunkt mit einem Beispiel gezeigt.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATtiny2313|Tiny2313]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen }}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim B As Byte                                           {{vbcomment|Zeichen von UART oder Testzeichen zum senden über USI}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 B = 0&lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;Tiny2313 USI-TWI-Test&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Messagebuf(1) = &amp;amp;H40                                    {{vbcomment|Adresse von 8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
     {{vbcomment|oder automatisch zählen lassen}}&lt;br /&gt;
     {{vbcomment|Incr B}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Messagebuf(2) = Not B                               {{vbcomment|not, weil andersrum}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; &amp;quot;&lt;br /&gt;
     Print Hex(usi_twi_errorstate);&lt;br /&gt;
     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
     Print Hex(temp_usisr)&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitms 700  ' Wenn automatisch gezählt werden soll, eine kleine Pause, damit man auch was sehen kann}}&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Clear flags, and reset counter.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI Transmit and receive function.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|Write a byte}}&lt;br /&gt;
         Pout_usi_scl = 0                                {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
         Usidr = Messagebuf(cnt)&lt;br /&gt;
         Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
         Ddr_usi_sda = 0                                 {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
         Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|kein ACK gekommen, Slave meldet sich nicht}}&lt;br /&gt;
         If Temp_usisr.0 = 1 Then&lt;br /&gt;
             Usi_twi_errorstate = &amp;amp;H05&lt;br /&gt;
             Exit For                                    {{vbcomment|hier wird die Schleife bei einem NACK verlasssen}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_stop&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
  &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Core function for shifting data in and out from the USI.}}&lt;br /&gt;
 {{vbcomment|Data to be sent has to be placed into the USIDR prior to calling}}&lt;br /&gt;
 {{vbcomment|this function. Data read, will be return'ed from the function.}}&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         Waitus 5&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         Waitus 4&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Check for transfer complete.}}&lt;br /&gt;
 &lt;br /&gt;
     Waitus 5&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Read out data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter und Receiver mit DS1621 als Slave ===&lt;br /&gt;
&lt;br /&gt;
;Senden und Empfangen (Repeated Start)&lt;br /&gt;
Im Beispiel wird ein DS1621 Temperatursensor mit I2C-Schnittstelle verwendet&lt;br /&gt;
Der Master sendet einem Slave ein Kommando, stellt um auf Empfang und holt den Temperaturwert, schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Der Temperaturwert wird über [[UART]] ([[RS232]]) im Klartext ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die Subroutinen sind im Prinzip die gleichen wie bei ''Master Transmitter''. Da der DS1621 aber mit 400kHz kommunizieren kann, wurden die ''Waitus'' zwischen den Pegelwechseln weggelassen da die Befehle hier sowieso nicht schnell genug sind, und ein Wait unnötig machen. Sie sind aber als Kommentar eingefügt, damit zu sehen ist an welchen Stellen ansonsten gewartet werden sollte. &lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt Temperaturwert vom Slave mit Adresse 144 (0x90 bzw. &amp;amp;H90):&amp;lt;br&amp;gt;&lt;br /&gt;
(Das Beispiel belegt 1348 Byte im Flash, das sind ca. 65% eines Tiny2313 !)&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit DS1621 @ &amp;amp;H90}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|Temperatur von DS1621 lesen, und über UART ausgeben}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                          {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                  {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                   {{vbcomment|Anzahl Zeichen die gesendet werden sollen}}&lt;br /&gt;
 Dim Cnt As Byte                                         {{vbcomment|Zähler}}&lt;br /&gt;
 Dim Rw As Bit                                           {{vbcomment|Read/Write Flag}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 Anzahlbuf = 2                                           {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 500                                              {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Dim Device As Byte&lt;br /&gt;
 Dim Deviceread As Byte&lt;br /&gt;
 Dim Lowtemp As Byte&lt;br /&gt;
 Dim Hightemp As Byte&lt;br /&gt;
 &lt;br /&gt;
 Device = &amp;amp;H90&lt;br /&gt;
 Deviceread = &amp;amp;H91&lt;br /&gt;
 &lt;br /&gt;
 Sound Portd.5 , 300 , 450                               {{vbcomment|BEEP}}&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;DS1621-USI Temperatur&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Hauptprogramm}}&lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     Messagebuf(1) = Device                              {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
     Messagebuf(2) = &amp;amp;HEE                                {{vbcomment|Temperaturmessung anstoßen}}&lt;br /&gt;
     Anzahlbuf = 2&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
     {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate = 0 Then                      {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
         Call Usi_twi_master_stop&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitms 1}}&lt;br /&gt;
         Messagebuf(1) = Device                          {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
         Messagebuf(2) = &amp;amp;HAA                            {{vbcomment|Temperaturmessung Lesekommando}}&lt;br /&gt;
         Anzahlbuf = 2&lt;br /&gt;
         Call Usi_twi_start_transceiver&lt;br /&gt;
         {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
         {{vbcomment|kein STOP an dieser Stelle !}}&lt;br /&gt;
         {{vbcomment|es folgt ein Repeated START !}}&lt;br /&gt;
 &lt;br /&gt;
         If Usi_twi_errorstate = 0 Then                  {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
             {{vbcomment|Temperatur lesen}}&lt;br /&gt;
             Messagebuf(1) = Deviceread                  {{vbcomment|Adresse von DS1621}}&lt;br /&gt;
             Messagebuf(2) = 0&lt;br /&gt;
             Messagebuf(3) = 0&lt;br /&gt;
             Anzahlbuf = 3&lt;br /&gt;
             Call Usi_twi_start_transceiver&lt;br /&gt;
             {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
             If Usi_twi_errorstate = 0 Then              {{vbcomment|kein Fehler aufgetreten}}&lt;br /&gt;
 &lt;br /&gt;
                 Call Usi_twi_master_stop&lt;br /&gt;
                 {{vbcomment|Print Hex(usi_twi_errorstate)}}&lt;br /&gt;
 &lt;br /&gt;
                 Lowtemp = Messagebuf(2)&lt;br /&gt;
                 Hightemp = Messagebuf(3)&lt;br /&gt;
 &lt;br /&gt;
                 Print Lowtemp ; &amp;quot;,&amp;quot; ;&lt;br /&gt;
 &lt;br /&gt;
                 If Hightemp = &amp;amp;H80 Then&lt;br /&gt;
                     Print &amp;quot;5&amp;quot;&lt;br /&gt;
                 Else&lt;br /&gt;
                     Print &amp;quot;0&amp;quot;&lt;br /&gt;
                 End If&lt;br /&gt;
 &lt;br /&gt;
             End If&lt;br /&gt;
         End If&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usi_twi_errorstate &amp;lt;&amp;gt; 0 Then                     {{vbcomment|bei einem Fehler den Fehlercode ausgeben}}&lt;br /&gt;
         Print &amp;quot;Error &amp;quot; ; Hex(usi_twi_errorstate)&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                      {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     Waitms 2000&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Clear flags, and reset counter.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI Transmit and receive function.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                       {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usisr.5 = 1 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                       {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     If Usisr.4 = 1 Then                                 {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                       {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_scl = 0                                    {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                 {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Rw = Messagebuf(1).0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|SlaveAdresse immer Write, sonst auf R/W prüfen}}&lt;br /&gt;
         {{vbcomment|RW-Bit : Messagebuf(1).0 ist 1}}&lt;br /&gt;
         If Cnt = 1 Or Rw = 0 Then&lt;br /&gt;
             {{vbcomment|Write a byte}}&lt;br /&gt;
             Pout_usi_scl = 0                            {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
             Usidr = Messagebuf(cnt)&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|kein ACK gekommen}}&lt;br /&gt;
             If Temp_usisr.0 = 1 Then&lt;br /&gt;
                 Usi_twi_errorstate = &amp;amp;H05               {{vbcomment|The slave did not acknowledge all data}}&lt;br /&gt;
                 If Cnt = 1 Then&lt;br /&gt;
                     Usi_twi_errorstate = &amp;amp;H06           {{vbcomment|The slave did not acknowledge the address}}&lt;br /&gt;
                 End If&lt;br /&gt;
                 Exit For                                {{vbcomment|die Schleife bei einem Fehler verlasssen}}&lt;br /&gt;
             End If&lt;br /&gt;
         Else&lt;br /&gt;
             {{vbcomment|Read a Byte}}&lt;br /&gt;
             Ddr_usi_sda = 0                             {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
             Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
             Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
             Messagebuf(cnt) = Temp_usisr                {{vbcomment|Empfangenes Byte ins Array}}&lt;br /&gt;
 &lt;br /&gt;
             {{vbcomment|Prepare to generate ACK (or NACK in case of End Of Transmission)}}&lt;br /&gt;
             If Cnt = Anzahlbuf Then&lt;br /&gt;
                 Usidr = &amp;amp;HFF                            {{vbcomment|Load NACK to confirm End Of Transmission.}}&lt;br /&gt;
             Else&lt;br /&gt;
                 Usidr = &amp;amp;H00                            {{vbcomment|Load ACK. Set data register bit 7 (output for SDA) low.}}&lt;br /&gt;
             End If&lt;br /&gt;
 &lt;br /&gt;
             Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
             Call Usi_twi_master_transfer                {{vbcomment|ACK oder NACK senden}}&lt;br /&gt;
 &lt;br /&gt;
         End If&lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
 &lt;br /&gt;
     Pout_usi_sda = 0                                    {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                    {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     {{vbcomment|Waitus 4}}&lt;br /&gt;
     Pout_usi_sda = 1                                    {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 1                                            {{vbcomment|5}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                 {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     Usisr.5 = 1                                         {{vbcomment|USIPF zurücksetzen}}&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Core function for shifting data in and out from the USI.}}&lt;br /&gt;
 {{vbcomment|Data to be sent has to be placed into the USIDR prior to calling}}&lt;br /&gt;
 {{vbcomment|this function. Data read, will be return'ed from the function.}}&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                             {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         {{vbcomment|Waitus 5}}&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Waitus 4}}&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                              {{vbcomment|USIOIF, Check for transfer complete.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitus 5}}&lt;br /&gt;
     Temp_usisr = Usidr                                  {{vbcomment|Read out data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                        {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                     {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Slave ==&lt;br /&gt;
&lt;br /&gt;
Da der I2C-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Mega8]] mit einem [[ATMega8|Mega8]], und als Slave das [[RN-Control]] Board, mit dem Adapter auf dem der [[ATtiny2313|Tiny2313]] sitzt, verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|USI-I2C-Slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortC aus (aber nur die oberen 6 bit, da die beiden unteren für I2C verwendet werden), an dem beim RN-Control eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=25058] - Thread im Forum der zu diesem hier geführt hat&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&amp;amp;products_id=107] - DS1621 bei Robotikhardware&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
= Baustelle =&lt;br /&gt;
{{Baustelle|Linux_80}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:11, 26. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9730</id>
		<title>Bascom und USI-Kommunikation</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9730"/>
				<updated>2006-11-26T01:11:46Z</updated>
		
		<summary type="html">&lt;p&gt;Linux 80: Neu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel folgen einige Programmbeispiele um das [[USI (Avr)|USI]]-Hardwaremodul der [[AVR]]s zu verwenden. Mit dem [[USI (Avr)|USI]]-Modul können die Schnittstellen [[I2C]] ([[TWI]]) und [[SPI]] nachgebildet werden. Näheres zu [[USI (Avr)|USI]], [[I2C]] und [[SPI]] finden sich in den entsprechenden Artikeln. Die Beispiele sind zwar in [[Bascom]] Basic verfasst, aber so ausgeführt, das es möglich sein sollte das Prinzip mit jeder anderen Sprache nachvollziehen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Master ==&lt;br /&gt;
[[Bild:USI-I2C_PCF8574_RN-Control_Tiny2313.JPG|thumb|Beispielumgebung]]&lt;br /&gt;
Ist der AVR Master, bestimmt er was und wie schnell es auf dem [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]]-Bus zugeht. (Ausnahme: [[Clock_Stretching]] )&lt;br /&gt;
&lt;br /&gt;
Zur Generierung der gewünschten Busgeschwindigkeit ist die Software zuständig, die länge der Pausen zwischen den Takten muss erechnet werden, im Beispielprogramm für ca. 100kHz bei 16MHz CPU-Frequenz.&lt;br /&gt;
Der Takt kann auch mithilfe eines [[Timer/Counter (Avr)|Timer]]s erzeugt werden, dies wird erst zu einem späteren Zeitpunkt mit einem Beispiel gezeigt.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Control]] mit einem [[ATtiny2313|Tiny2313]], und als Slave ein [[I2C_Chip-Übersicht#I.2FO_expanders:|PCF8574]], da sich dieser leicht ansteuern lässt. &amp;lt;!--  und jeden Scheiss mitmacht ;-)) --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;Nur Senden&lt;br /&gt;
&lt;br /&gt;
Der Master sendet einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm sendet ein Byte zum Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte senden}}&lt;br /&gt;
 $regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
 $crystal = 16000000&lt;br /&gt;
 $baud = 9600&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Unterprogramme für die USI-Kommunikation}}&lt;br /&gt;
 Declare Sub Usi_twi_master_initialise()&lt;br /&gt;
 Declare Sub Usi_twi_start_transceiver()&lt;br /&gt;
 Declare Sub Usi_twi_master_stop()&lt;br /&gt;
 Declare Sub Usi_twi_master_transfer()&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|einige Aliases anlegen}}&lt;br /&gt;
 Pout_usi_scl Alias Portb.7&lt;br /&gt;
 Pin_usi_scl Alias Pinb.7&lt;br /&gt;
 Ddr_usi_scl Alias Ddrb.7&lt;br /&gt;
 Pout_usi_sda Alias Portb.5&lt;br /&gt;
 Pin_usi_sda Alias Pinb.5&lt;br /&gt;
 Ddr_usi_sda Alias Ddrb.5&lt;br /&gt;
 &lt;br /&gt;
 Dim Usi_twi_errorstate As Byte                            {{vbcomment|eigener Fehlerstatus}}&lt;br /&gt;
 {{vbcomment|Array der Daten die übertragen werden}}&lt;br /&gt;
 Dim Messagebuf(4) As Byte&lt;br /&gt;
 Dim Temp_usisr As Byte                                    {{vbcomment|Tempvariable für Unterprogramm}}&lt;br /&gt;
 Dim Anzahlbuf As Byte                                     {{vbcomment|Anzahl Zeichen die gesendet werden sollen }}&lt;br /&gt;
 Dim Cnt As Byte                                           {{vbcomment|Zähler}}&lt;br /&gt;
 Dim B As Byte                                             {{vbcomment|Zeichen von UART oder Testzeichen zum senden über USI}}&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 8 bits i.e. count 16 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_8bit = &amp;amp;HF0&lt;br /&gt;
 {{vbcomment|Prepare register value to: Clear flags, and set USI to shift 1 bit i.e. count 2 clock edges.}}&lt;br /&gt;
 Const Temp_usisr_1bit = &amp;amp;HFE&lt;br /&gt;
 &lt;br /&gt;
 B = 0&lt;br /&gt;
 Anzahlbuf = 2                                             {{vbcomment|in diesem Beispiel immer nur 2 Zeichen}}&lt;br /&gt;
 &lt;br /&gt;
 Waitms 300                                                {{vbcomment|Sicherheitspause nach Reset}}&lt;br /&gt;
 &lt;br /&gt;
 Call Usi_twi_master_initialise&lt;br /&gt;
 &lt;br /&gt;
 Print&lt;br /&gt;
 Print &amp;quot;Tiny2313 USI-TWI-Test&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 Messagebuf(1) = &amp;amp;H40                                      {{vbcomment|Adresse von 8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|warten bis etwas über UART kommt}}&lt;br /&gt;
     Input B&lt;br /&gt;
     {{vbcomment|oder automatisch zählen lassen}}&lt;br /&gt;
     {{vbcomment|Incr B}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Den Wert zum Slave senden}}&lt;br /&gt;
     Messagebuf(2) = Not B                                 {{vbcomment|not, weil andersrum}}&lt;br /&gt;
     Call Usi_twi_start_transceiver&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ausgabe, damit wir sehen was geschehen ist}}&lt;br /&gt;
     Print B ;&lt;br /&gt;
     Print &amp;quot; &amp;quot;&lt;br /&gt;
     Print Hex(usi_twi_errorstate);&lt;br /&gt;
     Print &amp;quot; &amp;quot; ;&lt;br /&gt;
     Print Hex(temp_usisr)&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_initialise                        {{vbcomment|nochmal initialisieren falls ein Fehler aufgetreten ist}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Waitms 700  ' Wenn automatisch gezählt werden soll, eine kleine Pause, damit man auch was sehen kann}}&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI TWI single master initialization function}}&lt;br /&gt;
 Sub Usi_twi_master_initialise()&lt;br /&gt;
     {{vbcomment|Direction Out}}&lt;br /&gt;
     Ddr_usi_scl = 1&lt;br /&gt;
     Ddr_usi_sda = 1&lt;br /&gt;
     {{vbcomment|Release SCL &amp;amp; SDA}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Pout_usi_sda = 1&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Preload dataregister with &amp;quot;released level&amp;quot; data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Disable Interrupts.}}&lt;br /&gt;
     {{vbcomment|Set USI in Two-wire mode.}}&lt;br /&gt;
     {{vbcomment|Software stobe as counter clock source}}&lt;br /&gt;
     Usicr = &amp;amp;B00101010&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Clear flags, and reset counter.}}&lt;br /&gt;
     Usisr = &amp;amp;B11110000&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|USI Transmit and receive function.}}&lt;br /&gt;
 Sub Usi_twi_start_transceiver()&lt;br /&gt;
 &lt;br /&gt;
     Usi_twi_errorstate = 0&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Test if any unexpected conditions have arrived prior to this execution.}}&lt;br /&gt;
     {{vbcomment|Ist eine Startbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.7 = 1 Then                                   {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H02                         {{vbcomment|Usi_twi_ue_start_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Stopbedingung aufgetreten ?}}&lt;br /&gt;
     If Usisr.5 = 1 Then                                   {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H03                         {{vbcomment|Usi_twi_ue_stop_con}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Ist eine Datenkollision aufgetreten ?}}&lt;br /&gt;
     If Usisr.4 = 1 Then                                   {{vbcomment|USIDC}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H04                         {{vbcomment|Usi_twi_ue_data_col}}&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Release SCL to ensure that (repeated) Start can be performed}}&lt;br /&gt;
     Pout_usi_scl = 1&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Generate Start Condition}}&lt;br /&gt;
     Pout_usi_sda = 0                                      {{vbcomment|Force SDA LOW.}}&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_scl = 0                                      {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
     Pout_usi_sda = 1                                      {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|checken ob die Startsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.7 = 0 Then                                   {{vbcomment|USISIF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H07&lt;br /&gt;
         Exit Sub&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Write address and Read/Write data}}&lt;br /&gt;
     For Cnt = 1 To Anzahlbuf&lt;br /&gt;
         {{vbcomment|Write a byte}}&lt;br /&gt;
         Pout_usi_scl = 0                                  {{vbcomment|Pull SCL LOW.}}&lt;br /&gt;
         Usidr = Messagebuf(cnt)&lt;br /&gt;
         Temp_usisr = Temp_usisr_8bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|Clock and verify (N)ACK from slave}}&lt;br /&gt;
         Ddr_usi_sda = 0                                   {{vbcomment|Enable SDA as input.}}&lt;br /&gt;
         Temp_usisr = Temp_usisr_1bit&lt;br /&gt;
         Call Usi_twi_master_transfer&lt;br /&gt;
 &lt;br /&gt;
         {{vbcomment|kein ACK gekommen, Slave meldet sich nicht}}&lt;br /&gt;
         If Temp_usisr.0 = 1 Then&lt;br /&gt;
             Usi_twi_errorstate = &amp;amp;H05&lt;br /&gt;
             Exit For                                      {{vbcomment|hier wird die Schleife bei einem NACK verlasssen}}&lt;br /&gt;
         End If&lt;br /&gt;
 &lt;br /&gt;
     Next Cnt&lt;br /&gt;
 &lt;br /&gt;
     Call Usi_twi_master_stop&lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Function for generating a TWI Stop Condition. Used to release the TWI bus.}}&lt;br /&gt;
 Sub Usi_twi_master_stop()&lt;br /&gt;
     Pout_usi_sda = 0                                      {{vbcomment|Pull SDA LOW.}}&lt;br /&gt;
     Pout_usi_scl = 1                                      {{vbcomment|Release SCL.}}&lt;br /&gt;
 &lt;br /&gt;
     {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
     While Pin_usi_scl = 0&lt;br /&gt;
     Wend&lt;br /&gt;
     Waitus 4&lt;br /&gt;
     Pout_usi_sda = 1                                      {{vbcomment|Release SDA.}}&lt;br /&gt;
     Waitus 5&lt;br /&gt;
 &lt;br /&gt;
     ' checken ob die Stopsequenz vom eigenen USI erkannt wurde}}&lt;br /&gt;
     If Usisr.5 = 0 Then                                   {{vbcomment|USIPF}}&lt;br /&gt;
         Usi_twi_errorstate = &amp;amp;H08&lt;br /&gt;
 {{vbcomment|       Exit Sub                 ' Exit nicht nötig da schon das Ende erreicht}}&lt;br /&gt;
     End If&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
 &lt;br /&gt;
 {{vbcomment|Core function for shifting data in and out from the USI.}}&lt;br /&gt;
 {{vbcomment|Data to be sent has to be placed into the USIDR prior to calling}}&lt;br /&gt;
 {{vbcomment|this function. Data read, will be return'ed from the function.}}&lt;br /&gt;
 Sub Usi_twi_master_transfer()&lt;br /&gt;
     Usisr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Temp_usisr = &amp;amp;B00101011                               {{vbcomment|for Toggle Clock Port.}}&lt;br /&gt;
 &lt;br /&gt;
     Do&lt;br /&gt;
         Waitus 5&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
         {{vbcomment|Wait for SCL to go high.}}&lt;br /&gt;
         While Pin_usi_scl = 0&lt;br /&gt;
         Wend&lt;br /&gt;
 &lt;br /&gt;
         Waitus 4&lt;br /&gt;
         Usicr = Temp_usisr&lt;br /&gt;
 &lt;br /&gt;
     Loop Until Usisr.6 = 1                                {{vbcomment|USIOIF, Check for transfer complete.}}&lt;br /&gt;
 &lt;br /&gt;
     Waitus 5&lt;br /&gt;
     Temp_usisr = Usidr                                    {{vbcomment|Read out data.}}&lt;br /&gt;
     Usidr = &amp;amp;HFF                                          {{vbcomment|Release SDA.}}&lt;br /&gt;
 &lt;br /&gt;
     Ddr_usi_sda = 1                                       {{vbcomment|Enable SDA as output.}}&lt;br /&gt;
 &lt;br /&gt;
 End Sub&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
Der Master holt von einem Slave ein (oder mehrere) Byte, und schliesst die Übertragung anschliessend ab.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Slave Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beispielprogramm holt ein Byte vom Slave mit Adresse 64 (0x40 bzw. &amp;amp;H40):&lt;br /&gt;
&lt;br /&gt;
 {{vbcomment|USI-I2C Testprogramm}}&lt;br /&gt;
 {{vbcomment|mit PCF8574 @ &amp;amp;H40}}&lt;br /&gt;
 {{vbcomment|}}&lt;br /&gt;
 {{vbcomment|ohne Interrupt und ohne Timer}}&lt;br /&gt;
 {{vbcomment|ein Byte lesen}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== USI-I2C-Slave ==&lt;br /&gt;
&lt;br /&gt;
Da der I2C-Master den Takt vorgibt, sind die [[TWI#Anmerkung_zur_CPU-Frequenz|Anmerkungen zur CPU-Frequenz]] zu beachten.&lt;br /&gt;
&lt;br /&gt;
In den Beispielen wird als Master das Board [[RN-Mega8]] mit einem [[ATMega8|Mega8]], und als Slave das [[RN-Control]] Board, mit dem Adapter auf dem der [[ATtiny2313|Tiny2313]] sitzt, verwendet. Da nur diese beiden Boards am Bus hängen, wurde ebenfalls als Slaveadresse 64 (0x40 bzw. &amp;amp;H40) verwendet, damit man die vorhergehenden Beispiele gleich weiterverwenden kann.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transmitter ===&lt;br /&gt;
&lt;br /&gt;
;auf Abruf Senden&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Master übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Receiver''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt Bytewerte zurück die sich bei jeder Abfrage um eins erhöhen. Verwendet man beim Master das Beispiel von ''Master Receiver'', wird der Wert nach jeder Eingabe von Enter  angezeigt.&lt;br /&gt;
 {{vbcomment|USI-I2C-Slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Receiver ===&lt;br /&gt;
&lt;br /&gt;
;Nur Empfangen&lt;br /&gt;
&lt;br /&gt;
Der Slave wird von einem Master über eine festgelegte Adresse angesprochen, ein (oder mehrere) Byte werden zum Slave übertragen, und anschliessend die Übertragung beendet.&lt;br /&gt;
&lt;br /&gt;
Das Gegenstück wäre ''Master Transmitter''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm gibt die Bytewerte an PortC aus (aber nur die oberen 6 bit, da die beiden unteren für I2C verwendet werden), an dem beim RN-Control eine LED-Reihe angeschlossen ist. Verwendet man beim Master das Beispiel von ''Master Transmitter'', wird der Wert, den man dort eingibt am Slave Binär angezeigt.&lt;br /&gt;
 {{vbcomment|TWI-slave test}}&lt;br /&gt;
 {{vbcomment|zum simulieren eines PCF8574}}&lt;br /&gt;
 &lt;br /&gt;
 Do&lt;br /&gt;
 Loop&lt;br /&gt;
 &lt;br /&gt;
 End&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Avr]] - Infos zu AVR allgemein&lt;br /&gt;
* [[I2C|I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C]] - Details zu I2C&lt;br /&gt;
* [[TWI]] - Two-wire Serial Interface&lt;br /&gt;
* [[SPI]] - Serial Peripheral Interface&lt;br /&gt;
* [[TWI Praxis]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
* [[TWI Praxis Multimaster]] - Bascom-Beispiele für Hardware TWI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==WebLinks==&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/viewtopic.php?t=25058] - Thread im Forum der zu diesem hier geführt hat&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2561.pdf Atmel_AVR310] - Using the USI module as a I2C master&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2560.pdf Atmel_AVR312] - Using the USI module as a I2C slave&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Baustelle =&lt;br /&gt;
{{Baustelle|Linux_80}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:Linux 80|Linux 80]] 02:11, 26. Nov 2006 (CET)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Abkürzung]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Kommunikation]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Praxis]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Linux 80</name></author>	</entry>

	</feed>