So habe den I2C Bus mit dem Oszi unter die Lupe genommen. Mit dem bisherigen Code vom Slave wurde das ACK nach dem empfangen der Adresse, nicht an Master gesendet.
Theoretisch sollte der Ablauf des Slaves doch so sein:
-START ISR, Counter auf 0 setzten
-wenn Counteroverflow, dann wurde die Adresse empfangen, nun ACK senden -> SDA auf Output, Counter = 14
wenn ich SDA auf Output setzte, geht SDA auf low, verlasse ich nun die OVF-ISR, geht SDA sofort wieder auf high. Ich kann also nicht einmal ein ACK vom Slave zum Master senden.
Code:$regfile = "attiny85.dat" $crystal = 8000000 Dim Slave_adress As Byte Dim Master_read As Byte Dim I2c_mode As Byte Dim Data_byte As Byte Dim Command As Byte Dim Input_buffer(12) As Byte Dim Count As Byte Slave_adress = &H30 'Slave Adresse Master_read = Slave_adress + 1 Enable Interrupts 'Interrupts einschalten Usicr = &B10101100 'Start enable, I2C mode, ext. clock 'Config Portb.0 = Input 'SDA On Usi_start I2c_start Nosave On Usi_ovf I2c_read_write Nosave Open "comb.4:1200,8,n,1" For Output As #1 Do 'Hauptprogramm 'Printbin #1 , Count 'Printbin #1 , Input_buffer(1) , 12 'Waitms 250 Loop End I2c_start: I2c_mode = 0 Count = 0 Config Portb.0 = Input 'SDA Bitwait Portb.2 , Reset 'Warte bis Start kondition fertig Usicr = &B11111000 'Start enable, Owerflow enable, I2C mode, SCL low, ext. clock 'Usidr = 0 Usisr = &B11110000 'Reset Flags Return I2c_read_write: Select Case I2c_mode Case 0 'Adress Mode Select Case Usidr Case Slave_adress I2c_mode = 11 Usidr = 0 Usisr = 14 Case Master_read I2c_mode = 12 Ddrb.0 = 1 '<--- SDA auf Output setzten Usisr = 14 Case Else Usisr = 0 Usicr = &B10101000 'Start enable, I2C mode, ext. clock End Select Case 1 'Master write Mode If Count = 0 Then Command = Usidr Else Input_buffer(count) = Usidr End If Incr Count I2c_mode = 11 Usidr = 0 Usisr = 14 Case 2 'Master read Mode I2c_mode = 12 Usidr = 0 Usisr = 14 Case 11 'write ACK to Master I2c_mode = 1 Usidr = 255 Usisr = 0 Case 12 'read ACK from Master I2c_mode = 2 Usidr = &B01101000 '<-- Byte das zum Master ¸bertragen werden soll !!! Usisr = 0 End Select Set Usisr.6 'Reset Counteroverflow Return
Im Datenblatt steht:
When the output driver is enabled for the SDA pin it will force the line SDA low if the output of the USI Data Register or the corresponding bit in the PORTB register is zero. Otherwise, the SDA line will not be driven (i.e., it is released).
Mein Problem ist, wenn ich SDA auf Output schalte, wird das Daten Register nicht gesendet.
Ich blicke da einfach nicht durch, sollte doch eigentlich mit dem Code funktionieren ??
Was habe ich vergessen ? Hat jemand mit dem USI Erfahrung, der mir da weiter helfen kann ?







Zitieren

Lesezeichen