AVR Embedded Tutorial - I²C, TWI/de
I²C / TWI
Vorwort
Dieser Code ist für einen Atmega328/Arduino mit 16MHz. Wie man die UART ansteuert, steht hier:
- UART UARTInit und UARTSendString(...
Beschreibung
Dieses Beispiel demonstriert die Kommunikation mit der I²C/TWI - Schnittstelle.
Als Slave-Geräte werden 2 AD1115 A/D-Wandler verwendet. Diese sind sehr einfach in der Handhabung und sind auch sehr einfach erhältlich. Was sehr wichtig ist, dass man bei TWIStart die Adresse um ein Bit nach links verschiebt und anschließend mittels Write/Read mit or verknüpft. Es gibt viele Tutorials dazu. Dort sieht man das leider sehr schlecht.
PulUp-Widerstände sind nicht nötig, da diese schon auf der Platine des ADS1115 verbaut sind.
I²C Funktionen
Konstanten
const
CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
ADSaddr0 = $48; // Adresse Wandler 0
ADSaddr1 = $49; // Adresse Wandler 1
I2C_Takt = 400000; // I²C-Takt (400KHz)
TWI_Write = 0;
TWI_Read = 1;
I²C inizialisieren
procedure TWIInit;
const
TWBR_val = byte((CPU_Clock div I2C_Takt) - 16) div 2;
begin
TWSR := 0;
TWBR := byte(TWBR_val);
end;
I²C Senden/Empfangen starten
procedure TWIStart(addr: byte);
begin
// Senden/Empfangen einleiten
TWCR := 0;
TWCR := (1 shl TWINT) or (1 shl TWSTA) or (1 shl TWEN);
while ((TWCR and (1 shl TWINT)) = 0) do begin
end;
// Adresse des Endgerätes senden
TWDR := addr;
TWCR := (1 shl TWINT) or (1 shl TWEN);
while ((TWCR and (1 shl TWINT)) = 0) do begin
end;
end;
I²C Senden/Empfang beendet
procedure TWIStop;
begin
TWCR := (1 shl TWINT) or (1 shl TWSTO) or (1 shl TWEN);
end;
Zeichen Senden
procedure TWIWrite(u8data: byte);
begin
TWDR := u8data;
TWCR := (1 shl TWINT) or (1 shl TWEN);
while ((TWCR and (1 shl TWINT)) = 0) do begin
end;
end;
Zeichen Empfangen
Bis auf das vorletzte Zeichen muss mit TWIReadACK(... gelesen werden. Das letzte Zeichen muss mit TWIReadNACK(... gelesen werden.
// Lesen bis zum vorletzten Zeichen.
function TWIReadACK: byte;
begin
TWCR := (1 shl TWINT) or (1 shl TWEN) or (1 shl TWEA);
while (TWCR and (1 shl TWINT)) = 0 do begin
end;
Result := TWDR;
end;
// Letztes Zeichen lesen.
function TWIReadNACK: byte;
begin
TWCR := (1 shl TWINT) or (1 shl TWEN);
while (TWCR and (1 shl TWINT)) = 0 do begin
end;
Result := TWDR;
end;
ADS1115 spezifischen Code
Dieser Code ist ADS1115 spezifischen, andere I²C-Geräte müssen im Datenblatt nachgeguckt werden.
// Parameter an ADS1115 schicken und Messen einleiten
procedure WriteADS1115(addr: UInt16);
begin
TWIStart((addr shl 1) or TWI_Write);
TWIWrite(1);
TWIWrite(%11000011); // High
TWIWrite(%11100011); // Low
TWIStop;
end;
// Messung von ADS1115 auslesen.
function ReadADS1115(addr: UInt16): UInt16;
begin
TWIStart((addr shl 1) or TWI_Write);
TWIWrite(0);
TWIStop;
TWIStart((addr shl 1) or TWI_Read);
Result := TWIReadACK * $100 + TWIReadNACK;
TWIStop;
end;
Beispiel
var
Data: integer;
s: ShortString;
begin
asm cli end; // Interrupt sperren.
UARTInit;
TWIInit;
asm sei end; // Interrupt frei geben.
repeat
WriteADS1115(ADSaddr0);
Data := ReadADS1115(ADSaddr0);
str(Data: 6, s);
UARTSendString('Kanal 0: ');
UARTSendString(s);
WriteADS1115(ADSaddr1);
Data := ReadADS1115(ADSaddr1);
str(Data: 6, s);
UARTSendString(' Kanal 1: ');
UARTSendString(s);
UARTSendString(#13#10);
until 1 = 2;
end.
Parameter ADS1115
Eine kleine Auflistung der wichtigsten Parameter des ADS1115. Mehr Infos im Datenblatt.
Low: 11100011
???00011: SPS Bit [7:5]
Bit | SPS |
---|---|
000 | 8 |
001 | 16 |
010 | 32 |
011 | 64 |
100 | 128 |
101 | 250 |
110 | 475 |
111 | 860 (default) |
High: 11000011
1???0011: Kanal (Multiplex) Bit [14:12]
Bit | Kanal |
---|---|
100 | 0 (default) |
101 | 1 |
110 | 2 |
111 | 3 |
1100???1: Gain Bit [11:9] (Volt)
Bit | Volt |
---|---|
000 | FS = ±6.144 |
001 | FS = ±4.096 |
010 | FS = ±2.048 (default) |
011 | FS = ±1.024 |
100 | FS = ±0.512 |
101 | FS = ±0.256 |
110 | FS = ±0.256 |
111 | FS = ±0.256 |
Siehe auch
- Übersichtseite AVR Embedded Tutorial/de
Autor: Mathias