A
Andreas Baier
Guest
Hallo,
nachdem ich jetzt schon einige Versuche hinter mir habe und mir google auch
nichts vernünftiges sagt, versuch ich's hier:
Ich versuche einen mit dem Hardware TWI des Atmega16 den Temperatursensor
(DS1621) anzusprechen, allerdings bekomme ich nach dem Senden der Adresse
kein ACK.
Jetzt frage ich mich, ob es vielleicht ein Fehler am Hardwareaufbau sein
könnte. Ich betreibe den DS1621 zu Testzwecken auf einem Breadboard, direkt
ohne externe Pullups ans STK500 angeschlossen.
Frage: brauche ich doch externe Pullups, oder regelt das TWI das über die
internen Pullups der Ports (PC0/PC1)?
Der Schaltungsaufbau sieht momentan so aus:
STK/AVR DS1621
======= =======
PC0 ------ SCL Vdd -----+
PC1 ------ SDA A0 -+ |
+- Tout A1 -+ |
GND ----+- GND A2 -+ |
+------------+ |
|
VTG ---------------------+
Der ATMega taktet mit 1Mhz. Wenn ich am STK messe, messe ich am VTG-Pin ca.
4,3 V gegnüber GND. Laut Datenblatt sollte das für den DS1621 reichen. Die
Adressbits habe ich auf Masse gelegt - insgesamt ist die Adresse also
"1001000".
Der TestCode sieht folgendermaßen aus (fast 1:1 aus dem Datenblatt des
Atmega16 übernommen):
---- snip
I2CTEST:
push TEMP1
ldi TEMP1, (1<<TWPS1|1<<TWPS0) ;set up prescale
out TWSR, TEMP1
ldi TEMP1, 0xFF ;set up frequency (Atmega@1Mhz)
out TWBR, TEMP1
ldi TEMP1, (1<<TWINT|1<<TWSTA|1<<TWEN) ;send start condition
out TWCR, TEMP1
twiwait1:
in TEMP1,TWCR
sbrs TEMP1, TWINT ;check if TWINT is set (wait
rjmp twiwait1 ;until start has been sent)
in TEMP1, TWSR ;check status register
andi TEMP1, 0xF8 ;mask unnecessary bits
cpi TEMP1, 0x08
brne twierror ;branch on error
ldi TEMP1, 0b10010001 ;load adress SLA_W
out TWDR, TEMP1
ldi TEMP1, (1<<TWINT|1<<TWEN) ;send it
out TWCR, TEMP1
twiwait2:
in TEMP1, TWCR ;check if TWINT is set
sbrs TEMP1, TWINT
rjmp twiwait2
in TEMP1, TWSR ;check on ack
andi TEMP1, 0xF8 ;mask unneccessary
cpi TEMP1, 0x18 ;branch on NACK
brne TWINACK ;print 'n' on NACK
ldi CHARACTER, 'a' ;print 'a' not NACK (on ACK)
rcall PUTCHAR
pop TEMP1
ret
TWIERROR:
ldi Character, 'E'
rcall PUTCHAR
rjmp HALT
TWINACK:
ldi Character, 'n'
rcall Putchar
rjmp HALT
---- snap
Vielleicht kann mir jemand helfen, das Problem zu lösen - langsam bin ich
echt ratlos...
Gruß Andreas
nachdem ich jetzt schon einige Versuche hinter mir habe und mir google auch
nichts vernünftiges sagt, versuch ich's hier:
Ich versuche einen mit dem Hardware TWI des Atmega16 den Temperatursensor
(DS1621) anzusprechen, allerdings bekomme ich nach dem Senden der Adresse
kein ACK.
Jetzt frage ich mich, ob es vielleicht ein Fehler am Hardwareaufbau sein
könnte. Ich betreibe den DS1621 zu Testzwecken auf einem Breadboard, direkt
ohne externe Pullups ans STK500 angeschlossen.
Frage: brauche ich doch externe Pullups, oder regelt das TWI das über die
internen Pullups der Ports (PC0/PC1)?
Der Schaltungsaufbau sieht momentan so aus:
STK/AVR DS1621
======= =======
PC0 ------ SCL Vdd -----+
PC1 ------ SDA A0 -+ |
+- Tout A1 -+ |
GND ----+- GND A2 -+ |
+------------+ |
|
VTG ---------------------+
Der ATMega taktet mit 1Mhz. Wenn ich am STK messe, messe ich am VTG-Pin ca.
4,3 V gegnüber GND. Laut Datenblatt sollte das für den DS1621 reichen. Die
Adressbits habe ich auf Masse gelegt - insgesamt ist die Adresse also
"1001000".
Der TestCode sieht folgendermaßen aus (fast 1:1 aus dem Datenblatt des
Atmega16 übernommen):
---- snip
I2CTEST:
push TEMP1
ldi TEMP1, (1<<TWPS1|1<<TWPS0) ;set up prescale
out TWSR, TEMP1
ldi TEMP1, 0xFF ;set up frequency (Atmega@1Mhz)
out TWBR, TEMP1
ldi TEMP1, (1<<TWINT|1<<TWSTA|1<<TWEN) ;send start condition
out TWCR, TEMP1
twiwait1:
in TEMP1,TWCR
sbrs TEMP1, TWINT ;check if TWINT is set (wait
rjmp twiwait1 ;until start has been sent)
in TEMP1, TWSR ;check status register
andi TEMP1, 0xF8 ;mask unnecessary bits
cpi TEMP1, 0x08
brne twierror ;branch on error
ldi TEMP1, 0b10010001 ;load adress SLA_W
out TWDR, TEMP1
ldi TEMP1, (1<<TWINT|1<<TWEN) ;send it
out TWCR, TEMP1
twiwait2:
in TEMP1, TWCR ;check if TWINT is set
sbrs TEMP1, TWINT
rjmp twiwait2
in TEMP1, TWSR ;check on ack
andi TEMP1, 0xF8 ;mask unneccessary
cpi TEMP1, 0x18 ;branch on NACK
brne TWINACK ;print 'n' on NACK
ldi CHARACTER, 'a' ;print 'a' not NACK (on ACK)
rcall PUTCHAR
pop TEMP1
ret
TWIERROR:
ldi Character, 'E'
rcall PUTCHAR
rjmp HALT
TWINACK:
ldi Character, 'n'
rcall Putchar
rjmp HALT
---- snap
Vielleicht kann mir jemand helfen, das Problem zu lösen - langsam bin ich
echt ratlos...
Gruß Andreas