Forum: Mikrocontroller und Digitale Elektronik TWI-Master mit USI am ATtiny2313 (Assembler)


von Christian S. (solder)


Lesenswert?

Hallo Leute,

versuche seit einiger Zeit TWI per USI am ATTiny 2313 zum Laufen zu 
bringen. Bin schon kurz davor auf Bit banging zu wechseln, da die 
Vereinfachung per USI nur gering zu sein scheint (vor allem als Master). 
Und es funktioniert nicht. Also Start und Stop bekomme ich hin. Ich kann 
mitlerweise sogar das erste Byte ausgeben. Seit dem ich das aber so weit 
habe, dass ein ACK vom Slave zurückkommt, geht danach gar nichts mehr. 
Das ACK setzt nämlich SDA auf L und da bleibt es dann auch. Schon nach 
dem Senden des ersten Bytes ist USIDC im USISR gesetzt (da habe ich 
ACK/NACK noch gar nicht ausgewertet). Sende ich Daten, die kein ACK 
ergeben, passiert das nicht und ich kann auch ein zweites Byte senden.
Jetzt setze ich auch das Schieberegister von Hand weiter, aber 
eigentlich müsste das per SCL passieren (USICS1:0 = 1). So könnte man 
auch ACK und NACK darüber generieren bzw. einlesen. Das funktioniert 
aber bei mir gar nicht.
Was auf dem Bus passiert haben ich mit Logicanalyzer verfolgt. 
Systemtakt ist 7,37MHz.
1
  cli
2
  rcall I2Cinit
3
  rcall I2Cstart
4
  ldi tmp,0x81      ;Adresse $40 + W (Si7021)
5
  rcall I2Csenddata
6
;  brts end        ;NACK?
7
  ldi tmp,0xE0      ;Kommando
8
  rcall I2Csenddata
9
end:
10
  rcall I2Cstop
11
12
loop:   rjmp loop
13
14
I2Cinit:  
15
  sbi portb,7          ;SCL high
16
  sbi portb,5          ;SDA high
17
  sbi ddrb,7          ;Port B7 (SCL) als Ausgang
18
  sbi ddrb,5          ;Port B5 (SDA) als Ausgang
19
  sbi ddrb,0
20
  out usidr,ff        ;Datenregister mit FF initialisieren
21
  ldi tmp,(1<<USIWM1)         ;  | (3<<USICS0)    ;USI-Mode TWI manuellem Clock [163-165]
22
  out usicr,tmp
23
  ret
24
25
I2Cdown:
26
  clr tmp
27
  out usicr,tmp        ;I2C abschalten
28
  ret  
29
30
I2Cstop:
31
  cbi usidr,7          ;SDA auf L (falls H war)
32
  nop
33
  nop
34
  sbi portb,7          ;SCL auf H
35
I2Cstop1:
36
  sbis pinb,7          ;warten, dass auf H geht (falls Clock Stretching)
37
  rjmp I2Cstop1
38
  sbi usidr,7          ;SDA auf H
39
  ret
40
41
I2Cstart:
42
;  out usidr,ff
43
  sbi usidr,7          ;SDA auf high (für Restart)
44
  nop
45
  sbi portb,7          ;SCL auf high (für Restart)
46
I2Cstart1:
47
  sbis pinb,7          ;SCL high?
48
  rjmp I2Cstart1        ;nein - warten
49
;  out usidr,null
50
  cbi usidr,7          ;SDA auf low
51
  nop
52
  cbi portb,7          ;SCL auf low
53
  nop
54
  nop
55
  nop
56
  ret
57
58
; Adresse schicken (Adresse + R/W-Bit in tmp)
59
I2Csenddata:
60
  out usidr,tmp        ;Adresse in Schieberegister
61
  ldi tmp,0xf8        ;Interrupt-Flags löschen, Counter auf 8
62
  out usisr,tmp
63
  ldi tmp,8          ;Bitzähler auf 8
64
I2Csenddata1:
65
  sbi usicr,usitc        ;SCL toggle H
66
I2Csenddata2:
67
  sbis pinb,7          ;SCL high?
68
  rjmp I2Csenddata2      ;noch nicht
69
  nop
70
  sbi usicr,usitc        ;CLK toggle L
71
  nop
72
  sbi usicr,usiclk      ;SR eins weiter
73
  dec tmp            ;Bitzähler, nächstes Bit
74
  brne I2Csenddata1      ;fertig? nein
75
;  in tmp,usisr
76
;  rcall u_printhex
77
;  ldi tmp,13
78
;  rcall serout
79
  ldi tmp,0xff
80
  out usisr,tmp
81
  cbi ddrb,5          ;SDA als Eingang
82
  sbi usicr,usitc        ;CLK toggle H (liest ACK/NACK)
83
  nop
84
  nop
85
  nop
86
  nop 
87
  set
88
  sbis pinb,5          ;SDA auf H (NAK)?
89
  clt              ;nein
90
  sbi usicr,usitc        ;CLK toggle L
91
  sbi ddrb,5          ;SDA auf Ausgang
92
  ret

von Christian S. (solder)


Lesenswert?

Fehler gefunden... Wenn man noch was schreiben will, sollte das LSB 0 
sein in der Adresse.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.