Forum: Mikrocontroller und Digitale Elektronik AT90s2313 + ds1621 (liest nur Schrott)


von Thomas W. (gras78ix)


Angehängte Dateien:

Lesenswert?

Folgendes Problem: Versuche auf einem STK500 mit einem Atmel AT90S2313
den DS1621 Temperatursensor auszulesen; der liefert anscheinend nur
schrott - ich glaub nur nullen.
Ansteuerung: der ds1621 ist direkt an den PortB angeschlossen.
PortB.0 = sda, PortB.1 = sck. Die Adressbit liegen alle auf GND.

Es wird wohl evtl. am Code liegen, nur finde ich den Fehler nicht.
Zuerst hatte ich nach den Spezifikationen gearbeitet, d.h. habe ueber
portB pins gesendet und ueber PinB pins gelesen, was dazu fuehrte,dass
ich nur Einsen (0xFF..FFF) lesen konnte.

Nun lasse ich die PortB pins immer auf null und benutze die DDRB pins
zum 1 oder 0 schreiben. Jetzt lese ich nur Nullen(anscheinend).

Kann mir jemand helfen?
Der Code ist zwar umfangreich, aber gut dokumentiert; Schaut euch den
doch bitte mal an.

Oder muss ich noch etwas zwischen den Leitungen loeten??

von crazy horse (Gast)


Lesenswert?

das ist mir jetzt zu viel zum durchackern...
Über DDRx zu arbeiten ist schon richtig - erfordert aber ext.
pullup-Widerstände scl und sda. Hast du die dran? Richtwert 3k3 oder
4k7.

von Thomas W. (gras78ix)


Lesenswert?

geht das denn nicht mit den internen Pull-Ups ??

von Thomas W. (gras78ix)


Lesenswert?

Ich zeig euch die relevanten Codestellen:
- Initialisierung:
  MCU_initPortB:
  cbi DDRB,_I2C_ClockPin
  cbi PORTB,_I2C_ClockPin
  cbi DDRB,_I2C_DataPin
  cbi PORTB,_I2C_DataPin
  sbi DDRB, _FanControlPin
  sbi PORTB,_FanControlPin
  ret

Bit schreiben:
  I2C_writeBit:
  rcall  I2C_Scl_Low
  cpi    r16,0
  breq  I2C_writeBit_0
  I2C_writeBit_1:
    rcall I2C_Sda_High
    rjmp   I2C_writeBit_exit
  I2C_writeBit_0:
    rcall I2C_Sda_Low
  I2C_writeBit_exit:
    rcall  I2C_Scl_High
    ret

- Bit lesen:
   I2C_readBit:
  push  r18
  rcall  I2C_Scl_Low
  ldi r16,cInput
  rcall  I2C_setDataPinDirection
  rcall  I2C_Scl_High
  in r16,_I2C_InputPort
  andi r16,(1<<_I2C_DataPin)
  I2C_readBit_exit:
    pop r18
    ret

- Sda pin auf high Vcc:
  I2C_Sda_High:
  push   r16
  cbi _I2C_PortDirection,_I2C_DataPin
  ldi r16,cI2C_DataWait
  rcall  MCU_doSleep_1mueS
  pop   r16
  ret

- Sda pin auf Gnd
  I2C_Sda_Low:
  push   r16
  sbi  _I2C_PortDirection,_I2C_DataPin
  ldi  r16,cI2C_DataWait
  rcall  MCU_doSleep_1mueS
  pop   r16
  ret

Scl ist analog

von Uwe (Gast)


Lesenswert?

Hallo Thomas!

Habe mal für dich das Datenblatt gelesen.

<Nun lasse ich die PortB pins immer auf null und benutze die DDRB pins
<zum 1 oder 0 schreiben. Jetzt lese ich nur Nullen(anscheinend).
 .
 .
<geht das denn nicht mit den internen Pull-Ups ??

Und nun ein Auszug aus dem Datenblatt:

Table 19. DDDn Bits on Port D Pins
DDDn PORTDn I/O    Pull Up Comment
 0     0   Input   No Tri-state (Hi-Z)
 0     1   Input   Yes PDn will source current if ext. pulled low.
 1     0   Output  No Push-Pull Zero Output
 1     1   Output  No Push-Pull One Output

Wenn du jetzt deine Aussagen und Fragen kombinierst und in der Tabelle
die notwendigen Spalten beachtest, sollte dir ein Licht aufgehen.

Viel Erfolg, Uwe

von Sven (Gast)


Lesenswert?

>>geht das denn nicht mit den internen Pull-Ups ??

>>Wenn du jetzt deine Aussagen und Fragen kombinierst und in der
Tabelle die notwendigen Spalten beachtest, sollte dir ein Licht
aufgehen.

Oder kürzer: Nein.

Wenn Du über PORTxxx arbeitest, gibt es keine Pullups, high ist high
und der DS zeiht das wohl nicht runter, selbst wenn eine Übetragung
zustande käme, würdest Du nur 0xFF lesen. Sic!

