PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USI - I2C - Master - Lib



linux_80
14.01.2007, 19:59
Hallo,

da ich mich schon über einen längeren Zeitraum mit dem USI-Modul der AVRs beschäftige, hatte ich heute wieder Zeit und Lust, etwas daran zu optimieren.

Herausgekommen ist eine Bascom-Library um sie in ein Programm einzubinden, damit man die typischen Bascom-Befehle für I2C verwenden kann.
Es muss also nur diese Lib eingebunden werden, dann kann ganz normal mit Config ... und I2cwbyte usw. weitergearbeitet werden.

Sieht dann so aus:

$lib "i2c_usi.lbx"

Config Scl = Portb.7 ' Ports fuer I2C-Bus
Config Sda = Portb.5
'Config I2cdelay = 10 ' je höher der Wert umso langsamer der Bus

I2cinit

' usw.


Da ich von den original Lib's abgeschaut habe, weiss ich nicht was man alles verbreiten darf, deshalb erstmal nur die compilierte Version im Anhang, denn in der Demo von Bascom sind auch die vorcompilierten Libs dabei, die jeder einsehen kann.

Meine Testumgebung:
Master : Tiny2313, oder Tiny45
Slaves : DS1621 Tempsensor, PCF8574 um den Wert an LEDs auszugeben.

hier noch ein Bildchen mit der Tiny45 Umgebung:
https://www.roboternetz.de/phpBB2/album_thumbnail.php?pic_id=1191 (https://www.roboternetz.de/phpBB2/album_pic.php?pic_id=1191)
Click zum vergrössern
Auf den ersten 7 LEDs des PCF wird der Temperaturwert angegeben, die 8. LED, ganz rechts, gibt die 0.5 Grad an.

Die Vorgeschichte ist in diesem Thread zu lesen:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25058
weiteres im Wiki unter
USI (Avr) (https://www.roboternetz.de/wissen/index.php/USI_%28Avr%29)
und
Bascom und USI-Kommunikation (https://www.roboternetz.de/wissen/index.php/Bascom_und_USI-Kommunikation)

Hier noch mein Testprogramm auf den Tiny's:

' USI-I2C Testprogramm
' mit DS1621 @ &H90
' mit PCF8574 @&H40
'
' ohne Interrupt und ohne Timer
' Temperatur von DS1621 lesen, und an PCF ausgeben
' dient nur zum testen, mit den eingebauten Bascom Befehlen

'$regfile = "attiny2313.dat"
'$crystal = 16000000

$regfile = "attiny45.dat"
$crystal = 8000000
'$baud = 9600

$lib "i2c_usi.lbx" ' I2C benutzt USI-Modul

Waitms 500

' Falls T2313 die 1. Version
'Config Scl = Portb.7 ' Ports fuer IIC-Bus
'Config Sda = Portb.5

' diese für Tiny45 und Co.
Config Scl = Portb.2 ' Ports fuer IIC-Bus
Config Sda = Portb.0

'Config I2cdelay = 10 ' je höher der Wert umso langsamer der Bus
' 10 ergibt ca. 100kHz (sollte zumindest)

I2cinit

' Debug LED
Led Alias Portb.1
Config Led = Output

Led = 0

Const Ds1621w = &H90
Const Ds1621r = &H91
Dim Lowtemp As Byte
Dim Hightemp As Byte
Dim Tempvar1 As Byte
Dim Tempvar2 As Byte

Const Pcf8574w = &H40

' Hauptprogramm
Do
' Temperatur lesen
Gosub Ds1621temp

' Wert an PCF senden, erst umrechnen für die LEDs
Tempvar1 = Not Lowtemp
Tempvar2 = Not Hightemp
Tempvar1 = Tempvar1 And Tempvar2
I2cstart
I2cwbyte Pcf8574w
I2cwbyte Tempvar1
I2cstop

Waitms 50

' Debug, solange es Blinkt ist's gut
Toggle Led
Loop

End

Ds1621temp:
' Messen anstossen
'I2csend Ds1621w , &HEE
I2cstart
I2cwbyte Ds1621w
I2cwbyte &HEE
I2cstop

' If Err = 1 Then Print "I2C-Err ! 1 "

' der DS1621 braucht mind. 400ms zum Temperatur umwandeln !
Waitms 500
' Wert auslesen
I2cstart
I2cwbyte Ds1621w
I2cwbyte &HAA
I2cstart
I2cwbyte Ds1621r
I2crbyte Lowtemp , Ack
I2crbyte Hightemp , Nack
I2cstop

If Err = 0 Then
' Negativer Wert ?
If Lowtemp.7 = 1 Then
Lowtemp = Not Lowtemp
If &H80 > Hightemp Then
Incr Lowtemp
End If
' Print "-" ;
Else
' Print " " ;
End If

' Print Lowtemp ; "," ;

If Hightemp = &H80 Then
' Print "5"
Else
' Print "0"
End If
Else
' Print "I2C-Err ! "
End If

Return

Sicherheitshalber schreib ich's nochmal her, diese Lib ist nur für den Masterbetrieb geeignet !

Multimaster hab ich noch nicht erprobt, im Moment wird nur überprüft, ob die Startsequenz abgesetzt werden konnte. Evtl. könnte man davor noch abfragen ob wirklich beide Leitungen high sind.

linux_80
14.01.2007, 21:29
Hier gleich ein Update,
hier hab ich versucht, minimale Multimasterfähigkeit einzubauen,
beim Versuch ein Start abzusetzen wird vorher überprüft, ob nicht schon jemand anders ein Start auf den Bus losgelassen hat,
und ob beide Leitungen auch high sind.

Vom Erfolg des Start-absetzens kann nach dem I2cstart mit der Variablen Err abgefragt werden, also wenn Err = 0, dann kann man weitermachen, ansonsten evtl. nochmal probieren.

Das könnte in etwa so aussehen:

I2cstart
If Err = 0 Then
I2cwbyte Ds1621w
I2cwbyte &HEE
I2cstop
End If


Das ist jetzt aber noch nicht erprobt, dH. als Single-Master funktioniert es, nur ob es auch als Multimaster tut :-k