Che Guevara
12.09.2011, 19:34
Hallo,
da bei meinem derzeitigen Projekt die I2C Verbindung nicht klappt, habe ich an ein paar Stellen im Code die Variablen ausgeben lassen und bin zu der Feststellung gekommen, dass TWI_BTR nie kleiner 2 wird. Ich verstehe allerdings nicht ganz warum? IMHO sollte es doch 1 sein, wenn der Master nur noch 1 Byte vom Slave haben will?! Evtl. könnte jemand ja mal drüber sehen :)
Hier der Code für den Master:
$regfile = "m328pdef.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Declare Sub Init_system()
Declare Function Tastatur() As Byte
Declare Sub Walze_drehen()
Declare Function Codieren(byval Codieren_in As Byte) As Byte
Declare Function Reflektor(byval Reflektor_in As Byte) As Byte
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Pwm0a = 0 'rot
Pwm0b = 0 'grün
$lib "i2c_twi.lbx"
Config Scl = Portc.5
Config Sda = Portc.4
I2cinit
Config Twi = 400000
Const Slave_write = &H70
Const Slave_read = &H71
Const Gen_call = &H00
Dim Ar_out(4) As Byte
Dim Walze_1(26) As Byte
Dim Walze_1_inv(26) As Byte
Dim Pointer_1 As Byte
Dim Ar_out_old(4) As Byte
Dim Fehler As Word
Dim Durchlauefe As Word
Dim Korrekt As Word
Dim Tmp As Byte
Dim I As Byte
Dim A As Byte
Dim _out As Byte 'ascii-wert (skaliert auf 1-26)
Dim _in As Byte 'ascii-wert (skaliert auf 1-26)
Const _a = 1
Const _b = 2
Const _c = 3
Const _d = 4
Const _e = 5
Const _f = 6
Const _g = 7
Const _h = 8
Const _i = 9
Const _j = 10
Const _k = 11
Const _l = 12
Const _m = 13
Const _n = 14
Const _o = 15
Const _p = 16
Const _q = 17
Const _r = 18
Const _s = 19
Const _t = 20
Const _u = 21
Const _v = 22
Const _w = 23
Const _x = 24
Const _y = 25
Const _z = 26
Call Init_system()
For I = 1 To 5
Pwm0a = 250
Pwm0b = 0
Waitms 100
Pwm0a = 0
Pwm0b = 250
Waitms 100
Next I
Pwm0a = 0
Pwm0b = 0
Waitms 200
Do
Call Init_system()
For A = 1 To 4
Ar_out(a) = _a 'Tastatur()
Ar_out_old(a) = Ar_out(a)
'Ar_out(a) = Codieren(ar_out(a))
Next A
I2csend Slave_write , Ar_out(1) , 4
Waitms 100
I2creceive Slave_read , Ar_out(1) , 4 , 4
If Ar_out(1) = Ar_out_old(1) And Ar_out(2) = Ar_out_old(2) And Ar_out(3) = Ar_out_old(3) And Ar_out(4) = Ar_out_old(4) Then
Pwm0a = 0
Pwm0b = 250
Else
Pwm0a = 250
Pwm0b = 0
End If
Wait 1
Loop
Sub Walze_drehen()
Local Tmp2 As Byte
Tmp2 = Walze_1(1)
For Pointer_1 = 1 To 26
Tmp = Pointer_1 + 1
If Tmp = 27 Then Tmp = 1
Walze_1(pointer_1) = Walze_1(tmp)
If Pointer_1 = 26 Then
Walze_1(26) = Tmp2
End If
Walze_1_inv(walze_1(pointer_1)) = Pointer_1
Next Pointer_1
End Sub
Function Tastatur() As Byte
Tastatur = Rnd(25) + 1
End Function
Function Codieren(byval Codieren_in As Byte) As Byte
Tmp = Walze_1(codieren_in)
Tmp = Reflektor(tmp)
Codieren = Walze_1_inv(tmp)
Call Walze_drehen()
End Function
Function Reflektor(byval Reflektor_in As Byte) As Byte
If Reflektor_in.0 = 0 Then
Reflektor = Reflektor_in + 1
If Reflektor = 27 Then Reflektor = 1
Else
Reflektor = Reflektor_in - 1
If Reflektor = 0 Then Reflektor = 26
End If
End Function
Sub Init_system()
Walze_1(1) = 23
Walze_1(2) = 15
Walze_1(3) = 9
Walze_1(4) = 24
Walze_1(5) = 7
Walze_1(6) = 1
Walze_1(7) = 22
Walze_1(8) = 17
Walze_1(9) = 12
Walze_1(10) = 13
Walze_1(11) = 26
Walze_1(12) = 2
Walze_1(13) = 5
Walze_1(14) = 21
Walze_1(15) = 14
Walze_1(16) = 25
Walze_1(17) = 11
Walze_1(18) = 6
Walze_1(19) = 16
Walze_1(20) = 8
Walze_1(21) = 3
Walze_1(22) = 18
Walze_1(23) = 4
Walze_1(24) = 19
Walze_1(25) = 10
Walze_1(26) = 20
Walze_1_inv(23) = 1
Walze_1_inv(15) = 2
Walze_1_inv(9) = 3
Walze_1_inv(24) = 4
Walze_1_inv(7) = 5
Walze_1_inv(1) = 6
Walze_1_inv(22) = 7
Walze_1_inv(17) = 8
Walze_1_inv(12) = 9
Walze_1_inv(13) = 10
Walze_1_inv(26) = 11
Walze_1_inv(2) = 12
Walze_1_inv(5) = 13
Walze_1_inv(21) = 14
Walze_1_inv(14) = 15
Walze_1_inv(25) = 16
Walze_1_inv(11) = 17
Walze_1_inv(6) = 18
Walze_1_inv(16) = 19
Walze_1_inv(8) = 20
Walze_1_inv(3) = 21
Walze_1_inv(18) = 22
Walze_1_inv(4) = 23
Walze_1_inv(19) = 24
Walze_1_inv(10) = 25
Walze_1_inv(20) = 26
End Sub
End
Und der Slave:
$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Declare Sub Init_system()
Declare Function Tastatur() As Byte
Declare Sub Walze_drehen()
Declare Function Codieren(byval Codieren_in As Byte) As Byte
Declare Function Reflektor(byval Reflektor_in As Byte) As Byte
$lib "i2c_twi-slave.lbx"
Config Twislave = &H70 , Btr = 4 , Bitrate = 400000 , Save = Save , Gencall = 1
Config Sda = Portc.1
Config Scl = Portc.0
I2cinit
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Lcdbus = 4
Initlcd
Cls
Cursor Off Noblink
Deflcdchar 0 , 32 , 32 , 1 , 18 , 20 , 24 , 16 , 32
Dim Walze_1(26) As Byte
Dim Walze_1_inv(26) As Byte
Dim Pointer_1 As Byte
Dim Ar_out(4) As Byte
Dim Ar_out_old(4) As Byte
Dim Fehler As Word
Dim Durchlauefe As Word
Dim Korrekt As Word
Dim Dechiffriert(4) As Byte
Dim Tmp As Byte
Dim I As Byte
Dim _out As Byte 'ascii-wert (skaliert auf 1-26)
Dim _in As Byte 'ascii-wert (skaliert auf 1-26)
Const _a = 1
Const _b = 2
Const _c = 3
Const _d = 4
Const _e = 5
Const _f = 6
Const _g = 7
Const _h = 8
Const _i = 9
Const _j = 10
Const _k = 11
Const _l = 12
Const _m = 13
Const _n = 14
Const _o = 15
Const _p = 16
Const _q = 17
Const _r = 18
Const _s = 19
Const _t = 20
Const _u = 21
Const _v = 22
Const _w = 23
Const _x = 24
Const _y = 25
Const _z = 26
Call Init_system()
Dim X As Byte
Waitms 200
Enable Interrupts
Do
!nop
Loop
Sub Walze_drehen()
Local Tmp2 As Byte
Tmp2 = Walze_1(1)
For Pointer_1 = 1 To 26
Tmp = Pointer_1 + 1
If Tmp = 27 Then Tmp = 1
Walze_1(pointer_1) = Walze_1(tmp)
If Pointer_1 = 26 Then
Walze_1(26) = Tmp2
End If
Walze_1_inv(walze_1(pointer_1)) = Pointer_1
Next Pointer_1
End Sub
Function Tastatur() As Byte
Tastatur = Rnd(25) + 1
End Function
Function Codieren(byval Codieren_in As Byte) As Byte
Tmp = Walze_1(codieren_in)
Tmp = Reflektor(tmp)
Codieren = Walze_1_inv(tmp)
Call Walze_drehen()
End Function
Function Reflektor(byval Reflektor_in As Byte) As Byte
If Reflektor_in.0 = 0 Then
Reflektor = Reflektor_in + 1
If Reflektor = 27 Then Reflektor = 1
Else
Reflektor = Reflektor_in - 1
If Reflektor = 0 Then Reflektor = 26
End If
End Function
Sub Init_system()
Walze_1(1) = 23
Walze_1(2) = 15
Walze_1(3) = 9
Walze_1(4) = 24
Walze_1(5) = 7
Walze_1(6) = 1
Walze_1(7) = 22
Walze_1(8) = 17
Walze_1(9) = 12
Walze_1(10) = 13
Walze_1(11) = 26
Walze_1(12) = 2
Walze_1(13) = 5
Walze_1(14) = 21
Walze_1(15) = 14
Walze_1(16) = 25
Walze_1(17) = 11
Walze_1(18) = 6
Walze_1(19) = 16
Walze_1(20) = 8
Walze_1(21) = 3
Walze_1(22) = 18
Walze_1(23) = 4
Walze_1(24) = 19
Walze_1(25) = 10
Walze_1(26) = 20
Walze_1_inv(23) = 1
Walze_1_inv(15) = 2
Walze_1_inv(9) = 3
Walze_1_inv(24) = 4
Walze_1_inv(7) = 5
Walze_1_inv(1) = 6
Walze_1_inv(22) = 7
Walze_1_inv(17) = 8
Walze_1_inv(12) = 9
Walze_1_inv(13) = 10
Walze_1_inv(26) = 11
Walze_1_inv(2) = 12
Walze_1_inv(5) = 13
Walze_1_inv(21) = 14
Walze_1_inv(14) = 15
Walze_1_inv(25) = 16
Walze_1_inv(11) = 17
Walze_1_inv(6) = 18
Walze_1_inv(16) = 19
Walze_1_inv(8) = 20
Walze_1_inv(3) = 21
Walze_1_inv(18) = 22
Walze_1_inv(4) = 23
Walze_1_inv(19) = 24
Walze_1_inv(10) = 25
Walze_1_inv(20) = 26
End Sub
Twi_write_addressed:
Return
'***************************
Twi_gotdata:
Ar_out(twi_btw) = Twi
If Twi_btw = 1 Then Call Init_system()
'Locate 1 , 1
'Lcd Ar_out(1) ; ":" ; Ar_out(2) ; ":" ; Ar_out(3) ; ":" ; Ar_out(4) ; " "
Dechiffriert(twi_btw) = Codieren(ar_out(twi_btw))
Return
'***************************
Twi_stop_rstart_received:
Return
'***************************
Twi_read_addressed:
Return
'***************************
Twi_master_needs_more_byte:
Twi = Dechiffriert(twi_btr)
Locate 1 , Twi_btr
Lcd Twi_btr
If Twi_btr = 1 Then
Locate 2 , 1
Lcd "a"
Else
Locate 2 , 1
Lcd " "
End If
Return
'***************************
Twi_master_need_nomore_byte:
Return
'***************************
Twi_slave_error:
Return
End
Vielen Dank & Gruß
Chris
EDIT:
Habe den Fehler gefunden; Wenn der Master den Slave das erste mal über die Read-Addresse anspricht, wird das erste Byte direkt in der Twi_read_addressed verlangt und somit ist zu diesem Zeitpunkt Twi_btr = 1 .
da bei meinem derzeitigen Projekt die I2C Verbindung nicht klappt, habe ich an ein paar Stellen im Code die Variablen ausgeben lassen und bin zu der Feststellung gekommen, dass TWI_BTR nie kleiner 2 wird. Ich verstehe allerdings nicht ganz warum? IMHO sollte es doch 1 sein, wenn der Master nur noch 1 Byte vom Slave haben will?! Evtl. könnte jemand ja mal drüber sehen :)
Hier der Code für den Master:
$regfile = "m328pdef.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Declare Sub Init_system()
Declare Function Tastatur() As Byte
Declare Sub Walze_drehen()
Declare Function Codieren(byval Codieren_in As Byte) As Byte
Declare Function Reflektor(byval Reflektor_in As Byte) As Byte
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Pwm0a = 0 'rot
Pwm0b = 0 'grün
$lib "i2c_twi.lbx"
Config Scl = Portc.5
Config Sda = Portc.4
I2cinit
Config Twi = 400000
Const Slave_write = &H70
Const Slave_read = &H71
Const Gen_call = &H00
Dim Ar_out(4) As Byte
Dim Walze_1(26) As Byte
Dim Walze_1_inv(26) As Byte
Dim Pointer_1 As Byte
Dim Ar_out_old(4) As Byte
Dim Fehler As Word
Dim Durchlauefe As Word
Dim Korrekt As Word
Dim Tmp As Byte
Dim I As Byte
Dim A As Byte
Dim _out As Byte 'ascii-wert (skaliert auf 1-26)
Dim _in As Byte 'ascii-wert (skaliert auf 1-26)
Const _a = 1
Const _b = 2
Const _c = 3
Const _d = 4
Const _e = 5
Const _f = 6
Const _g = 7
Const _h = 8
Const _i = 9
Const _j = 10
Const _k = 11
Const _l = 12
Const _m = 13
Const _n = 14
Const _o = 15
Const _p = 16
Const _q = 17
Const _r = 18
Const _s = 19
Const _t = 20
Const _u = 21
Const _v = 22
Const _w = 23
Const _x = 24
Const _y = 25
Const _z = 26
Call Init_system()
For I = 1 To 5
Pwm0a = 250
Pwm0b = 0
Waitms 100
Pwm0a = 0
Pwm0b = 250
Waitms 100
Next I
Pwm0a = 0
Pwm0b = 0
Waitms 200
Do
Call Init_system()
For A = 1 To 4
Ar_out(a) = _a 'Tastatur()
Ar_out_old(a) = Ar_out(a)
'Ar_out(a) = Codieren(ar_out(a))
Next A
I2csend Slave_write , Ar_out(1) , 4
Waitms 100
I2creceive Slave_read , Ar_out(1) , 4 , 4
If Ar_out(1) = Ar_out_old(1) And Ar_out(2) = Ar_out_old(2) And Ar_out(3) = Ar_out_old(3) And Ar_out(4) = Ar_out_old(4) Then
Pwm0a = 0
Pwm0b = 250
Else
Pwm0a = 250
Pwm0b = 0
End If
Wait 1
Loop
Sub Walze_drehen()
Local Tmp2 As Byte
Tmp2 = Walze_1(1)
For Pointer_1 = 1 To 26
Tmp = Pointer_1 + 1
If Tmp = 27 Then Tmp = 1
Walze_1(pointer_1) = Walze_1(tmp)
If Pointer_1 = 26 Then
Walze_1(26) = Tmp2
End If
Walze_1_inv(walze_1(pointer_1)) = Pointer_1
Next Pointer_1
End Sub
Function Tastatur() As Byte
Tastatur = Rnd(25) + 1
End Function
Function Codieren(byval Codieren_in As Byte) As Byte
Tmp = Walze_1(codieren_in)
Tmp = Reflektor(tmp)
Codieren = Walze_1_inv(tmp)
Call Walze_drehen()
End Function
Function Reflektor(byval Reflektor_in As Byte) As Byte
If Reflektor_in.0 = 0 Then
Reflektor = Reflektor_in + 1
If Reflektor = 27 Then Reflektor = 1
Else
Reflektor = Reflektor_in - 1
If Reflektor = 0 Then Reflektor = 26
End If
End Function
Sub Init_system()
Walze_1(1) = 23
Walze_1(2) = 15
Walze_1(3) = 9
Walze_1(4) = 24
Walze_1(5) = 7
Walze_1(6) = 1
Walze_1(7) = 22
Walze_1(8) = 17
Walze_1(9) = 12
Walze_1(10) = 13
Walze_1(11) = 26
Walze_1(12) = 2
Walze_1(13) = 5
Walze_1(14) = 21
Walze_1(15) = 14
Walze_1(16) = 25
Walze_1(17) = 11
Walze_1(18) = 6
Walze_1(19) = 16
Walze_1(20) = 8
Walze_1(21) = 3
Walze_1(22) = 18
Walze_1(23) = 4
Walze_1(24) = 19
Walze_1(25) = 10
Walze_1(26) = 20
Walze_1_inv(23) = 1
Walze_1_inv(15) = 2
Walze_1_inv(9) = 3
Walze_1_inv(24) = 4
Walze_1_inv(7) = 5
Walze_1_inv(1) = 6
Walze_1_inv(22) = 7
Walze_1_inv(17) = 8
Walze_1_inv(12) = 9
Walze_1_inv(13) = 10
Walze_1_inv(26) = 11
Walze_1_inv(2) = 12
Walze_1_inv(5) = 13
Walze_1_inv(21) = 14
Walze_1_inv(14) = 15
Walze_1_inv(25) = 16
Walze_1_inv(11) = 17
Walze_1_inv(6) = 18
Walze_1_inv(16) = 19
Walze_1_inv(8) = 20
Walze_1_inv(3) = 21
Walze_1_inv(18) = 22
Walze_1_inv(4) = 23
Walze_1_inv(19) = 24
Walze_1_inv(10) = 25
Walze_1_inv(20) = 26
End Sub
End
Und der Slave:
$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Declare Sub Init_system()
Declare Function Tastatur() As Byte
Declare Sub Walze_drehen()
Declare Function Codieren(byval Codieren_in As Byte) As Byte
Declare Function Reflektor(byval Reflektor_in As Byte) As Byte
$lib "i2c_twi-slave.lbx"
Config Twislave = &H70 , Btr = 4 , Bitrate = 400000 , Save = Save , Gencall = 1
Config Sda = Portc.1
Config Scl = Portc.0
I2cinit
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Config Lcdbus = 4
Initlcd
Cls
Cursor Off Noblink
Deflcdchar 0 , 32 , 32 , 1 , 18 , 20 , 24 , 16 , 32
Dim Walze_1(26) As Byte
Dim Walze_1_inv(26) As Byte
Dim Pointer_1 As Byte
Dim Ar_out(4) As Byte
Dim Ar_out_old(4) As Byte
Dim Fehler As Word
Dim Durchlauefe As Word
Dim Korrekt As Word
Dim Dechiffriert(4) As Byte
Dim Tmp As Byte
Dim I As Byte
Dim _out As Byte 'ascii-wert (skaliert auf 1-26)
Dim _in As Byte 'ascii-wert (skaliert auf 1-26)
Const _a = 1
Const _b = 2
Const _c = 3
Const _d = 4
Const _e = 5
Const _f = 6
Const _g = 7
Const _h = 8
Const _i = 9
Const _j = 10
Const _k = 11
Const _l = 12
Const _m = 13
Const _n = 14
Const _o = 15
Const _p = 16
Const _q = 17
Const _r = 18
Const _s = 19
Const _t = 20
Const _u = 21
Const _v = 22
Const _w = 23
Const _x = 24
Const _y = 25
Const _z = 26
Call Init_system()
Dim X As Byte
Waitms 200
Enable Interrupts
Do
!nop
Loop
Sub Walze_drehen()
Local Tmp2 As Byte
Tmp2 = Walze_1(1)
For Pointer_1 = 1 To 26
Tmp = Pointer_1 + 1
If Tmp = 27 Then Tmp = 1
Walze_1(pointer_1) = Walze_1(tmp)
If Pointer_1 = 26 Then
Walze_1(26) = Tmp2
End If
Walze_1_inv(walze_1(pointer_1)) = Pointer_1
Next Pointer_1
End Sub
Function Tastatur() As Byte
Tastatur = Rnd(25) + 1
End Function
Function Codieren(byval Codieren_in As Byte) As Byte
Tmp = Walze_1(codieren_in)
Tmp = Reflektor(tmp)
Codieren = Walze_1_inv(tmp)
Call Walze_drehen()
End Function
Function Reflektor(byval Reflektor_in As Byte) As Byte
If Reflektor_in.0 = 0 Then
Reflektor = Reflektor_in + 1
If Reflektor = 27 Then Reflektor = 1
Else
Reflektor = Reflektor_in - 1
If Reflektor = 0 Then Reflektor = 26
End If
End Function
Sub Init_system()
Walze_1(1) = 23
Walze_1(2) = 15
Walze_1(3) = 9
Walze_1(4) = 24
Walze_1(5) = 7
Walze_1(6) = 1
Walze_1(7) = 22
Walze_1(8) = 17
Walze_1(9) = 12
Walze_1(10) = 13
Walze_1(11) = 26
Walze_1(12) = 2
Walze_1(13) = 5
Walze_1(14) = 21
Walze_1(15) = 14
Walze_1(16) = 25
Walze_1(17) = 11
Walze_1(18) = 6
Walze_1(19) = 16
Walze_1(20) = 8
Walze_1(21) = 3
Walze_1(22) = 18
Walze_1(23) = 4
Walze_1(24) = 19
Walze_1(25) = 10
Walze_1(26) = 20
Walze_1_inv(23) = 1
Walze_1_inv(15) = 2
Walze_1_inv(9) = 3
Walze_1_inv(24) = 4
Walze_1_inv(7) = 5
Walze_1_inv(1) = 6
Walze_1_inv(22) = 7
Walze_1_inv(17) = 8
Walze_1_inv(12) = 9
Walze_1_inv(13) = 10
Walze_1_inv(26) = 11
Walze_1_inv(2) = 12
Walze_1_inv(5) = 13
Walze_1_inv(21) = 14
Walze_1_inv(14) = 15
Walze_1_inv(25) = 16
Walze_1_inv(11) = 17
Walze_1_inv(6) = 18
Walze_1_inv(16) = 19
Walze_1_inv(8) = 20
Walze_1_inv(3) = 21
Walze_1_inv(18) = 22
Walze_1_inv(4) = 23
Walze_1_inv(19) = 24
Walze_1_inv(10) = 25
Walze_1_inv(20) = 26
End Sub
Twi_write_addressed:
Return
'***************************
Twi_gotdata:
Ar_out(twi_btw) = Twi
If Twi_btw = 1 Then Call Init_system()
'Locate 1 , 1
'Lcd Ar_out(1) ; ":" ; Ar_out(2) ; ":" ; Ar_out(3) ; ":" ; Ar_out(4) ; " "
Dechiffriert(twi_btw) = Codieren(ar_out(twi_btw))
Return
'***************************
Twi_stop_rstart_received:
Return
'***************************
Twi_read_addressed:
Return
'***************************
Twi_master_needs_more_byte:
Twi = Dechiffriert(twi_btr)
Locate 1 , Twi_btr
Lcd Twi_btr
If Twi_btr = 1 Then
Locate 2 , 1
Lcd "a"
Else
Locate 2 , 1
Lcd " "
End If
Return
'***************************
Twi_master_need_nomore_byte:
Return
'***************************
Twi_slave_error:
Return
End
Vielen Dank & Gruß
Chris
EDIT:
Habe den Fehler gefunden; Wenn der Master den Slave das erste mal über die Read-Addresse anspricht, wird das erste Byte direkt in der Twi_read_addressed verlangt und somit ist zu diesem Zeitpunkt Twi_btr = 1 .