Forum: Mikrocontroller und Digitale Elektronik DS1631 I2C Ansteuerung - Interpretationsprobleme


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Teddy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
wie einige wissen, beschäftige ich mich Zurzeit mit I2C. Das 
Grundprinzip scheine ich verstanden zu haben.
Da ich mit MCP23017 weniger Glück hatte, habe ich mich mit dem DS1631 
beschäftigt.

Ich habe zur Zeit Probleme mit der Datenverarbeitung.
Habe die MSB Bytes und LSB Bytes ausgelesen. Die MSB Bytes müsste ich 
nur auf das Vorzeichen prüfen.

Wie gehe ich mit dem LSB Byte um? Beim LSB Byte geht es ja um die 
Nachkommastellen.
Im Grunde müsste ich die Bits, die gesetzt sind überprüfen und diese 
dann mit dem MSB Bytes verrechnen, aber ich komme nicht klar wie.
1
void DS1631_Temperatur_Read(void)
2
{
3
  uint8_t temp_MSB;
4
  uint8_t temp_LSB;
5
      
6
  I2C_Startbit();
7
  I2C_Slave_RW(I2C_Schreiben);
8
  I2C_Send_Data(Temperatur_Ablesen);
9
  I2C_Startbit();
10
  I2C_Slave_RW(I2C_Lesen);
11
  temp_MSB=I2C_Receive_Data();
12
  temp_LSB=I2C_Receive_Data();
13
  I2C_Stopbit();
14
  
15
  //USART_Transmit_Strings("Die Temperatur betraegt\n");
16
  USART_Transmit(temp_MSB);
17
  //USART_Transmit_Strings(" °C");
18
  
19
}


Dann habe ich noch ein merkwürdiges Problem. Die Funktion
lasse ich in einer While(1) schleife laufen. Leider wird mir nur eine 
Temperatur ausgegeben. Danach hört die Schleife auf.
Das konnte ich durch eine Diode überprüfen. Der Code sieht wie folg aus.
1
#include <avr/io.h>
2
#include "DS1631.h"
3
#include "USART.h"
4
#include "I2C.h"
5
#include <util/delay.h>
6
7
8
int main(void)
9
{  
10
  DDRB=0x00;
11
  PORTB=0x01;
12
  
13
  USART_Init(MYUBRR);
14
  I2C_Init();
15
  DS1631_Config(0x0C);
16
  DS1631_Start_Convert();
17
  while(1)
18
  {
19
      DS1631_Temperatur_Read();    //Temp auslesen
20
      PORTB^=PORTB;                //LED toggeln
21
      _delay_ms(2000);             //ca 2sekunden warten
22
  }
23
24
25
}

von spess53 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi

>  I2C_Slave_RW(I2C_Lesen);
>  temp_MSB=I2C_Receive_Data();
>  temp_LSB=I2C_Receive_Data();  <<<<<<<
>  I2C_Stopbit();

Zwischenfrage: Beim Lesen des letzten Bytes muss der Master ein NACK 
schicken. Das vermisse ich hier.

MfG Spess

von Teddy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>  I2C_Slave_RW(I2C_Lesen);
>>  temp_MSB=I2C_Receive_Data();
>>  temp_LSB=I2C_Receive_Data();  <<<<<<<
>>  I2C_Stopbit();
>
> Zwischenfrage: Beim Lesen des letzten Bytes muss der Master ein NACK
> schicken. Das vermisse ich hier.
>
> MfG Spess

My bad.
Tatsächlich läufts es jetzt.

Wie könnte ich mit dem LSB Byte angehen?
Wie gesagt. Zu Fuß würde ich so vorgehen, dass ich jedes Bit überprüfe, 
ob diese gesetzt sind, dann würde ich dementsprechend rechnen.
Die ersten 4 Bits (0 bis 3) sind 0.
Ist zb das 4. gesetzt, dann rechne ich 2^(-4) dazu, bei 3. Bit 2^(-3) 
usw.
Kennt ihr ne elegantere Lösung?

von Teddy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
PUSH.

Folgendes:

