Forum: Mikrocontroller und Digitale Elektronik I2C DS1621 mit 90S8515


von derOJ (Gast)


Lesenswert?

Hallo.
Ich bin am verzweifeln. Habe den DS1621 Chip folgendermaßen
angeschlossen:

Vcc an +5V
A0 bis A2 an +5V -> Adresse 111
GND an Masse

SDA an PD2 (einen 2.7k von +5V zusätzlich darauf als Pull-Up)
SCL an PD7 (einen 2.7k von +5V zusätzlich darauf als Pull-Up)

Wollte zum testen, da ich zum ertsen Mal was mit I2C mache zuerst das
Config Register beschreiben und danach wieder auslesen.

Habe die Routinen von hier benutzt:
http://www.kreatives-chaos.com/index.php?seite=i2croutinen

dann mein Programm so:

.include "8515def.inc"
.include "i2c.inc"


.equ   scl    = 7
 .equ   sda    = 2

 .equ  i2c_port  = PORTD
 .equ  i2c_pin   = PIND
 .equ  i2c_ddr   = DDRD

.equ UBRRVAL = 51    ;8MHz, 9600 Baud

.def temp = r16

.def  rTempL = r18  ;16 Bit Zählregister definieren für pause_10ms
.def  rTempH = r19

        ; Stackpointer initialisieren
  ldi R16, LOW(RAMEND)
  out SPL, R16
  ldi R16, HIGH(RAMEND)
  out SPH, R16

      ; Baudrate einstellen
        ldi temp, UBRRVAL
        out UBRR, temp

  sbi UCR, TXEN    ;TX aktivieren
  cbi UCR, CHR9    ;8Bit Transfer

;register schreiben
  rcall i2c_start
  ldi   r16, 0x9E    ; Adresse des Chips senden ( 0x9F = lesen , 0x9E =
schreiben)
  rcall putbyte

  ldi   r16, 0xAC
  rcall putbyte    ; Bytewert AC (=10101100) an den Chip senden

  ldi r16, 1    ; 1SHOT-Bit in Config-Register setzen
  rcall putbyte
  rcall i2c_stop

  rcall pause_10ms

;register lesen
  rcall i2c_start
  ldi   r16, 0x9E      ; Adresse des Chips senden ( 0x9F = lesen , 0x9E 
=
schreiben)
  rcall putbyte
  ldi r16, 0xAC      ;config-Register
  rcall putbyte

  rcall i2c_start      ;repeated Start, diesmal mit lesen
  ldi r16, 0x9F
  rcall putbyte

  rcall getbyte      ; Wert vom Chip lesen -> r16
  rcall i2c_stop

  subi r16, -48                  ; In ASCII wandeln
  rcall send_serial

ende: rjmp ende                       ;programm einfach anhalten


send_serial:
        sbis USR,UDRE                   ; Warten bis UDR für das
nächste
                                        ; Byte bereit ist
        rjmp send_serial
        out UDR, r16
        ret


pause_10ms:

  ldi rTempL, 0b01000000    ;Den 16 Bit Wert Value
  ldi rTempH, 0b00011111    ;in das Zählregister laden.
Delay2ka:
  subi rTempL, 0x01    ;Das Zählregister um eins
  sbci rTempH, 0x00    ;dekrementieren.
  brne Delay2ka     ;Solange ungleich Null, Vorgang wiederholen.
              ;hier eventuelle NOP's einfügen
  ret



klappt aber nich. Im Hyperterminal tut sich nix.
Habe auch schon mit den original ATMEL Routinen probiert. Da hatte ich
zumindest einen '/' im Terminal.
Was mach ich falsch?

von Thomas (Gast)


Lesenswert?

Ohne deinen Code angeschaut zu haben, weise ich darauf hin, dass man bei
I2C mal gerne die PullUps (4,7 k) vergißt. Kann das vielleicht sein?

Gruß

Thomas

von derOJ (Gast)


Lesenswert?

Ich habe einfach 2,7k genommen weil ich gerade kene anderen hatte. Habe
aber dann auch mit 4,7k probiert...ohne erfolg.
Ich habe die Pull-Ups direkt am DS1621 gelötet.

Ich habe aber nach einigem Probieren es wieder hinbekommen, dass ich
ein '/' auf dem Terminal sehe...Leider macht es überhaupt nichts aus,
welchen Wert ich ins Config Register schreibe.
In der Routine für "ein Byte lesen" wird der Pin am yC als Eingang
mit internem Pull-Up geschaltet. Hab auch mal ohne probiert. Immer
dasselbe Spiel.
Bin dann die Routinen der Reihe nach Befehl für Befehl auf nem Baltt
Papier durchgegangen und mit den Infos im Datenblatt des DS1621
verglichen. Bin zwar kein Profi, aber so wie ich das verstanden habe
passt das Timing auch. Einzig unklar ist die Überprüfung der ACK und
das senden des NACK.
Im Code der Senderoutine wurde eine Schleife auskommentiert, die wartet
bis SDA gecleart wird und stattdessen einfach eine Pause eingefügt.
...
  sbi  I2C_PORT, scl
  rcall pause1u
  rcall pause
;getack_:
;  sbic  I2C_PIN, sda
;  rjmp  getack_
...

In der Empfangsroutine wird ein NACK wird aber überhauptnicht
generiert. Kann mir einer sagen wie man das generiert?
Eigentlich muss man doch nach dem letzten empfangenen Bit, den SDA
wieder als Ausgang schalten und wenn SCL noch LOW ist den SDA auf HIGH
setzen. Dannach dann SCL auch auf HIGH, oder?

von derOJ (Gast)


Lesenswert?

Also.
Nochmal rumgetestet.
Ich habe jetz in meiner Senderoutine eine ausgabe übers UART eingebaut
zur Kontrolle, ob meine Shift-Operationen über das Carry auch funzen.
Da kommen auch die Bytes raus, die ich ihm übergebe. Ich gebe also nach
jedem Shift das Carry aufs SDA und auf das UART.

mache ich dasgleiche jedoch in der Empfangsroutine, bekomme ich nur
Nullen. Also empfängt mein Atmel er nix, oder es wurde auch dem Chip
nix gesendet. Irgendwo noch en Hardwareproblem vielleicht?

von derOJ (Gast)


Lesenswert?

Hi.
Habe jetz den I2C per Software am laufen. Kann den DS1621 also
auslesen.
Jedoch habe ich noch ein Problem.
Ich kann die Vorkommastellen des DS1621 auslesen und erhalte auch
richtige Werte. 20°C im Zimmer, wenn ich mit dem Fön da ran gehe, dann
steigt der Wert auch an, so wie er soll.
Jetz zum Problem.
Ich habe in der Empfangsroutine eine Ausgabefunktion für jedes einzelne
Bit untergebracht. Sprich ich gebe das Byte zur Kontrolle Binär über das
UART aus. Dabei habe ich jedoch gesehen, dass das zweite Byte vom
DS1621, was ja für die NAchkommastelle der Temp. da ist, alle Bits auf
'1' hat.
Laut Datenblatt sollte aber nur das 7te Bit auf '1' bzw. '0' sein,
die restlichen würden alle auf '0' gesetzt...
Woran kann das liegen?

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.