Wenn Du über DDRxxx arbeitest, geht das mit den Pullups "im Prinzip",
aber die Werte sind so hoch (>30k oder so), dass es nach einem low zu
lange dauert, bis die Leitung wieder high ist, Du liest nur 0x00.

Externe Pullups sollten bei etwa 3k3 liegen, bei längeren Leitungen bis
1k runter (gucken was der DS noch an Strom runterziehen kann), oder die
Übertragung extrem verlangsamen.

Sven

von Uwe (Gast)


Lesenswert?

@Sven

<Wenn Du über DDRxxx arbeitest, geht das mit den Pullups "im
Prinzip",
<aber die Werte sind so hoch (>30k oder so), dass es nach einem low zu
<lange dauert, bis die Leitung wieder high ist, Du liest nur 0x00.


DDDn PORTDn I/O    Pull Up   Comment
 0     0   Input     No      Tri-state (Hi-Z)

 1     0   Output    No      Push-Pull Zero Output

Ohne Kommentar.
MFG Uwe

von Thomas W. (gras78ix)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
verwende jetzt externe 3.3 KOhm an SDA und SCL; leider lese ich
jetzt nur noch 0xFF. Ist denn meine Mini-Schaltung fuern A....?

Ist die Wartezeit relevant? Ich dachte die kann nur zu kurz sein,
aber nicht zu lang...
Der AT90S2313 sitzt im STK500 der DS1621 ist so wie im Schaltplan
angeschlossen...
(Manno, mir gehn langsam die Haare zum Ausraufen aus)

von crazy horse (Gast)


Lesenswert?

Mein Gott :-)

pullup-Widerstände gehören von der entsprechenden Leitung nach Vcc,
nicht in Reihe.

von Thomas W. (gras78ix)


Angehängte Dateien:

Lesenswert?

so etwa??
(ok,ok ich hab von pull-up Widerstaenden nicht die kleinste
Ahnung - ich gebs ja zu)

von Sven (Gast)


Lesenswert?

@Uwe

>>DDDn PORTDn I/O    Pull Up   Comment
>> 0     0   Input     No      Tri-state (Hi-Z)
>> 1     0   Output    No      Push-Pull Zero Output
>>Ohne Kommentar.

Stimmt. Man müßte DDR und PORT im Wechsel schalten:

 0     1   Input   Yes PDn will source current if ext. pulled low.
 1     0   Output  No Push-Pull Zero Output

Aber das macht eh keinen Sinn, externe Pull>UP<s dran und fertig.

Sven

von Thomas W. (gras78ix)


Lesenswert?

Habs die 3.3kOhm Pull-Ups wie vorhin beschrieben reingeloetet.
Ist auch alles richtig:
bei
writeBit(0) ist Sda auf 0V
bei
writeBit(1) ist Sda auf +5V

Nur lese ich jetzt immer noch nur 0xFF? Liegts an meiner I2C_readBit
Routine an der readTemperature ???
Oder ist der DS1621 geschossen?
(I2C_Scl_Low,I2C_Scl_High,I2C_Sda_Low,I2C_Sda_High funktionieren)
Hier die Kurzfassungen:

I2C_readBit:(...)
  rcall  I2C_Scl_Low
      ;wait 10 mueSec
  rcall  I2C_Scl_High
      ;wait 10 mueSec
  in r16,_I2C_InputPort
  andi  r16,(1<<_I2C_DataPin)
      (...)

DS1621_readTemperature:
      ldi   r17,cDS1621_Write
  ldi   r18,cDS1621_ReadTemperatur
  rcall  DS1621_sendStart (= write(0x90)+getAck+write(0xAA)+getAck)

  DS1621_readTemperature_main:
  rcall  I2C_Scl_Low
  rcall  I2C_Sda_High
  rcall  I2C_Scl_High

  ldi   r17,0b10010001
  or    r17,r16
  mov  r16,r17
  rcall  I2C_writeByte (= write(0x91)+getAck)
  rcall  I2C_readByte ;MSBYTE->r16
    mov r18,r16
    ldi  r16,0
    rcall  I2C_writeBit ;write an ACK = 0

    rcall  I2C_readByte ;LSBYTE->r16
    mov   r17,r16
    ldi  r16,1
    rcall  I2C_writeBit      ;write an nACK = 1
    rcall  DS1621_sendStop
    ret


Entweder ich seh den Fehler nicht oder die HW ist defekt....

von Thomas W. (gras78ix)


Lesenswert?

Sorry Leute, muss euch nochmal nerven;
Das mit High oder Low auf den Pins funktioniert ja richtig.
Lese komischerweise nur 0xFE, als MSBYTE der Temperatur und 0x00
als LSBYTE der Temperatur.
In meinem Zimmer hat es aber keine 254`C....

von Thomas W. (gras78ix)


Lesenswert?

hm,...wenn ich das ConfigurationsRegister auslese, bekomme
ich 0xFF wieder...

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.