Mein Code für den LSB Byte sieht wie folgt aus, zwar nicht elegant, aber 
sollte funktionieren.
1
void DS1631_Temperatur_Read(void)
2
{
3
  uint8_t temp_MSB;
4
  uint8_t temp_LSB;
5
  float zahl = 0;  
6
  char buffer[30];
7
8
  I2C_Startbit();
9
  I2C_Slave_RW(I2C_Schreiben);
10
  I2C_Send_Data(Temperatur_Ablesen);
11
  I2C_Startbit();
12
  I2C_Slave_RW(I2C_Lesen);
13
  temp_MSB=I2C_Receive_Data();
14
  temp_LSB=I2C_Receive_Data();
15
  I2C_NACKbit();
16
  I2C_Stopbit();
17
  
18
  if(temp_LSB & 0x80)
19
  {
20
    zahl = 0.5 + zahl;
21
  }
22
  if(temp_LSB & 0x40)
23
  {
24
    zahl = 0.25 + zahl;
25
  }
26
  if(temp_LSB & 0x20)
27
  {
28
    zahl = 0.125 + zahl;
29
  }
30
  if(temp_LSB & 0x10)
31
  {
32
    zahl = 0.0625 + zahl;
33
  }
34
  
35
  zahl = zahl + (float) temp_MSB;
36
  
37
  sprintf(buffer, "%f", zahl);
38
  
39
  //USART_Transmit_Strings("Die Temperatur betraegt\n");
40
  USART_Transmit_Strings(buffer);
41
  //USART_Transmit_Strings(" °C");
42
}

Statt dem Temperaturwert bei buffer wird bei mir nur ?????? (Arduino 
Serieller Monitor) bzw. HTerm.exe ausgegeben.

von Auweia (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Teddy schrieb:
> if(temp_LSB & 0x80)
>   {
>     zahl = 0.5 + zahl;
>   ...
>     zahl = 0.0625 + zahl;
> }
>
>   zahl = zahl + (float) temp_MSB;

Das ist jetzt nicht wahr, oder?

Was hieltest du davon, das LSB so zu nehmen wie es ist und z.B. mit 
(1/256.0) gewichtet zu deinem MSB hinzu zu addieren?

von Auweia (Gast)


Bewertung
0 lesenswert
nicht lesenswert
p.s.
Die Tücke dieser Handpulerei liegt bei der 0.
Wenn du aus MSB und LSB zunächst einen 16-Bit signed int machst und den 
dann mit (1/256.0) multiplizierst, passt alles automatisch.

von Klaus R. (klara)


Bewertung
0 lesenswert
nicht lesenswert
Teddy schrieb:
> Mein Code für den LSB Byte sieht wie folgt aus, zwar nicht elegant, aber
> sollte funktionieren.

Hier ist meiner.
1
       Dim cRxDaten As String = USB.RXDaten
2
        '---------------------
3
        Dim iWert As Int32 = 0
4
        Dim iWert0 As Int32 = 0
5
        Dim iWert1 As Int32 = 0
6
7
        iWert0 = Asc(cRxDaten.Substring(1, 1))
8
        iWert1 = Asc(cRxDaten.Substring(2, 1))
9
10
        Try
11
            If CBool(iWert0 And &H80) Then
12
                iWert = (128 - (iWert0 And &H7F))       'alt: iWert0 & &H7F
13
                iWert = iWert * (-10000)
14
            Else
15
                iWert = iWert0
16
                iWert = iWert * 10000
17
            End If
18
            iWert = CInt(iWert + ((iWert1 / (2 ^ 4)) * 625)) ' data2 shr 4
19
            Return iWert
20
        Catch Ex As Exception
21
            Log.File.WriteHandledException(Ex)
22
            iStatus = I2C_Integer_Ueberlauf
23
            Return 0
24
        End Try

von eProfi (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von Teddy (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke Jungs, aber ich kann euren Code leider nicht lesen.
Ich habe jetzt so gemacht, wie hier im Thread:

Beitrag "Re: I2C DS1631 nur NACK"

Ganz unten. Klappt auch, ich muss mir nur die Umrechnung mal anschauen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.