<?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=Pit49</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=Pit49"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Spezial:Beitr%C3%A4ge/Pit49"/>
		<updated>2026-04-11T16:11:34Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=V-USB:_Ein_Firmware_USB-Treiber_f%C3%BCr_AVR&amp;diff=23022</id>
		<title>V-USB: Ein Firmware USB-Treiber für AVR</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=V-USB:_Ein_Firmware_USB-Treiber_f%C3%BCr_AVR&amp;diff=23022"/>
				<updated>2013-09-25T16:36:26Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mit [http://www.obdev.at/products/vusb/index.html V-USB] von Objective Development ist es ohne weitere Hardware möglich, mit einem AVR Mikrocontroller ein USB-Gerät aufzubauen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware Voraussetzungen des AVRs ==&lt;br /&gt;
=== Spannungspegel-Problem ===&lt;br /&gt;
Da der AVR mit anderen Spannungen als die des USB-Standards arbeitet, müssen diese Angepasst werden. Der Computer und der AVR-Mikrocontroller haben beide bestimmte Anforderungen an die Spannung für einen High- bzw. Low-Pegel. Da wir die Computerseite nicht verändern können, müssen die Anpassungen am AVR stattfinden. Vom PC wird ein Low-Pegel als 0V, ein High-Pegel als 3,3V übertragen. Jedoch ist dies das kleinere Problem, da die AVR-Mikrocontroller selbst bei 5V diesen Pegel sicher als High erkennen.&lt;br /&gt;
Die andere Richtung ist ein größeres Problem. Der Computer erwartet als Low-Pegel eine Spannung von 0V - 0,8V und 2V - 3,6V als High. Um diese Voraussetzungen zu erfüllen, muss entweder der AVR mit einer Spannung von 2V - 3,6V betreiben werden oder die Pegel müssen an D+ und D- des AVRs angepasst werden.&lt;br /&gt;
&lt;br /&gt;
==== Lösung A: Verringern der Betriebspannung des AVRs ====&lt;br /&gt;
Für diese Lösung wird die Betriebsspannung des AVRs auf 3,3V - 3,6V herunter gesetzt.&lt;br /&gt;
Dies ist mit einem 3,3V-Spannungsregler (z.B. LE33CZ, LT1761ES5-3.3) möglich.&lt;br /&gt;
[[Bild:voltage-regulator.gif|thumb|Spannungsanpassung mit einem Spannungsregler]]&lt;br /&gt;
&lt;br /&gt;
'''Vorteile'''&lt;br /&gt;
* Saubere Lösung. Schnelle Übergänge auf D+ und D-&lt;br /&gt;
* Gute Störfestigkeit am Signaleingang&lt;br /&gt;
* Stromverbrauch des µC ist bei 3,3 V geringer als bei 5 V&lt;br /&gt;
&lt;br /&gt;
'''Nachteile'''&lt;br /&gt;
* 3,3V-Spannungsregler sind oft teuer und schwer zu beschaffen&lt;br /&gt;
* Viele ältere AVRs funktionieren bei 3,3 V nicht sicher beim geforderten Takt (12 MHz). Auch bei neueren sind bei 3.3 V kaum mehr als 13 MHz garantiert. &lt;br /&gt;
* Ruhestrom für den Spannungsregler (Forderung nach sparsamem Regler)&lt;br /&gt;
&lt;br /&gt;
Ebenso ist es möglich, die Spannung mit Gleichrichterdioden zu reduzieren.&lt;br /&gt;
Hierfür werden einfach zwei oder drei Gleichrichterdioden in Reihe vor VCC des AVRs geschaltet.&lt;br /&gt;
[[Bild:voltage-reduction-with-diodes.gif|thumb|Pegelanpassung mit Dioden]]&lt;br /&gt;
&lt;br /&gt;
'''Zusätzliche Vorteile'''&lt;br /&gt;
* Niedrige Kosten / Bauteile sind leicht zu bekommen.&lt;br /&gt;
* Kein Ruhestrom --&amp;gt; USB-Konformer Standby-Modus&lt;br /&gt;
&lt;br /&gt;
'''Zusätzliche Nachteile'''&lt;br /&gt;
* Keine Spannungsregelung --&amp;gt; Spannung schwankt, das Geschwindigkeitsprobelm wird dadurch noch größer. Eventuell zu viel Spannung im Leerlauf.  &lt;br /&gt;
* Die unregulierte Spannung ist problematisch für Analoge Schaltungen (ADC,...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Lösung B: Anpassen der Spannung an D+ und D- ====&lt;br /&gt;
Ebenso kann man die Spannung an den Datenleitungen (D+ und D-) mit Zenerdioden verringern. Es werden 3,6V Low-Power Zenerdioden (wie 1N4148, 500mW oder weniger) empfohlen, da diese eine geringe Kapazität haben und somit weniger Störungen auf den Datenleitungen verursachen.&lt;br /&gt;
[[Bild:level-conversion-with-zener.gif|thumb|Pegelanpassung mit Zenerdioden]]&lt;br /&gt;
&lt;br /&gt;
Wenn diese Lösung verwendet wird, stellen sie vor Benutzung sicher, dass die Spannungspegel mit den geforderten Pegeln(LOW:0V-0,8V HIGH:2V-3,6V) übereinstimmen.&lt;br /&gt;
&lt;br /&gt;
'''Vorteile'''&lt;br /&gt;
* Niedrige Kosten&lt;br /&gt;
* Leicht zu bekommen&lt;br /&gt;
* Ganze Schaltung kann mit 5V betrieben werden --&amp;gt; Hohe Taktraten möglich&lt;br /&gt;
* zusätzlicher Schutz vor Überspannungen / ESD&lt;br /&gt;
&lt;br /&gt;
'''Nachteile'''&lt;br /&gt;
* Keine saubere Lösung: Es muss ein Kompromiss zwischen allen Möglichkeiten gefunden werden.&lt;br /&gt;
* Zener-Dioden kommen mit einem breiten Spektrum an Merkmalen. Deshalb könnten die Ergebnisse nicht reproduzierbar sein.&lt;br /&gt;
* Hohe Ströme beim Senden von High-Leveln&lt;br /&gt;
* Nicht viel Reserve beim Empfangen&lt;br /&gt;
&lt;br /&gt;
=== Allgemeine Anmerkungen zur Hardware ===&lt;br /&gt;
Es wird bei jeder der oben genannten Schaltungen ein PullUp-Widerstand (1,5k - 10k) von D- nach Vcc benötigt. Ebenso muss zwischen AVR und Die Datenleitungen ein Widerstand von je 68 Ohm.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Welche Taktraten können verwendet werden? ===&lt;br /&gt;
Momentan unterstützt V-USB Taktraten von 12 MHz, 12.8 MHz, 15 MHz, 16 MHz, 16.5 MHz, 18 MHz und 20 MHz. Diese Taktraten sind präzise, dies bedeutet, dass ein Quarz mit 11.9 MHz nicht funktionieren würde. Nur bei den 16.5 und 12.8 MHz Varianten ist eine Toleranz von 1%.16.5 MHz kann z.B. mit dem internen RC Oszillator von AVRs wie dem ATTiny25/45/85 oder dem ATTiny26 erreicht werden.&lt;br /&gt;
'''Entscheidungshilfe'''&lt;br /&gt;
* Möchten sie den internen RC Oszillator benutzen? Dann nehmen sie die 16.5MHz-Variante.&lt;br /&gt;
* Ist sehr wenig Speicher vorhanden? Verwenden sie am besten die 16MHz oder 20Mhz Variante.&lt;br /&gt;
* Wird der AVR mit einer niedrigen Spannung betrieben? Dann verwenden sie die 12MHz-Variante.&lt;br /&gt;
* Wollen sie CRC-Prüfsummen verwenden? Benutzen sie die 18Mhz-Variante.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anschluss an den AVR ===&lt;br /&gt;
Die Datenleitung D+ muss über den 68 Ohm-Widerstand mit dem Port INT0 des AVRs verbunden werden. D- kann an einen beliebigen Port. Diese Ports müssen dann in der &amp;quot;usbconfig.h&amp;quot; angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Software des AVR: Die Firmware ==&lt;br /&gt;
Als erstes muss man sich die neueste Version von V-USB von folgender Seite herunterladen: [http://www.obdev.at/products/vusb/download.html]&lt;br /&gt;
Nachdem sie das Archiv heruntergeladen haben, entpacken sie es und kopieren sie den Ordner &amp;quot;usbdrv&amp;quot; in ihr Projektverzeichnis. Kopieren bzw. erstellen sie das Makefile und passen darin die Taktrate und den verwendeten Controller an. Ebenso wird eine &amp;quot;usbconfig.h&amp;quot; benötigt, diese kann z.B. aus dem tests-Ordner kopiert werden. In dieser müssen nun die Punkte USB_CFG_IOPORTNAME, USB_CFG_DMINUS_BIT und USB_CFG_DPLUS_BIT angepasst werden.&lt;br /&gt;
&lt;br /&gt;
In der main.c müssen immer als erstes folgende Dateien importiert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt; //IO-Zugriff: Braucht man immer&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt; // V-USB braucht interrupts&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/wdt.h&amp;gt; //Watchdog: Sollte immer aktiv sein.&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;usbdrv.h&amp;quot; //Der USB-Treiber&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt; //Wird später für Timing etc. benötigt&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Gerät mit selbst geschriebenem PC-Treiber (kein HID) ===&lt;br /&gt;
Der Code für ein eigenes Gerät wird hier am Beispiel eines Gerätes veranschaulicht, bei dem sich über USB der PWM-Kanal steuern lässt. Damit kann man zum Beispiel eine LED dimmen.&lt;br /&gt;
&lt;br /&gt;
Nach den Includes komm nun die Funktion zum Verarbeiten eingehender Daten.&lt;br /&gt;
Das erste Empfangene Byte, also der Befehl wird mit rq-&amp;gt;bRequest abgefragt. In diesem Fall ist dieser entweder 0 oder 1. 0 bedeutet den PWM-Wert zu setzen, 1 bedeutet den Status (PWM-Wert) zurückzusenden.&lt;br /&gt;
Die einzelnen Parameter des Aufrufs können mit rq-&amp;gt;wValue.bytes[id] abgefragt werden. Bei Befehl 0 wird in rq-&amp;gt;wValue.bytes[0] der neue PWM-Wert übertragen. bytes[1] ist das 2. byte von wValue, welches beim Senden von Zahlen &amp;gt; 8bit entsteht. Ebenso gibt es noch rq-&amp;gt;wIndex[id], welches gleich funktioniert.&lt;br /&gt;
Durch setzen von replyBuf kann festgelegt werden, welche Daten zurückgesendet werden sollen. Dabei muss immer replyBuf[id] verwendet werden. Bei Befehl 1 wird mit replyBuf[0] = OCR1A der aktuelle PWM-Wert zurückgesendet.&lt;br /&gt;
Mit return 2 wird dann noch mitgeteilt, dass überhaupt was zurückgesendet werden soll (2 Bytes). Mit return 0 wird nichts zurückgesendet. Das ist in diesem Fall der Fall, wenn ein ungültiger Befehl übermittelt wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])&lt;br /&gt;
{&lt;br /&gt;
usbRequest_t    *rq = (void *)data;&lt;br /&gt;
static uchar    replyBuf[2];&lt;br /&gt;
&lt;br /&gt;
    usbMsgPtr = replyBuf;&lt;br /&gt;
    if(rq-&amp;gt;bRequest == 0){&lt;br /&gt;
	replyBuf[0] = rq-&amp;gt;wValue.bytes[0];&lt;br /&gt;
        replyBuf[1] = 0x0;&lt;br /&gt;
&lt;br /&gt;
	OCR1A=rq-&amp;gt;wValue.bytes[0];&lt;br /&gt;
	eeprom_write_byte(0,OCR1A);&lt;br /&gt;
	return 2;&lt;br /&gt;
    }&lt;br /&gt;
    else if (rq-&amp;gt;bRequest == 1) {&lt;br /&gt;
	replyBuf[0] = OCR1A;&lt;br /&gt;
        replyBuf[1] = 0x0;&lt;br /&gt;
	return 2;&lt;br /&gt;
    }&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;
Als nächstes komm void main:&lt;br /&gt;
Hier schalten wir als erstes den Watchdog-Timer ein. Danach setzen wir alle Ports und DDR so wie wir sie brauchen. Es ist nur darauf zu achten, dass INT0 ein Eingang ist. Bei einem Atmega8 ist dies PORTD.2. Für unser Beispiel setzen wir TCCR1A als 8_bit PWM-Timer. Danach laden wir den letzten PWM-Wert aus dem EEPROM (Wird immer beim Ändern gespeichert). Nun trennen wir die Verbindung für &amp;gt; 500ms, dies wird benötigt, um nach einen Neustart des Mikrocontrollers (z.B. durch Watchdog) dem PC mitzuteilen, dass er neugestartet ist. Danach Verbinden wir uns wieder mit usbDeviceConnect(). Nun muss die Verbindung mit usbInit() initialisiert werden ud die Interrupts mit sei() eingeschaltet werden. Nun muss nur noch im Mainloop der Watchdog zurückgesetzt werden und usbPoll() aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
uchar   i;&lt;br /&gt;
&lt;br /&gt;
    wdt_enable(WDTO_1S);&lt;br /&gt;
    DDRD = ~(1 &amp;lt;&amp;lt; 2);   /* all outputs except PD2 = INT0 */&lt;br /&gt;
    DDRB = 0xff;    /* output pins setzen */&lt;br /&gt;
    PORTD = 0;     /* USB-Verbindung */&lt;br /&gt;
    PORTB = 0;     /* output pins aus*/&lt;br /&gt;
&lt;br /&gt;
	TCCR1A = (1&amp;lt;&amp;lt;WGM10)|(1&amp;lt;&amp;lt;COM1A1); // PWM, phase correct, 8 bit.&lt;br /&gt;
	TCCR1B =  (1&amp;lt;&amp;lt;CS11) |(1&amp;lt;&amp;lt;CS10); // set clock/prescaler 1/64 -&amp;gt; enable counter&lt;br /&gt;
	OCR1A=eeprom_read_byte(0);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* We fake an USB disconnect by pulling D+ and D- to 0 during reset. This is&lt;br /&gt;
 * necessary if we had a watchdog reset or brownout reset to notify the host&lt;br /&gt;
 * that it should re-enumerate the device. Otherwise the host's and device's&lt;br /&gt;
 * concept of the device-ID would be out of sync.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */&lt;br /&gt;
    i = 0;&lt;br /&gt;
    while(--i){         /* fake USB disconnect for &amp;gt; 500 ms */&lt;br /&gt;
        wdt_reset();&lt;br /&gt;
        _delay_ms(2);&lt;br /&gt;
    }&lt;br /&gt;
    usbDeviceConnect();&lt;br /&gt;
    usbInit();&lt;br /&gt;
    sei();&lt;br /&gt;
    for(;;){    /* main event loop */&lt;br /&gt;
        wdt_reset();&lt;br /&gt;
        usbPoll();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist die Firmware fertig. Hier noch ein Makefile für avr-gcc: (Chip: Mega8, Clock: 12MHz, Programmer: Ponyser)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Name: Makefile&lt;br /&gt;
# Project: edited PowerSwitch&lt;br /&gt;
# Author: &lt;br /&gt;
# Creation Date: &lt;br /&gt;
# Tabsize: 4&lt;br /&gt;
# Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH&lt;br /&gt;
# License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)&lt;br /&gt;
# This Revision: $Id: Makefile 277 2007-03-20 10:53:33Z cs $&lt;br /&gt;
&lt;br /&gt;
DEVICE = atmega8&lt;br /&gt;
AVRDUDE = avrdude -c ponyser -P /dev/ttyS0 -p $(DEVICE)&lt;br /&gt;
# Choose your favorite programmer and interface above.&lt;br /&gt;
&lt;br /&gt;
COMPILE = avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=$(DEVICE) #-DDEBUG_LEVEL=2&lt;br /&gt;
# NEVER compile the final product with debugging! Any debug output will&lt;br /&gt;
# distort timing so that the specs can't be met.&lt;br /&gt;
&lt;br /&gt;
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o&lt;br /&gt;
&lt;br /&gt;
# symbolic targets:&lt;br /&gt;
all:	main.hex&lt;br /&gt;
&lt;br /&gt;
.c.o:&lt;br /&gt;
	$(COMPILE) -c $&amp;lt; -o $@&lt;br /&gt;
&lt;br /&gt;
.S.o:&lt;br /&gt;
	$(COMPILE) -x assembler-with-cpp -c $&amp;lt; -o $@&lt;br /&gt;
# &amp;quot;-x assembler-with-cpp&amp;quot; should not be necessary since this is the default&lt;br /&gt;
# file type for the .S (with capital S) extension. However, upper case&lt;br /&gt;
# characters are not always preserved on Windows. To ensure WinAVR&lt;br /&gt;
# compatibility define the file type manually.&lt;br /&gt;
&lt;br /&gt;
.c.s:&lt;br /&gt;
	$(COMPILE) -S $&amp;lt; -o $@&lt;br /&gt;
&lt;br /&gt;
flash:	all&lt;br /&gt;
	$(AVRDUDE) -U flash:w:main.hex:i&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Fuse low byte:&lt;br /&gt;
# 0xef = 1 1 1 0   1 1 1 1&lt;br /&gt;
#        ^ ^ \+/   \--+--/&lt;br /&gt;
#        | |  |       +------- CKSEL 3..0 (clock selection -&amp;gt; crystal @ 12 MHz)&lt;br /&gt;
#        | |  +--------------- SUT 1..0 (BOD enabled, fast rising power)&lt;br /&gt;
#        | +------------------ CKOUT (clock output on CKOUT pin -&amp;gt; disabled)&lt;br /&gt;
#        +-------------------- CKDIV8 (divide clock by 8 -&amp;gt; don't divide)&lt;br /&gt;
#&lt;br /&gt;
# Fuse high byte:&lt;br /&gt;
# 0xdb = 1 1 0 1   1 0 1 1&lt;br /&gt;
#        ^ ^ ^ ^   \-+-/ ^&lt;br /&gt;
#        | | | |     |   +---- RSTDISBL (disable external reset -&amp;gt; enabled)&lt;br /&gt;
#        | | | |     +-------- BODLEVEL 2..0 (brownout trigger level -&amp;gt; 2.7V)&lt;br /&gt;
#        | | | +-------------- WDTON (watchdog timer always on -&amp;gt; disable)&lt;br /&gt;
#        | | +---------------- SPIEN (enable serial programming -&amp;gt; enabled)&lt;br /&gt;
#        | +------------------ EESAVE (preserve EEPROM on Chip Erase -&amp;gt; not preserved)&lt;br /&gt;
#        +-------------------- DWEN (debug wire enable)&lt;br /&gt;
#fuse_tiny2313:	# only needed for attiny2313&lt;br /&gt;
	# $(AVRDUDE) -U hfuse:w:0xdb:m -U lfuse:w:0xef:m&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.bin *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s&lt;br /&gt;
&lt;br /&gt;
# file targets:&lt;br /&gt;
main.bin:	$(OBJECTS)&lt;br /&gt;
	$(COMPILE) -o main.bin $(OBJECTS)&lt;br /&gt;
&lt;br /&gt;
main.hex:	main.bin&lt;br /&gt;
	rm -f main.hex main.eep.hex&lt;br /&gt;
	avr-objcopy -j .text -j .data -O ihex main.bin main.hex&lt;br /&gt;
	./checksize main.bin&lt;br /&gt;
# do the checksize script as our last action to allow successful compilation&lt;br /&gt;
# on Windows with WinAVR where the Unix commands will fail.&lt;br /&gt;
&lt;br /&gt;
disasm:	main.bin&lt;br /&gt;
	avr-objdump -d main.bin&lt;br /&gt;
&lt;br /&gt;
cpp:&lt;br /&gt;
	$(COMPILE) -E main.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
D+ ist in diesem Beispiel mit PD2 verbunden, D- mit PD0. Die LED hängt an PB1. (Schaltplan noch in Arbeit.)&lt;br /&gt;
[http://www.rn-wissen.de/index.php/V-USB:_Ein_Firmware_USB-Treiber_f%C3%BCr_AVR#PC-Software_bei_nicht_HID-Projekten_.28Treiber.29 Hier gehts zur PC-Seitigen Programmierung dieses Projekts]&lt;br /&gt;
&lt;br /&gt;
=== HID-Gerät (Tastatur/Maus/...) ===&lt;br /&gt;
[noch in Arbeit]&lt;br /&gt;
&lt;br /&gt;
== PC-Software bei nicht HID-Projekten (Treiber) ==&lt;br /&gt;
'''WARNUNG: Dieser Absatz ist veraltet und funktioniert NICHT mit der aktuellen libusb!'''&lt;br /&gt;
Ein etwas aktuelleres Tutorial, welches leider auch veraltet ist sei dennoch mal genannt: [http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/ dreamincode.net]&lt;br /&gt;
&lt;br /&gt;
Wenn man nun ein Gerät mit einer Firmware hat, muss man als nächstes den Treiber für den PC schreiben. Dies werde ich nun am obigen Beispiel erläutern.&lt;br /&gt;
&lt;br /&gt;
Als erstes sollte man sich überlegen, was die Software können muss. In unserem Beispiel wären das:&lt;br /&gt;
* Den PWM-Wert setzen&lt;br /&gt;
* Befehl ein/aus&lt;br /&gt;
* aktuellen Wert auslesen&lt;br /&gt;
Die Befehle ein bzw. aus müssen dabei keine eigenen Befehle werden, da man dafür den Wert 255(an) bzw. 0(aus) senden kann.&lt;br /&gt;
&lt;br /&gt;
Um nun überhaupt einen USB-Treiber schreiben zu können, muss man sich als erstes &amp;quot;libusb&amp;quot; für c bzw. &amp;quot;libusb++&amp;quot; für c++ herunterladen. Unter Linux kann dies über den Paketmanager (Synaptic/Aptitude) geschehen. Unter Windows muss man sich die Bibliothek von folgender Seite herunterladen: [http://www.libusb.org/ http://www.libusb.org/]/[http://libusb.sourceforge.net/ http://libusb.sourceforge.net/]. Stellen sie sicher, dass wenn sie unter Windows arbeiten, die Win32-Version herunterladen.&lt;br /&gt;
&lt;br /&gt;
Als erstes muss man auch wieder einige Header importieren:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;  /* Brauchen wir für Ein-/ bzw. Ausgabe */&lt;br /&gt;
#include &amp;lt;string.h&amp;gt; /* Brauchen wir für die Auswertung von Parametern */&lt;br /&gt;
#include &amp;lt;usb.h&amp;gt;    /* Die Bibliothek - Liegt diese im Projektverzeichnis so muss #include &amp;quot;usb.h&amp;quot; verwendet werden*/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als nächstes müssen die VendorID und PID definiert werden. Diese können aus der Datei &amp;quot;USBID-License.txt&amp;quot; entnommen werden. WICHTIG: Zuerst ganz durchlesen um die Richtige auszuwählen.&lt;br /&gt;
Diese definiert man dann mit:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define USBDEV_SHARED_VENDOR    0x16C0  /* VOTI */&lt;br /&gt;
#define USBDEV_SHARED_PRODUCT   0x05DC  /* Obdev's free shared PID */&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In diesem Beispiel wurde die VendorID/PID so gewählt, dass es keine Klasse hat, also ein eigenes Gerät ist.&lt;br /&gt;
&lt;br /&gt;
Danach sollte man der Übersichtlichkeit halber, die einzelnen Befehle (welche einzelne Bytes sind) definieren. Für unser Beispiel heißt das:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define CMD_SETPWM  0&lt;br /&gt;
#define CMD_GETSTATUS   1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da dieses Projekt eine Konsolen-basierte Anwendung ist, ist es immer wichtig eine Hilfe mit den befehlen einzubauen. Nennen wir diese Funktion einfach usage: (Es kann selbstverständlich auch auf stdout ausgegeben werden.)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
static void usage(char *name)&lt;br /&gt;
{&lt;br /&gt;
    fprintf(stderr, &amp;quot;usage:\n&amp;quot;);&lt;br /&gt;
    fprintf(stderr, &amp;quot;  %s on\n&amp;quot;, name);&lt;br /&gt;
    fprintf(stderr, &amp;quot;  %s off\n&amp;quot;, name);&lt;br /&gt;
    fprintf(stderr, &amp;quot;  %s pwm [0-255]\n&amp;quot;, name);&lt;br /&gt;
    fprintf(stderr, &amp;quot;  %s status\n&amp;quot;, name);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als nächstes brauchen wir Funktionen zum Öffnen und Kommunizieren mit dem Gerät. Diese wurden aus dem Beispiel &amp;quot;PowerSwitch&amp;quot; von obdev kopiert:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
static int  usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)&lt;br /&gt;
{&lt;br /&gt;
char    buffer[256];&lt;br /&gt;
int     rval, i;&lt;br /&gt;
&lt;br /&gt;
    if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING &amp;lt;&amp;lt; 8) + index, langid, buffer, sizeof(buffer), 1000)) &amp;lt; 0)&lt;br /&gt;
        return rval;&lt;br /&gt;
    if(buffer[1] != USB_DT_STRING)&lt;br /&gt;
        return 0;&lt;br /&gt;
    if((unsigned char)buffer[0] &amp;lt; rval)&lt;br /&gt;
        rval = (unsigned char)buffer[0];&lt;br /&gt;
    rval /= 2;&lt;br /&gt;
    /* lossy conversion to ISO Latin1 */&lt;br /&gt;
    for(i=1;i&amp;lt;rval;i++){&lt;br /&gt;
        if(i &amp;gt; buflen)  /* destination buffer overflow */&lt;br /&gt;
            break;&lt;br /&gt;
        buf[i-1] = buffer[2 * i];&lt;br /&gt;
        if(buffer[2 * i + 1] != 0)  /* outside of ISO Latin1 range */&lt;br /&gt;
            buf[i-1] = '?';&lt;br /&gt;
    }&lt;br /&gt;
    buf[i-1] = 0;&lt;br /&gt;
    return i-1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#define USB_ERROR_NOTFOUND  1&lt;br /&gt;
#define USB_ERROR_ACCESS    2&lt;br /&gt;
#define USB_ERROR_IO        3&lt;br /&gt;
&lt;br /&gt;
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName)&lt;br /&gt;
{&lt;br /&gt;
struct usb_bus      *bus;&lt;br /&gt;
struct usb_device   *dev;&lt;br /&gt;
usb_dev_handle      *handle = NULL;&lt;br /&gt;
int                 errorCode = USB_ERROR_NOTFOUND;&lt;br /&gt;
static int          didUsbInit = 0;&lt;br /&gt;
&lt;br /&gt;
    if(!didUsbInit){&lt;br /&gt;
        didUsbInit = 1;&lt;br /&gt;
        usb_init();&lt;br /&gt;
    }&lt;br /&gt;
    usb_find_busses();&lt;br /&gt;
    usb_find_devices();&lt;br /&gt;
    for(bus=usb_get_busses(); bus; bus=bus-&amp;gt;next){&lt;br /&gt;
        for(dev=bus-&amp;gt;devices; dev; dev=dev-&amp;gt;next){&lt;br /&gt;
            if(dev-&amp;gt;descriptor.idVendor == vendor &amp;amp;&amp;amp; dev-&amp;gt;descriptor.idProduct == product){&lt;br /&gt;
                char    string[256];&lt;br /&gt;
                int     len;&lt;br /&gt;
                handle = usb_open(dev); /* we need to open the device in order to query strings */&lt;br /&gt;
                if(!handle){&lt;br /&gt;
                    errorCode = USB_ERROR_ACCESS;&lt;br /&gt;
                    fprintf(stderr, &amp;quot;Warning: cannot open USB device: %s\n&amp;quot;, usb_strerror());&lt;br /&gt;
                    continue;&lt;br /&gt;
                }&lt;br /&gt;
                if(vendorName == NULL &amp;amp;&amp;amp; productName == NULL){  /* name does not matter */&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
                /* now check whether the names match: */&lt;br /&gt;
                len = usbGetStringAscii(handle, dev-&amp;gt;descriptor.iManufacturer, 0x0409, string, sizeof(string));&lt;br /&gt;
                if(len &amp;lt; 0){&lt;br /&gt;
                    errorCode = USB_ERROR_IO;&lt;br /&gt;
                    fprintf(stderr, &amp;quot;Warning: cannot query manufacturer for device: %s\n&amp;quot;, usb_strerror());&lt;br /&gt;
                }else{&lt;br /&gt;
                    errorCode = USB_ERROR_NOTFOUND;&lt;br /&gt;
                    /* fprintf(stderr, &amp;quot;seen device from vendor -&amp;gt;%s&amp;lt;-\n&amp;quot;, string); */&lt;br /&gt;
                    if(strcmp(string, vendorName) == 0){&lt;br /&gt;
                        len = usbGetStringAscii(handle, dev-&amp;gt;descriptor.iProduct, 0x0409, string, sizeof(string));&lt;br /&gt;
                        if(len &amp;lt; 0){&lt;br /&gt;
                            errorCode = USB_ERROR_IO;&lt;br /&gt;
                            fprintf(stderr, &amp;quot;Warning: cannot query product for device: %s\n&amp;quot;, usb_strerror());&lt;br /&gt;
                        }else{&lt;br /&gt;
                            errorCode = USB_ERROR_NOTFOUND;&lt;br /&gt;
                            /* fprintf(stderr, &amp;quot;seen product -&amp;gt;%s&amp;lt;-\n&amp;quot;, string); */&lt;br /&gt;
                            if(strcmp(string, productName) == 0)&lt;br /&gt;
                                break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                usb_close(handle);&lt;br /&gt;
                handle = NULL;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        if(handle)&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    if(handle != NULL){&lt;br /&gt;
        errorCode = 0;&lt;br /&gt;
        *device = handle;&lt;br /&gt;
    }&lt;br /&gt;
    return errorCode;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als letztes kommt nun void main. In main muss als erstes ein Handle für das USB-Gerät definiert werden. Danach brauchen wir noch einen Buffer für Dinge, die vom Gerät kommen und dann noch einen Zähler für empfangene Bytes.&lt;br /&gt;
Danach prüfen wir, ob der Programmaufruf korrekt ist. (Parameterzahl):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
usb_dev_handle      *handle = NULL;&lt;br /&gt;
unsigned char       buffer[8];&lt;br /&gt;
int                 nBytes;&lt;br /&gt;
&lt;br /&gt;
    if(argc &amp;lt; 2){&lt;br /&gt;
        usage(argv[0]);&lt;br /&gt;
        exit(1);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Danach muss libusb initialisiert werden dann das Gerät mit der obigen Funktion geöffnet werden. Dabei musst du natürlich Email/Homepage durch deine Homepage bzw. E-Mail ersetzen. Ebenso muss der Name, in diesem Fall PWMControl angepasst werden. Die beiden Werte wurden vorher in der Datei &amp;quot;usbconfig.h&amp;quot; festgelegt. Lesen sie dazu jedoch die Datei &amp;quot;USBID-License.txt&amp;quot;. Diese Werte können natürlich auch als Defines gesetzt werden.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
usb_init();&lt;br /&gt;
    if(usbOpenDevice(&amp;amp;handle, USBDEV_SHARED_VENDOR, &amp;quot;EMail/Homepage&amp;quot;, USBDEV_SHARED_PRODUCT, &amp;quot;PWMControl&amp;quot;) != 0){&lt;br /&gt;
        fprintf(stderr, &amp;quot;Could not find USB device \&amp;quot;PWMControl\&amp;quot; with vid=0x%x pid=0x%x\n&amp;quot;, USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT);&lt;br /&gt;
        exit(1);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Als nächstes kommt unser eigentlicher Programmcode. In diesem wird zuerst überprüft ob on/off/pwm oder status übergeben wurde. Bei PWM wird zusätzlich geprüft, ob noch der PWM-Wert mit angegeben wurde. Mit dem befehl '' nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, [Befehl], [Param1], [Param2], (char *)buffer, sizeof(buffer), 5000);'' kann man nun Daten an das Gerät schicken. Sendet das Gerät Daten zurück, so sind diese in buffer abrufbar. Ebenfalls wird noch überprüft, ob ein fehler auftrat. Dies erfolgt mit ''if(nBytes &amp;lt; 0)''.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if(strcmp(argv[1], &amp;quot;pwm&amp;quot;) == 0){&lt;br /&gt;
		   if(argc &amp;lt; 3){&lt;br /&gt;
            		usage(argv[0]);&lt;br /&gt;
            		exit(1);&lt;br /&gt;
        	   }&lt;br /&gt;
            nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_SETPWM, atoi(argv[2]), 0, (char *)buffer, sizeof(buffer), 5000);&lt;br /&gt;
        }else if(strcmp(argv[1], &amp;quot;off&amp;quot;) == 0){&lt;br /&gt;
            nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_SETPWM, 0, 255, (char *)buffer, sizeof(buffer), 5000);&lt;br /&gt;
	}else if(strcmp(argv[1], &amp;quot;on&amp;quot;) == 0){&lt;br /&gt;
            nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_SETPWM, 255, 255, (char *)buffer, sizeof(buffer), 5000);       &lt;br /&gt;
	}else if(strcmp(argv[1], &amp;quot;status&amp;quot;) == 0){&lt;br /&gt;
            nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_GETSTATUS, 0, 0, (char *)buffer, sizeof(buffer), 5000);       	&lt;br /&gt;
	&lt;br /&gt;
 	if(nBytes &amp;lt; 2){&lt;br /&gt;
            if(nBytes &amp;lt; 0)&lt;br /&gt;
                fprintf(stderr, &amp;quot;USB error: %s\n&amp;quot;, usb_strerror());&lt;br /&gt;
            fprintf(stderr, &amp;quot;only %d bytes status received\n&amp;quot;, nBytes);&lt;br /&gt;
            exit(1);&lt;br /&gt;
        }&lt;br /&gt;
	printf(&amp;quot;%i\n&amp;quot;, buffer[0]);&lt;br /&gt;
&lt;br /&gt;
	}else{&lt;br /&gt;
            nBytes = 0;&lt;br /&gt;
            usage(argv[0]);&lt;br /&gt;
            exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        if(nBytes &amp;lt; 0)&lt;br /&gt;
            fprintf(stderr, &amp;quot;USB error: %s\n&amp;quot;, usb_strerror());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Letztendlich muss man das USB-gerät nur noch schließen und den void main beenden.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    usb_close(handle); //USB-Gerät schließen&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Quellen ==&lt;br /&gt;
* [http://www.obdev.at/products/vusb/index.html V-USB Homepage by Objective Development]&lt;br /&gt;
* [http://vusb.wikidot.com/ V-USB Wiki] &lt;br /&gt;
* Alle drei Schaltpläne wurden aus der Wiki von V-USB entnommen.&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
{{Ausbauwunsch|Das Thema HID-Geräte fehlt noch komplett.}}&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode C]]&lt;/div&gt;</summary>
		<author><name>Pit49</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Fototransistor&amp;diff=23021</id>
		<title>Fototransistor</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Fototransistor&amp;diff=23021"/>
				<updated>2013-09-25T15:28:47Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Bild:Fototransistor-Foto.JPG|thumb|Verschiedene Bauarten von Fototransistoren]]&lt;br /&gt;
Fototransistoren sind eine Art von [[Transistor | Transistoren]], die auf einfallendes Licht reagieren. Der Basis-Anschluss ist bei Fototransistoren optisch zugänglich.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
== Aufbau und Funktion ==&lt;br /&gt;
[[Bild:Fototransistor-Struktur.jpg|thumb|Innerer Aufbau eines Fototransistors]]&lt;br /&gt;
[[Bild:Fototransistor-Schaltbild.jpg|left]]''Schaltzeichen eines Fototransistors''&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
Wie die [[Fotodiode]] arbeitet auch der Fototransistor mit einer Halbleiterstrecke, die bei Lichteinfall ihre Eigenschaften ändert. Es handelt sich dabei um die Basis-Kollektor-Strecke, die als Fotodiode fungiert und den Basisstrom für den Fototransistor erzeugt. Der Fototransistor wird somit nur über das einfallende Licht gesteuert. Fällt Licht auf einen Fototransistor, dann erhöht sich der Strom, der zwischen Kollektor und Emitter fließt. Bei manchen Fototransistoren ist zudem der Basisanschluss herausgeführt. Dadurch ist eine Arbeitspunktstabilisierung oder eine Manipulation des Schaltverhaltens möglich.&lt;br /&gt;
&lt;br /&gt;
Die spektrale Empfindlichkeit von Fototransistoren ist mit der von Fotodioden vergleichbar, d.h. Fototransistoren aus Silizium haben ihr Maximum bei etwa 800 nm, solche aus Germanium bei etwa 1500 nm. Beide Wellenlängen liegen somit im Infrarotbereich.&lt;br /&gt;
&lt;br /&gt;
Fototransistoren haben ein lichtdurchlässiges Gehäuse, bei dem das Licht auf die Basis-Kollektor-Sperrschicht fallen kann. Die Empfindlichkeit ist jedoch auch vom verwendeten Material des Transistorgehäuses abhängig, ein transparentes Gehäuse hat eine breitere Empfindlichkeitskurve als ein schwarzes Epoxy-Gehäuse (IR-Filter). &lt;br /&gt;
&lt;br /&gt;
Der Vorteil des Fototransistors gegenüber der Fotodiode ist die wesentlich höhere Empfindlichkeit, denn der Fotostrom wird wie bei einem normalen bipolaren Transistor um etwa den Faktor 200 verstärkt. &lt;br /&gt;
Allerdings ist die Trägheit von Fototransistoren höher als die von Fotodioden: Die Grenzfrequenz eines Fototransistors liegt mit etwa 250 kHz wesentlich niedriger, bei Foto-Darlington-Transistoren liegt diese sogar nur bei ca. 30 kHz. Bei der typischen eher hochohmigen Beschaltung liegt die Grenzfrequenz sogar noch deutlich niedriger.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsbeispiele ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Fototransistor-analog.GIF|thumb|Fototransistor als Lichtstärkesensor]]&lt;br /&gt;
Häufig werden Fototransistoren als Lichtstärkesensor (z.B. in einem Roboter, der einer Linie folgt) verwendet und werden analog ausgewertet. Hierfür wird der Fototransistor zusammen mit einem Arbeitswiderstand von z.B. 10kOhm als Spannungsteiler geschaltet. Die Spannung am Widerstand ist dann näherungsweise proportional zur Helligkeit und kann direkt mit einem Analog-Digital-Wandler (wie er in den meisten Mikrocontrollern vorhanden ist) gemessen werden.&lt;br /&gt;
&lt;br /&gt;
Der Fototransistor wird üblicherweise gegen V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt; geschaltet und der Arbeitswiderstand gegen GND.&lt;br /&gt;
&lt;br /&gt;
Die Linearität ist besser als bei einem [[LDR]], aber schlechter als bei einer [[Fotodiode]].&lt;br /&gt;
&lt;br /&gt;
[[Bild:Optokoppler-Aufbau.GIF|thumb|Interner Aufbau eines Optokopplers]]Die Empfängerseite der meisten [[Optokoppler]] ist ein Fototransistor.&lt;br /&gt;
[[Bild:Fototransistor-Lichtschranke.GIF|thumb|Schaltplan einer Lichtschranke]]&lt;br /&gt;
Im Schaltplan rechts ist die einfachste Variante einer schnellen Lichtschranke zu sehen. R&amp;lt;sub&amp;gt;V&amp;lt;/sub&amp;gt; dient der Strombegrenzung durch die [[Leuchtdiode]], mit dem Widerstand R wird die Schaltschwelle eingestellt. Die Last muss keine Lampe, sondern kann jeder beliebige Verbraucher sein, vom [[Relais]] bis zum μController-Eingang. &lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vergleich bekannter Fototransistoren==&lt;br /&gt;
{| {{Blauetabelle}}&lt;br /&gt;
|-&lt;br /&gt;
| Name||Bauform||max. Empf.||Bereich der Empf. 10%||Empf. Fläche||Halbwinkel||Fotostrom typ.||Schaltzeit||Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|BP103B||5mm, klar||850nm||420...1300nm||0,12 mm²||+-25°||0,63-1,6 mA (3,4-8,6 mA)||7,5-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|BP103BF||5mm, dunkel||900nm||730...1120nm||0,045 mm²||+-12°||0,63-1,6 mA (3,4-8,6 mA)||7,5-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPW16N||3,3x2,4mm bedrahtet, klar||825nm||620...960nm||?||+-40°||0,07-0,14 mA||5µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPW17N||3,3x2,4mm bedrahtet, klar||825nm||620...960nm||?||+-12°||0,5-1 mA||5µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPW39||ähnlich TO-92, seitl. empf.||780nm||520...950nm||?||+-65°||0,5-1,6 mA||3,4µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPW40||5mm||780nm||520...950nm(50%)||?||+-20°||0,1-0,5 mA||3µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPW42||3mm||830nm||560...980nm(50%)||?||+-180°!?||0,9-1,9mA||3µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPX38||5mm Metall, hermetisch dicht TO-18||880nm||450-1120nm||0,675mm²||+-40°||0,2-3,6mA||9-18µs||Basis extra&lt;br /&gt;
|-&lt;br /&gt;
|BPX43||5mm Metall, hermetisch dicht TO-18||880nm||450...1100nm||0,675mm²||+-15°||0,8-15mA||9-18µs||Basis extra&lt;br /&gt;
|-&lt;br /&gt;
|BPX81||&amp;quot;einstellige Zeilenbauform&amp;quot; &amp;lt;3mm||850nm||440...1070nm||0,17mm²||+-18°||0,25-3,4mA||5,5-8µs||&lt;br /&gt;
|-&lt;br /&gt;
|BPY62||5mm Metall, hermetisch dicht||850nm||420...1130nm||0,12 mm²||+-8°||0,5-11,4mA||5-12µs||Basis extra&lt;br /&gt;
|-&lt;br /&gt;
|K153P&amp;lt;br/&amp;gt;(S472P)|| 5x5x2,7mm bedrahtet, dunkel||920nm||850...980nm(50%)||?||+-35°||1,7-5,5mA||4-15µs||&lt;br /&gt;
|-&lt;br /&gt;
|LPT80A||flach, 4,6x5,6x1,5mm; seitl. empf.||850nm||430...1070nm||0,30 mm²||+-35°||0,25-3,2mA||10µs||&lt;br /&gt;
|-&lt;br /&gt;
|PT15-21B/TR8||SMD 1206||940nm||730...1100nm||?||?||0,3 mA||15 µs||&lt;br /&gt;
|-&lt;br /&gt;
|PT331C||5mm, klar||940nm||400...1100nm||?||?||0,7-2,5 mA||15 µs||&lt;br /&gt;
|-&lt;br /&gt;
|SDP8406||.||ca. 870nm||ca.400...1100nm||?||ca.+-25°||bis 8 mA||ca.2-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|SDP8436||.||ca. 900nm||ca.750...1000nm||?||ca.+-10°||?||ca.2-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH300||5mm, klar||850nm||420...1130nm||0,12 mm²||+-25°||0,63-1,6 mA (3,4-8,6 mA)||7,5-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH300FA||5mm, dunkel||870nm||730...1120nm||0,12 mm²||+-25°||0,63-1,6 mA (3,4-8,6 mA)||7,5-10µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH305||&amp;quot;Mini-Bauform&amp;quot;||850nm||460...1060nm||0,17 mm²||+-16°||0,25-2,2 mA||5,5-6 µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH309||3mm, klar||860nm||380...1150nm||0,038 mm²||+-12°||0,4-5 mA (1,5-11,2 mA)||5-9µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH309FA||3mm, dunkel||900nm||730...1120nm||0,038 mm²||+-12°||0,4-5 mA (1,5-11,2 mA)||5-9µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH313||5mm, klar||850nm||460...1080nm||0,55mm²||+-10°||2,5-12,5mA||8-14µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH313FA||5mm, dunkel||870nm||740...1080nm||0,55mm²||+-10°||2,5-12,5mA||8-14µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH320||SMD, PLCC-2||980nm||450...1150nm||0,038mm²||+-60°||0,42-1mA||6-8µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH320FA||SMD, PLCC-2||980nm||750...1120nm||0,038mm²||+-60°||0,42-1mA||6-8µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH3100F||3mm, rechteckig, seitl. empf.||920nm||840...1080nm||1 mm²||+-14°||0,25mA||7-9µs||&lt;br /&gt;
|-&lt;br /&gt;
|SFH3310||3mm, klar||570nm||350...970nm||0,29 mm²||+-75°||2,5-8µA (290-460 µA)||?||&lt;br /&gt;
|-&lt;br /&gt;
|SFH3500||Surface Mount Radial||830nm||450...1060nm||0,55 mm²||+-13°||4-20 mA||17-24µs||&lt;br /&gt;
|-&lt;br /&gt;
|TEKT5400S||ähnlich TO-92, seitl. empf.||920nm||850...980nm(50%)||?||+-37°||4mA||5-6µs||&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Keine Garantie auf Vollständigkeit und Richtigkeit. Stand der Angaben: 12.Feb 2012 (BMS)&lt;br /&gt;
&lt;br /&gt;
== Anmerkungen ==&lt;br /&gt;
''Der Autor möchte hier weder die an anderen Stellen zu findenden Formelsammlungen wiedergeben, noch mit diesem Artikel ein Fachbuch ersetzten. Einzig die Grundlagen, die (aus eigener Erfahrung) für einen Hobby-Bastler von Interesse sind, sollen hier dargestellt werden.''&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Fotodiode]]&lt;br /&gt;
* [[Fotowiderstand]]&lt;br /&gt;
* [[Sensorarten]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://de.wikipedia.org Wikipedia]&amp;lt;br/&amp;gt;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/bau/0207012.htm Das ELektronik-KOmpendium - Fototransistor]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Autor ==&lt;br /&gt;
--[[Benutzer:Williwilli|Williwilli]] 20:26, 17. Okt 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
--[[Benutzer:BMS|BMS]] 20:50, 17. Mar 2011 (Tabelle)&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;br /&gt;
[[Kategorie:Sensoren]]&lt;/div&gt;</summary>
		<author><name>Pit49</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_Kompass_CMPS03&amp;diff=23020</id>
		<title>Bascom und Kompass CMPS03</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Bascom_und_Kompass_CMPS03&amp;diff=23020"/>
				<updated>2013-09-25T15:23:20Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Bild:kompass.jpeg|thumb|Wo gehts lang?]]Damit sich ein Roboter orientieren kann, gibt es die unterschiedlichsten Verfahren. Bei den meisten Verfahren wäre es hilfreich, wenn man wüsste, in welche Himmelsrichtung sich der Bot gerade bewegt. Wo ist Norden oder Süden? Genau für diesen Zweck wurde das Modul CMPS03 von Devantech entwickelt. Dieses Modul ist in der Handhabung äußerst einfach, es gibt über den I2C-Bus den genauen Winkel in Abstufungen von  0,1 Grad zum Nordpol aus, also 0 bis 360 Grad. Obwohl die Anwendung äußerst einfach ist, gibt es kaum Bascom-Beispiele.&lt;br /&gt;
Dem soll hier abgeholfen werden. Das nachfolgende Programm demonstriert die Anwendung mit dem bekannten Board RN-Control. Natürlich lassen sich die Funktionen auch einfach auf andere RN- oder AVR-Boards übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Die Pinbelegung des Modules==&lt;br /&gt;
&lt;br /&gt;
[[Bild:cmps3pin.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Einfacher Anschluss an den I2C-Bus==&lt;br /&gt;
Da [[RN-Control]] den Standard-I2C-Stecker (nach [[RN-Definitionen]]) benutzt, reicht ein Kabel für das Modul aus, die notwendige Betriebsspannung kann nämlich auch gleich über das I2C-Kabel erfolgen.&lt;br /&gt;
&lt;br /&gt;
Das Ganze sieht dann angeschlossen so aus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:kompassmodul_an_rncontrol.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Man benötigt nicht alle 10 Drähte des 10-pol. Kabels. Daher bastelt man sich einfach einen entsprechenden Stecker an das Kabel und schneidet die nicht benötigten Drähte ab. Da CMPS03 bereits über eine Stiftleiste verfügt, kann der Stecker dann bequem aufgesteckt werden. &lt;br /&gt;
&lt;br /&gt;
Das sieht dann beispielsweise so aus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:kompasskabel.gif|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Das Beispielprogramm in Bascom Basic==&lt;br /&gt;
Hier das vollständig dokumentierte Beispielprogramm für RN-Control. Das Programm kann unverändert übernommen und kompiliert werden. Es gibt über die RS232-Schnittstelle, also ein Terminalprogramm, die Firmwareversion und den Winkel zum Nordpol aus.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'###################################################&lt;br /&gt;
'cmps03_an_rncontrol.bas.bas&lt;br /&gt;
'für&lt;br /&gt;
'RoboterNetz Board RN-CONTROL (ab Version 1.1)&lt;br /&gt;
'und das Kompassmodul CMPS03 für Erkennung der Himmelsrichtung&lt;br /&gt;
'Datenblatt zu CMPS03 siehe Downloadbereich:&lt;br /&gt;
'http://www.roboternetz.de&lt;br /&gt;
&lt;br /&gt;
'Aufgabe:&lt;br /&gt;
' Gibt die Himmelsrichtung in Bezug auf Norden aus&lt;br /&gt;
&lt;br /&gt;
' Die Unterfunktionen können gerne in eigenen Programmen&lt;br /&gt;
' genutzt werden.&lt;br /&gt;
&lt;br /&gt;
' Autor: Frank  (Roboternetz)&lt;br /&gt;
' Modul: CMPS03 Devantech/robotikhardware.de  neueste Firmware&lt;br /&gt;
' Getestet mit CMPS Firmware 11&lt;br /&gt;
'#######################################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Declare Function Rn_cmps_himmelsrichtung() As Word&lt;br /&gt;
Declare Function Rn_cmps_firmware() As Byte&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
' ---------- Das RN-Control übliche --------------&lt;br /&gt;
$regfile = &amp;quot;m32def.dat&amp;quot;&lt;br /&gt;
$framesize = 42&lt;br /&gt;
$swstack = 32&lt;br /&gt;
$hwstack = 32&lt;br /&gt;
&lt;br /&gt;
$crystal = 16000000                 'Quarzfrequenz&lt;br /&gt;
$baud = 9600&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;
Dim Himmelsrichtung As Word&lt;br /&gt;
Dim Grad As Single&lt;br /&gt;
Dim V As Byte&lt;br /&gt;
&lt;br /&gt;
   Wait 3                           'Warte 3 Sekunde&lt;br /&gt;
   I2cinit&lt;br /&gt;
   Print &amp;quot;RN-Control CMPS03 Kompass Testprogramm &amp;quot;&lt;br /&gt;
   Print &amp;quot;CMPS03 Kompass Firmware Version:&amp;quot; ; Rn_cmps_firmware()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   V = 1&lt;br /&gt;
   Do&lt;br /&gt;
     Himmelsrichtung = Rn_cmps_himmelsrichtung()&lt;br /&gt;
     Print &amp;quot;Himmelsrichtung in 0,1 Grad Schritten: &amp;quot; ; Himmelsrichtung&lt;br /&gt;
     Grad = Himmelsrichtung / 10&lt;br /&gt;
     Print &amp;quot;Himmelsrichtung genau in Grad: &amp;quot; ; Grad&lt;br /&gt;
&lt;br /&gt;
     V = V + 3&lt;br /&gt;
     Wait 1&lt;br /&gt;
   Loop&lt;br /&gt;
&lt;br /&gt;
End&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function Rn_cmps_himmelsrichtung() As Word&lt;br /&gt;
Local Lob As Byte&lt;br /&gt;
Local Hib As Byte&lt;br /&gt;
Local Cmps_slaveid As Byte&lt;br /&gt;
Local Cmps_slaveid_read As Byte&lt;br /&gt;
&lt;br /&gt;
   Cmps_slaveid = &amp;amp;HC0&lt;br /&gt;
   Cmps_slaveid_read = Cmps_slaveid + 1&lt;br /&gt;
&lt;br /&gt;
   'Register auswählen&lt;br /&gt;
   I2cstart&lt;br /&gt;
   I2cwbyte Cmps_slaveid&lt;br /&gt;
   I2cwbyte 2&lt;br /&gt;
   I2cstop&lt;br /&gt;
&lt;br /&gt;
   I2cstart&lt;br /&gt;
   I2cwbyte Cmps_slaveid_read&lt;br /&gt;
   I2crbyte Hib , Ack&lt;br /&gt;
   I2crbyte Lob , Nack&lt;br /&gt;
   I2cstop&lt;br /&gt;
&lt;br /&gt;
   Rn_cmps_himmelsrichtung = Makeint(lob , Hib)&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Function Rn_cmps_firmware() As Byte&lt;br /&gt;
Local Firmware As Byte&lt;br /&gt;
Local Cmps_slaveid As Byte&lt;br /&gt;
Local Cmps_slaveid_read As Byte&lt;br /&gt;
&lt;br /&gt;
   Cmps_slaveid = &amp;amp;HC0&lt;br /&gt;
   Cmps_slaveid_read = Cmps_slaveid + 1&lt;br /&gt;
&lt;br /&gt;
   I2cstart&lt;br /&gt;
   I2cwbyte Cmps_slaveid&lt;br /&gt;
   I2cwbyte 0                'Leseregister festlegen&lt;br /&gt;
   I2cstop&lt;br /&gt;
&lt;br /&gt;
   I2cstart&lt;br /&gt;
   I2cwbyte Cmps_slaveid_read&lt;br /&gt;
   I2crbyte Firmware , Nack&lt;br /&gt;
   I2cstop&lt;br /&gt;
&lt;br /&gt;
   Rn_cmps_firmware = Firmware&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;
* [[Bascom]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
*  [http://www.roboternetz.de/phpBB2/dload.php?action=file&amp;amp;file_id=333 CMPS03 Deutsche als auch englische Anleitung/Datenblatt]&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>Pit49</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Beispiel_Drehzahlmessung_mit_RN-Control&amp;diff=21531</id>
		<title>Beispiel Drehzahlmessung mit RN-Control</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=Beispiel_Drehzahlmessung_mit_RN-Control&amp;diff=21531"/>
				<updated>2013-01-04T17:40:20Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wie einfach man mit einem Drehgeber die Drehzahl messen kann zeigt diese Schaltung /dieser Quelltext. Für dieses Beispiel wurde ein Drehgeber GP1A030 mit Codescheibe verwendet. Es könnte aber genauso ein GP1A038 oder ein ähnlicher Sensor sein. In diesem Demo wird nicht die Drehrichtung ausgewertet, obwohl es mit diesem Sensor ebenfalls möglich wäre.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:drehgeber_an_rncontrol.gif|center|framed|Beispielschaltung, wenn man lediglich die Drehzahl ohne Drehrichtung auswerten möchte. Als Widerstand hat sich 330 Ohm als gut erwiesen.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'###################################################&lt;br /&gt;
'rncontrol_drehzahl.BAS&lt;br /&gt;
'für&lt;br /&gt;
'RoboterNetz Board RN-CONTROL ab Version 1.1&lt;br /&gt;
'Das neue preiswerte Controllerboard zum Experimentieren&lt;br /&gt;
&lt;br /&gt;
' Achtung:&lt;br /&gt;
' Diese Demo ist mit Bascom Compiler 1.11.7.8 getestet&lt;br /&gt;
&lt;br /&gt;
'&lt;br /&gt;
'Aufgabe:&lt;br /&gt;
' Dieses Testprogramm demonstriert wie man mit Drehgebern&lt;br /&gt;
' die Umdrehungszahl von Motoren anzeigen kann&lt;br /&gt;
' Als Drehgeber wird ein Sharp GP1A030 mit Codescheibe&lt;br /&gt;
' verwendet (siehe http://www.robotikhardware.de Rubrik Sensoren)&lt;br /&gt;
' In diesem Demo wird nicht die Drehrichtung ausgewertet, daher&lt;br /&gt;
' wird nur ein Interrupt Port (INT0) an den Sensorausgang (VOA)&lt;br /&gt;
' angeschlossen. Zudem noch +5V, GND und +5V über 330 Ohm&lt;br /&gt;
' Widerstand an Anode des Sensors. Also einfachste Beschaltung.&lt;br /&gt;
&lt;br /&gt;
' Wenn man das Programm startet wird jede Sekunde die Drehzahl&lt;br /&gt;
' ermittelt und alle 3 Sekunden über RS232 auf einem&lt;br /&gt;
' Terminalprogramm (oder KN-KeyLCD) ausgegeben.&lt;br /&gt;
&lt;br /&gt;
' Das Programm eignet sich somit zum Messen von Drehzahlen als &lt;br /&gt;
' auch zur Überprüfung der Drehgeberfunktion. Es läßt sich&lt;br /&gt;
' sehr einfach zu Wegstrecken-Auswertung ausbauen. Statt&lt;br /&gt;
' an einem Interrupt könnte man den Sensor auch an einen Timereingang&lt;br /&gt;
' anschließen, jedoch wird dies hier im Programm nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Autor: Frank&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;
$regfile = &amp;quot;m32def.dat&amp;quot;&lt;br /&gt;
' bei Mega 16 $regfile = &amp;quot;m16def.dat&amp;quot;&lt;br /&gt;
$framesize = 32&lt;br /&gt;
$swstack = 32&lt;br /&gt;
$hwstack = 32&lt;br /&gt;
&lt;br /&gt;
$crystal = 16000000                                         'Quarzfrequenz&lt;br /&gt;
$baud = 9600&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Config Int0 = Falling&lt;br /&gt;
&lt;br /&gt;
Config Timer1 = Timer, Prescale = 256&lt;br /&gt;
Const Timervorgabe = 3036&lt;br /&gt;
Const Markierungenproscheibe = 120&lt;br /&gt;
&lt;br /&gt;
Dim Zaehlerirq0 As Long&lt;br /&gt;
Dim Impulseprosekunde As Long&lt;br /&gt;
Dim Impulseprominute As Long&lt;br /&gt;
Dim Umdrehungenprominute As Integer&lt;br /&gt;
&lt;br /&gt;
Print&lt;br /&gt;
Print &amp;quot;* RN-CONTROL 1.4 *&amp;quot;&lt;br /&gt;
Print &amp;quot;Drehzahl Messung&amp;quot;; &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Zaehlerirq0 = 0&lt;br /&gt;
On Int0 Irq0&lt;br /&gt;
Enable Int0&lt;br /&gt;
&lt;br /&gt;
On Timer1 Timer_irq&lt;br /&gt;
Enable Timer1&lt;br /&gt;
&lt;br /&gt;
Enable Interrupts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
   Print&lt;br /&gt;
   Print &amp;quot;Impulse Sek: &amp;quot;; Impulseprosekunde&lt;br /&gt;
   Impulseprominute = Impulseprosekunde * 60&lt;br /&gt;
   Umdrehungenprominute = Impulseprominute / Markierungenproscheibe&lt;br /&gt;
   Print &amp;quot;Umdreh. Min: &amp;quot;; Umdrehungenprominute&lt;br /&gt;
   Wait 3&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;
'Pro Impuls (Markierung auf Scheibe) ein Aufruf&lt;br /&gt;
Irq0:&lt;br /&gt;
 Incr Zaehlerirq0&lt;br /&gt;
Return&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'Pro Sekunde ein Aufruf&lt;br /&gt;
Timer_irq:&lt;br /&gt;
  Timer1 = Timervorgabe&lt;br /&gt;
  Impulseprosekunde = Zaehlerirq0&lt;br /&gt;
  Zaehlerirq0 = 0&lt;br /&gt;
  Return&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[RN-Control]]&lt;br /&gt;
* [[Avr]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Robotikeinstieg]]&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Software]]&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Pit49</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=Bascom_und_USI-Kommunikation&amp;diff=9907</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=9907"/>
				<updated>2006-12-23T20:44:30Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &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;
&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 anschließend 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 anschließend 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>Pit49</name></author>	</entry>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=AT90S2313&amp;diff=9906</id>
		<title>AT90S2313</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=AT90S2313&amp;diff=9906"/>
				<updated>2006-12-23T20:34:42Z</updated>
		
		<summary type="html">&lt;p&gt;Pit49: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Versorgungspannung:''' &lt;br /&gt;
::AT90S2313-4: 2.7V - 6V&lt;br /&gt;
::AT90S2313-10: 4V - 6V&lt;br /&gt;
::ATTiny2313-20: 1.8V - 5.5V&lt;br /&gt;
'''Flash-Programm-Speicher:''' 2kByte &amp;lt;br&amp;gt;&lt;br /&gt;
'''EEPROM-Datenspeicher:''' 128Byte &amp;lt;br&amp;gt;&lt;br /&gt;
'''SRAM-Datenspeicher:''' 128 Byte &amp;lt;br&amp;gt;&lt;br /&gt;
'''Taktfrequenz:'''&lt;br /&gt;
::AT90S2313-4: bis 4MHz&lt;br /&gt;
::AT90S2313-10: bis 10MHz&lt;br /&gt;
::ATTiny2313-20: bis 20MHz&lt;br /&gt;
'''Features:'''&lt;br /&gt;
* Full Duplex UART&lt;br /&gt;
* ein 8-bit Timer&lt;br /&gt;
* ein 16-bit Timer mit PWM, InputCapture, external Clock&lt;br /&gt;
* Analog-Comparator&lt;br /&gt;
* 15 digitale I/O-Ports&lt;br /&gt;
* programmierbarer Watchdog-Timer&lt;br /&gt;
'''weitere Features beim Tiny2313:'''&lt;br /&gt;
* 4 PWM Kanäle beim Tiny2313&lt;br /&gt;
* 18 digitale I/O-Ports wenn kein externer Quarz und kein Reset benutzt werden&lt;br /&gt;
* [[USI (Avr)|Universelle serielle Schnittstelle (USI)]], damit kann [[TWI]] oder [[SPI]] nachgebildet werden&lt;br /&gt;
* Pin Change Interrupts an PortB&lt;br /&gt;
* Debug-wire&lt;br /&gt;
* Interner RC-Oszillator bis 8 MHz&lt;br /&gt;
* erweiterte USART, mit Parity-Bit usw.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der AT90S2313 ist heute veraltet. Der Hersteller empfiehlt, für neue Designs den [[ATtiny2313]] zu verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:at90s2313tiny.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
* [[Atmel]]&lt;br /&gt;
* [[AVR]]&lt;br /&gt;
* [[HEX Beispiel-Dateien für AVR]]&lt;br /&gt;
&lt;br /&gt;
== Packages==&lt;br /&gt;
* PDIP 20&lt;br /&gt;
* SOIC 20 &lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/DOC0839.PDF Datenblatt des AT90S2313 (englisches PDF, 92 Seiten, 1.6 MByte)]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc4298.pdf AVR091: Replacing AT90S2313 by ATtiny2313 (englisches PDF, 11 Seiten, 118 kByte)]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2543.pdf Datenblatt des ATTiny2313 (englisches PDF, 231 Seiten, 2MB)]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Microcontroller]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Elektronik]]&lt;/div&gt;</summary>
		<author><name>Pit49</name></author>	</entry>

	</feed>