Gut, dann ist aber eins klar: beim Master kann dann der Fehler mal nicht liegen.
Wirst du Code der Slaves rausrücken müssen.
Druckbare Version
Gut, dann ist aber eins klar: beim Master kann dann der Fehler mal nicht liegen.
Wirst du Code der Slaves rausrücken müssen.
Die Slaves laufen einfach die Slave Receiver Routine aus dem TWI Praxis durch.
Ich hab die ein Beispiel hergerichtet, das für die Slaves prinzipiell passen sollte.
("PRINT" mußt du natürlich nicht machen)
deine Sachen müsstest du natürlich einfügen, Timer usw, das mit den Tasten etc.
MySlave.bas ist sozusagen das Slave-Hauptprogramm
mytwi.bas wird includiert, brauchst (sollst) du nix ändern
mytwi.lib muss in das Bascom-Directory, wo die ganzen Lib's stehen
bei mir ist das z.B. "C:\Program Files\MCS Electronics\BASCOM-AVR\LIB"
Die Master Sachen würde ich mit normalen I2c funktionen machen, damit kennst du dich ja aus
Hi,
ich werde mir deinen Code ma anschauen und hoffen das ich alles verstehe ^^....
Ein sehr großes Danke für deine Mühe
Hier ist mal mein Code vom Master und den Slaves.
Er gibt mir nun diesen fehler aus
Unknown interrupt [TWSI]
Code: On Twsi Twi_mst_slv_isr , Nosave
weiß keiner warum ich so einen fehler bekomme????
Versuch mal:
Code: On Twi Twi_mst_slv_isr , Nosave
(TWI statt TWSI)
Ich fürchte, da sind sich die Bascom-Versionen nicht ganz einig
Morgen,
danke für die Hilfe. Das mit dem TWI anstatt des TWSI hat geklappt und die Slaves önnen nun alle senden.
Aber ein Problem habe ich noch:
Ich möchte gerne alle Slaves nacheinander Fragen ob sie Daten haben und die dann auch empfangen, weil die Slaves sonst ja in der Sende Routine bleiben.
Ich wollte hierzu die Error Variable von der TWI_read_byte Funktion aus dm Wiki nehmen nur die Scheint immer null zu sein auch wenn der Slave eigentlich schon alle Bytes gesendet hat....
Hier mal der Code.....
Ich habe auch schon versucht die zu empfangenen Bytes abzufragen ob das die richtigen sind dies funktioniert aber leider auch nicht....Code:'-------------------------------------------------------------------------------
Projekt: Midi Looper inter
'-------------------------------------------------------------------------------
'-----------------------------Registrierung-------------------------------------
$regfile = "m32def.dat" 'Konfiguration auf ATmega 32
$lib "i2c_twi.lbx"
$crystal = 16000000 'Quarztakt 16MHz
$baud = 9600
Config Twi = 400000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 32 ' default use 10 for the SW stack
$framesize = 32
$eeprom
I2cinit
Declare Function Twi_read_byte(byval Slave As Byte) As Byte ' default use 40 for the frame space
'-----------------------------Configuration-------------------------------------
Config Porta = Output
Config Portb = Output
Config Portc = Input
'-----------------------------Dimensionierung-----------------------------------
Dim Uart As Byte
Dim Var(90) As Byte
Dim Vare(90) As Eram Byte
Dim Ausvar1(90) As Byte
Dim Ausvar2(90) As Byte
Dim Ausvar3(90) As Byte
Dim Ausvar4(90) As Byte
Dim Ausvar5(90) As Byte
Dim Ausvar6(90) As Byte
Dim Ausvar7(90) As Byte
Dim Ausvar8(90) As Byte
Dim Ausvar9(90) As Byte
Dim Ausvar10(90) As Byte
Dim Ausvare1(90) As Eram Byte
Dim Ausvare2(90) As Eram Byte
Dim Ausvare3(90) As Eram Byte
Dim Ausvare4(90) As Eram Byte
Dim Ausvare5(90) As Eram Byte
Dim Ausvare6(90) As Eram Byte
Dim Ausvare7(90) As Eram Byte
Dim Ausvare8(90) As Eram Byte
Dim Ausvare9(90) As Eram Byte
Dim Ausvare10(90) As Eram Byte
Dim Slave(6) As Byte
Dim Slavestat(6) As Byte
Dim Ebene As Byte
Dim Ebenee As Eram Byte
Dim Flanke1 As Bit
Dim Impuls1 As Bit
Dim Impuls2 As Bit
Dim Impuls3 As Bit
Dim Progmodus As Bit
Dim Z As Byte
Dim X As Byte
Dim Fusssch As Integer
Dim W As Integer
Dim Gleich As Bit
Dim Gleichuart As Bit
Dim Maxi As Byte
Dim Ausprog As Bit
Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data As Byte
Dim Error As Byte
Dim Sendbyte As Byte
Dim Loeschen As Bit
Dim Reseten As Bit
Dim Startwert As Byte
Dim Altuart As Byte
Dim Emfaengt As Byte
Dim Fussschsp As Byte
Led1 Alias Portb.0
Led2 Alias Porta.0
Led3 Alias Porta.1
Tast1 Alias Pinc.3
Tast2 Alias Pinc.5
Tast3 Alias Pinc.4
'-----------------------------Vorkonfiguration----------------------------------
Impuls1 = 0
Impuls2 = 0
Impuls3 = 0
Flanke1 = 0
Progmodus = 0
Fusssch = 0
X = 0
W = 0
Led1 = 1
Led2 = 1
Led3 = 1
Gleich = 0
Maxi = 6
Ausprog = 0
Loeschen = 0
Altuart = 0
Ebene = Ebenee
Emfaengt = &H00
Slave(1) = &H40
Slave(2) = &H50
Slave(3) = &H60
Slave(4) = &H70
Slave(5) = &H80
Slave(6) = &H90
Slavestat(1) = 0
Slavestat(2) = 0
Slavestat(3) = 0
Slavestat(4) = 0
Slavestat(5) = 0
Slavestat(6) = 0
For Fusssch = 1 To Maxi Step 1
Var(fusssch) = Vare(fusssch)
Ausvar1(fusssch) = Ausvare1(fusssch)
Ausvar2(fusssch) = Ausvare2(fusssch)
Ausvar3(fusssch) = Ausvare3(fusssch)
Ausvar4(fusssch) = Ausvare4(fusssch)
Ausvar5(fusssch) = Ausvare5(fusssch)
Ausvar6(fusssch) = Ausvare6(fusssch)
Ausvar7(fusssch) = Ausvare7(fusssch)
Ausvar8(fusssch) = Ausvare8(fusssch)
Ausvar9(fusssch) = Ausvare9(fusssch)
Ausvar10(fusssch) = Ausvare10(fusssch)
Next
Led1 = 0
Led2 = 0
Led3 = 0
Waitms 500
Led1 = 1
Led2 = 1
Led3 = 1
Waitms 1000
Ebene = 1
Emfaengt = Twi_read_byte(slave(1))
If Emfaengt = Slave(1) Then Slavestat(1) = 1
Emfaengt = Twi_read_byte(slave(2))
If Emfaengt = Slave(2) Then Slavestat(2) = 1
Emfaengt = Twi_read_byte(slave(3))
If Emfaengt = Slave(3) Then Slavestat(3) = 1
Emfaengt = Twi_read_byte(slave(4))
If Emfaengt = Slave(4) Then Slavestat(4) = 1
Emfaengt = Twi_read_byte(slave(5))
If Emfaengt = Slave(5) Then Slavestat(5) = 1
Emfaengt = Twi_read_byte(slave(6))
If Emfaengt = Slave(6) Then Slavestat(6) = 1
If Slavestat(1) = 1 Then
Led1 = 0
Waitms 200
Led1 = 1
Waitms 1000
End If
If Slavestat(2) = 1 Then
For Z = 1 To 2 Step 1
Led1 = 0
Waitms 200
Led1 = 1
Waitms 200
Next
Waitms 1000
End If
If Slavestat(3) = 1 Then
For Z = 1 To 3 Step 1
Led1 = 0
Waitms 200
Led1 = 1
Waitms 200
Next
Waitms 1000
End If
If Slavestat(4) = 1 Then
For Z = 1 To 4 Step 1
Led1 = 0
Waitms 200
Led1 = 1
Waitms 200
Next
Waitms 1000
End If
If Slavestat(5) = 1 Then
For Z = 1 To 5 Step 1
Led1 = 0
Waitms 200
Led1 = 1
Waitms 200
Next
Waitms 1000
End If
If Slavestat(6) = 1 Then
For Z = 1 To 6 Step 1
Led1 = 0
Waitms 200
Led1 = 1
Waitms 200
Next
Waitms 1000
End If
'----------------------------Hauptprogramm--------------------------------------
Do
If Tast1 = 1 And Flanke1 = 0 And Impuls1 = 0 Then
Led1 = 0
Progmodus = 1
Flanke1 = 1
Impuls1 = 1
Waitms 200
End If
If Tast1 = 1 And Flanke1 = 1 And Impuls1 = 0 Then
Led1 = 1
Progmodus = 0
Flanke1 = 0
Impuls1 = 1
Waitms 200
End If
If Tast1 = 0 Then Impuls1 = 0
If Ebene = 1 Then
Startwert = 1
Maxi = 2
Led2 = 0
Led3 = 1
End If
If Ebene = 2 Then
Startwert = 3
Maxi = 4
Led2 = 1
Led3 = 0
End If
If Ebene = 3 Then
Startwert = 5
Maxi = 6
Led2 = 0
Led3 = 0
End If
If Progmodus = 1 Then
Led1 = 0
X = 0
Loeschen = 0
Do
Loop Until Tast2 = 1 Or Tast3 = 1
If Tast2 = 1 Then Uart = &H11
If Tast3 = 1 Then Uart = &H12
If Tast1 = 0 Then
For Fusssch = Startwert To Maxi Step 1
If Uart = Var(fusssch) Then
Gleich = 1
Fussschsp = Fusssch
Fusssch = Maxi
Led1 = 1
Waitms 100
Led1 = 0
Waitms 100
Led1 = 1
Waitms 100
Led1 = 0
Ausprog = 1
For W = 1 To 6 Step 1
If Slavestat(w) = 1 Then
I2cstart
I2cwbyte Slave(w)
I2cwbyte &H09
I2cstop
Waitms 1
End If
Next
Else
Gleich = 0
End If
Next
If Gleich = 0 Then
X = Startwert - 1
For Fusssch = Startwert To Maxi Step 1
If Var(fusssch) = 0 Then
Var(fusssch) = Uart
Vare(fusssch) = Var(fusssch)
Fussschsp = Fusssch
Fusssch = Maxi
Gosub Blinken
Ausprog = 1
For W = 1 To 6 Step 1
If Slavestat(w) = 1 Then
I2cstart
I2cwbyte Slave(w)
I2cwbyte &H09
I2cstop
Waitms 1
End If
Next
Else
X = X + 1
End If
Next
If X = Maxi Then
For Z = 0 To 5 Step 1
Led1 = 1
Waitms 400
Led1 = 0
Waitms 400
Loeschen = 1
Next
For Fusssch = Startwert To Maxi Step 1
Var(fusssch) = 0
Vare(fusssch) = Var(fusssch)
Next
End If
End If
Do
Led1 = 1
Waitms 50
Led1 = 0
Waitms 50
Loop Until Tast1 = 1 Or Loeschen = 1
If Ausprog = 1 Then
For W = 1 To 6 Step 1
If Slavestat(w) = 1 Then
I2cstart
I2cwbyte Slave(w)
I2cwbyte &H08
I2cstop
Waitms 1
End If
Next
Waitms 200
'------------ab hier fragt er alle Slaves ab---------------------------------------
Fusssch = Fussschsp
Z = 0
For W = 1 To 6 Step 1
If Slavestat(w) = 1 Then
If Z = 0 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar1(fusssch) = Emfaengt
'----------------------------Z soll nur einen hörer gezählt werden wenn error = 0-------------------------------------------------------------
Z = Z + 1
Ausvare1(fusssch) = Ausvar1(fusssch)
Emfaengt = 0
End If
End If
If Z = 1 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar2(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare2(fusssch) = Ausvar2(fusssch)
emfaengt = 0
End If
End If
If Z = 2 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar3(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare3(fusssch) = Ausvar3(fusssch)
emfaengt = 0
End If
End If
If Z = 3 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar4(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare4(fusssch) = Ausvar4(fusssch)
emfaengt = 0
End If
End If
If Z = 4 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar5(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare5(fusssch) = Ausvar5(fusssch)
emfaengt = 0
End If
End If
If Z = 5 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar6(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare6(fusssch) = Ausvar6(fusssch)
emfaengt = 0
End If
End If
If Z = 6 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar7(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare7(fusssch) = Ausvar7(fusssch)
emfaengt = 0
End If
End If
If Z = 7 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar8(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare8(fusssch) = Ausvar8(fusssch)
emfaengt = 0
End If
End If
If Z = 8 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar9(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare9(fusssch) = Ausvar9(fusssch)
emfaengt = 0
End If
End If
If Z = 9 Then
Emfaengt = Twi_read_byte(slave(w))
If Error = 0 Then
Ausvar10(fusssch) = Emfaengt
Z = Z + 1
'Gosub Blinken
Ausvare10(fusssch) = Ausvar10(fusssch)
emfaengt = 0
End If
End If
For X = 1 To 30 Step 1
Emfaengt = Twi_read_byte(slave(w))
Next
End If
Next
'--------------------------in das unterprogramm blinken wird aber 10 mal gesprungen-------------
For W = 0 To Z Step 1
Gosub Blinken
Next
Led1 = 0
Waitms 500
End If
If Loeschen = 0 Then
Led1 = 1
Progmodus = 0
Flanke1 = 0
Ausprog = 0
Impuls1 = 1
End If
End If
End If
If Progmodus = 0 Then
Do
Loop Until Tast2 = 1 Or Tast3 = 1 Or Tast1 = 1
If Tast1 = 0 Then
If Tast2 = 1 Then Uart = &H11
If Tast3 = 1 Then Uart = &H12
For W = 1 To 6 Step 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte &H10
I2cstop
Waitms 1
Next
Waitms 1
If Gleichuart = 1 Then
Altuart = 0
Gleichuart = 0
End If
If Uart <> Altuart Then
For Fusssch = Startwert To Maxi Step 1
If Var(fusssch) = Uart Then
For W = 1 To 6 Step 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar1(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar2(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar3(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar4(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar5(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar6(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar7(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar8(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar9(fusssch)
I2cstop
Waitms 1
I2cstart
I2cwbyte Slave(w)
I2cwbyte Ausvar10(fusssch)
I2cstop
Next
End If
Next
Else
Gleichuart = 1
End If
Altuart = Uart
End If
End If
Loop
End
'Unterprogramme
' TWI read_byte
' holt ein Byte und schliesst die Übertragung ab
Function Twi_read_byte(slave As Byte) As Byte
Error = 0 ' Fehler zurücksetzen
Twi_read_byte = 0 ' Wert vorbelegen
' Startbedingung
Twcr = &B10100100 ' TWINT
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave Or &H01 ' slave adresse + Read
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' Slave hat sich gemeldet
If Twi_status = &H40 Then
Twcr = &B10000100 ' TWINT löschen, Byte senden
' kein ACK (TWEA = 0) senden, weil wir nur ein Byte lesen wollen
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' ein Byte wurde empfangen
If Twi_status = &H58 Or Twi_status = &H50 Then
Twi_read_byte = Twdr ' Daten lesen
Error = 0 ' kein Fehler
Else
Error = Twi_status ' Fehler
End If
Else
' kein slave
Error = Twi_status ' Fehler
End If
' STOPbedingung kommt hier immer im Ablauf, egal welcher Status
Twcr = &B10010100 ' TWINT löschen, STOP senden
' nach einem STOP wird TWINT nicht mehr gesetzt,
' man darf/kann also nicht darauf warten !
Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
Error = Twi_status ' Fehler
End If
End Function
' warten bis TWINT gesetzt ist, status auslesen
Twi_wait_int:
Do
Twi_control = Twcr And &H80
Loop Until Twi_control = &H80
Twi_status = Twsr And &HF8 ' status
' status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !
' Print "Err " ; Hex(twi_status)
Return
Blinken:
Led1 = 1
Waitms 200
Led1 = 0
Waitms 200
Return
Einer eine Idee?
Danke für alles mfg dämmi
Weiss nicht, ob ich dich jetzt richtig verstehe.
Wenn der Master sich vom Slave daten holt, kann der Slave weder ACKen noch NACKen, das kann nur der Master.
Beim Letzten (oder einzigen) gelesenen Byte setzt der Master NACK, dann weiss auch der Slave, dass es nun aus ist mit dem Übertragen.
Hi,
Jetzt weiß ich nicht was du mir damit sagen willst.
Das Problem welches ich in meiner Routine habe ist das Z immer ein höher gezählt wird. Das heißt error muss immer auf 0 sein auch wenn der Slave zb nur 2 Byte sendet.
Wenn Z nun auf 10 ist werden die gesendeten Bytes des 2. Slaves nicht gespeichert.
Die übertragung an sich funktioniert ja.