Forum: Mikrocontroller und Digitale Elektronik LM75 am Atmega32


von abc (Gast)


Lesenswert?

Ich will einen LM75 ansteuern und den Wert über RS232 übertragen.

Als Vorlage habe ich folgendes Programm genommen:
http://www.mikrocontroller.net/attachment/32519/simple_lm75.c

Nur verstehe ich nicht ganz, was da gemacht wird:

        whole_number_degrees = lm75_temp >>8;
        lm75_temp >>=7;
        UDR0 = whole_number_degrees;


Mein Code:
1
#define F_CPU 16000000UL      //Takt 1,6MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
#include <util/twi.h>
7
8
/* Programm Libs */
9
#include "defines.h"
10
11
#define LM75_ADR 0x4F // 7-bit, cf datasheet
12
#define F_SCL 100000
13
14
#define TWI_PRESC 1
15
#define TWBR_VAL (F_CPU / F_SCL - 16) / (2 * TWI_PRESC)
16
17
#if TWBR_VAL > 0xff
18
#   error "TWBR is too large, you need to set a different TWI-prescaler"
19
#elif TWBR_VAL < 0
20
#   undef TWBR_VAL
21
#   define TWBR_VAL 0
22
#endif
23
#define TW_BUSY_WAIT() while( !(TWCR & (1<<TWINT)))
24
25
#define TW_ERROR_MSK 0x1F
26
27
//! Compare TW-Status-register to given status-code
28
#define CHECK_TW_ERROR(ecode)  status = TW_STATUS; \
29
    if (status != ecode) return (status >> 3)
30
31
void twi_init (void);
32
int16_t get_lm75_temp (uint8_t adress/* TODO: , int8_t reg*/);
33
34
volatile uint8_t IRFlag;
35
volatile uint8_t RxData;
36
37
int main(void)
38
{
39
  /* TIMER INIT */
40
//  SETBIT(TCCR0,CS00);// Prescaler von 64 16MHz/64 = 250kHz = 4us
41
//  SETBIT(TCCR0,CS01);
42
//  TCNT0  = 240;    // Reload Wert 0-255   250*4us*8 = 8ms = 125Hz
43
//  SETBIT(TIMSK,TOIE0);   // Timer IR Aktivieren
44
45
  DDRD=0xFB; //D0-D1 & D3-D7 as Output
46
  SETBIT(MCUCR,ISC01); //Fallende Flanke
47
  SETBIT(GICR,INT0); //Taster IR Aktivieren
48
49
  sei();  //Globale IRs aktivieren
50
51
  /* Lokale Variablen: */
52
53
54
  /* Ports as Outputs: */
55
  DDRA=0xFF;
56
  DDRB=0xFF; 
57
  DDRC=0xFF;
58
59
  uart_init();
60
  //SETBIT(PORTB,1);
61
62
SETBIT(PORTA,3);//VCC für Temp
63
    int16_t lm75_temp;
64
    int8_t whole_number_degrees;
65
    twi_init();
66
67
   while (1)
68
   {
69
70
     lm75_temp = get_lm75_temp(LM75_ADR);
71
        if (lm75_temp & TW_ERROR_MSK)
72
        {
73
  CLEARBIT(PORTB,1);//LED      
74
        } else {
75
SETBIT(PORTB,1);//LED
76
        //no error while reading the lm75
77
78
    uart_putc(lm75_temp);
79
 
80
       whole_number_degrees = lm75_temp >>8;
81
        lm75_temp >>=7;
82
        //UDR = whole_number_degrees;
83
    //whole_number_degrees=10;
84
    //uart_putc(whole_number_degrees);  
85
        }     
86
   }
87
 
88
}
89
90
91
92
93
/* TIMER 0 IR HANDLER */
94
ISR( TIMER0_OVF_vect ) //Wenn Timer IR kommt Led ausschalten + IR Flag auf 1
95
{ 
96
    IRFlag = 1;
97
}
98
99
100
/* Taster 0 IR HANDLER */
101
ISR( INT0_vect ) 
102
{ 
103
104
}
105
106
void twi_init (void)
107
{
108
    TWBR = TWBR_VAL;
109
    //TWSR = TWPS & ~TW_STATUS;
110
}
111
112
int16_t get_lm75_temp (uint8_t adress/* TODO: , int8_t reg*/)
113
{
114
    uint8_t ret_val, status;    //return-wert, temp. Variable fuer TWSR
115
    
116
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
117
    TW_BUSY_WAIT();
118
    TWDR = (adress << 1 ) | TW_READ;
119
    TWCR = (1<<TWINT) | (1<<TWEN);
120
    TW_BUSY_WAIT();
121
    CHECK_TW_ERROR(TW_MR_SLA_ACK);
122
    
123
    TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN); //read and send ACK
124
    TW_BUSY_WAIT();
125
    status = TW_STATUS;
126
    CHECK_TW_ERROR(TW_MR_DATA_ACK);
127
    ret_val = TWDR<<8; //get highbyte
128
    
129
    TWCR = (1<<TWINT) | (1<<TWEN);  // read and send NAK
130
    TW_BUSY_WAIT();
131
    CHECK_TW_ERROR(TW_MR_DATA_NACK);
132
    ret_val |= TWDR;    //get low-byte
133
    TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
134
    return ret_val;
135
}

whole_number_degrees ist irgentwie immer 0 und lm75_temp überträgt mir 
den Wert 192, welcher auch nicht ganz korrekt sein kann.
In die Abfrage geht er problemlos hinein, dh kein Error.

Vorallem ändert sich der Wert 192 nicht wirklich.

Habt ihr da ein Paar Tipps für mich?

von abc (Gast)


Lesenswert?

Habs geschafft zumindest ohne die Kommastellen mal!

main.c:
1
#define F_CPU 16000000UL      //Takt 1,6MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
#include <util/twi.h>
7
#include "i2c.h"
8
9
/* Programm Libs */
10
#include "defines.h"
11
12
13
volatile uint8_t IRFlag;
14
volatile uint8_t RxData;
15
16
int main(void)
17
{
18
  /* TIMER INIT */
19
//  SETBIT(TCCR0,CS00);// Prescaler von 64 16MHz/64 = 250kHz = 4us
20
//  SETBIT(TCCR0,CS01);
21
//  TCNT0  = 240;    // Reload Wert 0-255   250*4us*8 = 8ms = 125Hz
22
//  SETBIT(TIMSK,TOIE0);   // Timer IR Aktivieren
23
24
  DDRD=0xFB; //D0-D1 & D3-D7 as Output
25
  SETBIT(MCUCR,ISC01); //Fallende Flanke
26
  SETBIT(GICR,INT0); //Taster IR Aktivieren
27
28
  sei();  //Globale IRs aktivieren
29
30
  /* Lokale Variablen: */
31
32
33
  /* Ports as Outputs: */
34
  DDRA=0xFF;
35
  DDRB=0xFF; 
36
  DDRC=0xFF;
37
38
39
  uart_init();
40
  //SETBIT(PORTB,1);
41
42
SETBIT(PORTA,3);//VCC für Temp
43
44
TWI_init(FAKTOR, TEILER);
45
char temperatur;
46
   while (1)
47
   {
48
49
    temperatur = TWI_empf(ADRESSE_R);
50
    uart_putc(temperatur);    
51
    if ( (UCSRA & (1<<RXC)) ) //Zeichen Empfangen?
52
    {
53
       RxData=uart_getc();
54
       if(RxData=='R')  //Relais Einschalten
55
     {
56
      SETBIT(PORTB,1);//LED
57
      SETBIT(PORTA,6);//Relais
58
      uart_putc('R');                
59
     }
60
       if(RxData=='S')  //Relais Ausschalten
61
     {
62
      CLEARBIT(PORTB,1);//LED
63
      CLEARBIT(PORTA,6);//Relais  
64
      uart_putc('S');              
65
     }
66
     }
67
68
      _delay_ms(1000);
69
70
/*  
71
    uart_putc('f');    
72
      _delay_ms(1000);
73
74
    uart_putc('A');
75
      _delay_ms(1000);
76
    uart_putc(uart_getc());*/
77
   }
78
 
79
}
80
81
82
83
84
/* TIMER 0 IR HANDLER */
85
ISR( TIMER0_OVF_vect ) //Wenn Timer IR kommt Led ausschalten + IR Flag auf 1
86
{ 
87
    IRFlag = 1;
88
}
89
90
91
/* Taster 0 IR HANDLER */
92
ISR( INT0_vect ) 
93
{ 
94
95
}

i2c.h:
1
#define TAKT 16000000UL 
2
#define ADRESSE_R 0b10011111 //Lesen 
3
#define ADRESSE_W 0b10011110 //Schreiben
4
#define FAKTOR 32
5
#define TEILER 1
6
7
void TWI_init(unsigned char faktor, unsigned char teiler)
8
{
9
TWBR = faktor;
10
TWSR = teiler;
11
}
12
13
void TWI_send(unsigned char adres, unsigned char daten)
14
{
15
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
16
loop_until_bit_is_set(TWCR, TWINT);
17
TWDR = adres;
18
TWCR = (1<<TWINT)|(1<<TWEN);
19
loop_until_bit_is_set(TWCR, TWINT);
20
TWDR = daten;
21
TWCR = (1<<TWINT)|(1<<TWEN);
22
loop_until_bit_is_set(TWCR, TWINT);
23
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
24
}
25
26
27
 char dat1, dat2;
28
29
 char TWI_empf(unsigned char adres)
30
{
31
32
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
33
loop_until_bit_is_set(TWCR, TWINT);
34
TWDR = adres;
35
TWCR = (1<<TWINT)|(1<<TWEN);
36
loop_until_bit_is_set(TWCR, TWINT);
37
TWCR = (1<<TWINT)|(1<<TWEN);
38
loop_until_bit_is_set(TWCR, TWINT);
39
dat1 = TWDR ;
40
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
41
42
TWCR = (1<<TWINT)|(1<<TWEN);
43
loop_until_bit_is_set(TWCR, TWINT);
44
dat2 = TWDR ;
45
46
loop_until_bit_is_set(TWCR, TWINT);
47
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
48
49
return dat1;
50
}

von abc (Gast)


Lesenswert?

weiß jemand wo mann da die Kommastelle noch bekommen kann?

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> weiß jemand wo mann da die Kommastelle noch bekommen kann?
Das 2. Byte (dat2) vom LM75 auswerten.

Gruß Oliver

von ... (Gast)


Lesenswert?

Oliver J. schrieb:
> Das 2. Byte (dat2) vom LM75 auswerten.

Im Datenblatt nachgucken kann jeder ;-)

von abc (Gast)


Lesenswert?

Vielen dank!

von abc (Gast)


Lesenswert?

Also dat2 ergibt Wert 32,64 usw.

Dh, ich muss den Wert einfach durch 32 Dividieren, dann hab ich die 
Kommastelle, korrekt?

von abc (Gast)


Lesenswert?

Wenn ich durch 32 dividiere habe ich ja nur 8 mögliche Zahlen ander 
kommastelle, also falsch.

Richtig wäre ja 10/256*dat2 oder?


Empfangsystem:

UTIL_uint2str(res, (int)(10/256*RxData) , 1, 1 );   //Kommastellen

von Oliver J. (skriptkiddy)


Lesenswert?

Versuchs mal so:
1
/* calculate temp in 2 °C */
2
int16_t temp = (dat1<<1) | (dat2>>7);
3
4
/* restore twos complement */
5
if (temp & (1<<8)) temp |= 0xff00;
6
7
/* scale to 1/10 °C */
8
temp *= 5;

Gruß Oliver

von abc (Gast)


Lesenswert?

Beim Auslesen der Temperatur des LM75 hängt sich der Prozessor auf, wenn 
ein Signal über USART reinkommt, versteh das nicht wirklich.

Usart funktioniert Problemlos wenn ich die Zeile auskommentiere:

// temperatur = TWI_empf(ADRESSE_R);
wenn ich sie drinlasse, hängt sich der Prozessor ab und zu auf, wenn 
über USART etwas empfangen wird während diesen Befehls.

Ist sehr strange, habt ihr da eine Idee?

Programm:
1
#define F_CPU 16000000UL //Takt 16MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
#include <util/twi.h>
7
#include "i2c.h"
8
9
/* Programm Libs */
10
#include "defines.h"
11
12
13
volatile uint8_t IRFlag;
14
volatile uint8_t IR_zaehl=0;
15
volatile uint8_t RxData;
16
17
int main(void)
18
{
19
/* TIMER INIT */
20
SETBIT(TCCR0,CS00);// Prescaler von 1024 16MHz/1024 = 15,6kHz = 64us
21
SETBIT(TCCR0,CS02);
22
TCNT0 = 255; // Reload Wert 0-255 250*4us*8 = 8ms = 125Hz
23
SETBIT(TIMSK,TOIE0); // Timer IR Aktivieren
24
25
// DDRD=0xFB; //D0-D1 & D3-D7 as Output
26
// SETBIT(MCUCR,ISC01); //Fallende Flanke
27
// SETBIT(GICR,INT0); //Taster IR Aktivieren
28
29
sei(); //Globale IRs aktivieren
30
31
/* Lokale Variablen: */
32
33
34
/* Ports as Outputs: */
35
DDRA=0xFF;
36
DDRB=0xFF;
37
DDRC=0xFF;
38
39
40
uart_init();
41
//SETBIT(PORTB,1);
42
43
SETBIT(PORTA,3);//VCC für Temp
44
45
TWI_init(FAKTOR, TEILER);
46
unsigned char temperatur=0;
47
unsigned char komma=0;
48
char test=0;
49
while (1)
50
{
51
52
if(IRFlag == 1 && !((UCSRA & (1<<RXC))))
53
{
54
IRFlag=0;
55
SETBIT(PORTB,1);//LED
56
// temperatur = TWI_empf(ADRESSE_R);
57
komma=dat2;
58
CLEARBIT(PORTB,1);//LED
59
}
60
61
//if ( (UCSRA & (1<<RXC)) ) //Zeichen Empfangen?
62
else
63
{
64
RxData=uart_getc();
65
if(RxData=='R') //Relais Einschalten
66
{
67
// SETBIT(PORTB,1);//LED
68
SETBIT(PORTA,6);//Relais
69
uart_putc('R');
70
}
71
if(RxData=='S') //Relais Ausschalten
72
{
73
// CLEARBIT(PORTB,1);//LED
74
CLEARBIT(PORTA,6);//Relais
75
uart_putc('S');
76
}
77
if(RxData=='T') //Relais Ausschalten
78
{
79
if(temperatur)
80
uart_putc(temperatur);
81
}
82
if(RxData=='U') //Relais Ausschalten
83
{
84
if(komma)
85
uart_putc(komma);
86
}
87
RxData=0;
88
}
89
90
_delay_ms(20);
91
92
93
}
94
95
}
96
97
98
99
100
/* TIMER 0 IR HANDLER */
101
ISR( TIMER0_OVF_vect ) //Wenn Timer IR kommt Led ausschalten + IR Flag auf 1
102
{
103
IR_zaehl++;
104
if(IR_zaehl==160)
105
{
106
IRFlag=1;
107
IR_zaehl=0;
108
}
109
}
110
111
112
/* Taster 0 IR HANDLER */
113
ISR( INT0_vect )
114
{
115
116
}

von abc (Gast)


Lesenswert?

Aber es tritt auch nicht immer auf, sondern zufällig. Zurzeit tritt es 
gar nicht auf.

von abc (Gast)


Lesenswert?

Hab jetzt mal einfach alle Bit-Warteschleifen gegen delay warteschleifen 
getauscht.

 char TWI_empf(unsigned char adres)
{

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
//loop_until_bit_is_set(TWCR, TWINT);
    _delay_ms(100);
TWDR = adres;
TWCR = (1<<TWINT)|(1<<TWEN);
//loop_until_bit_is_set(TWCR, TWINT);
    _delay_ms(100);
TWCR = (1<<TWINT)|(1<<TWEN);
//loop_until_bit_is_set(TWCR, TWINT);
    _delay_ms(100);
dat1 = TWDR ;
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);

TWCR = (1<<TWINT)|(1<<TWEN);
//loop_until_bit_is_set(TWCR, TWINT);
    _delay_ms(100);
dat2 = TWDR ;

//loop_until_bit_is_set(TWCR, TWINT);
    _delay_ms(100);
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);

return dat1;
}

von abc (Gast)


Lesenswert?

Hab Pullup von 5 auf 20kOhm geändert, scheint jetz zu funktionieren ;).

von abc (Gast)


Lesenswert?

So, nun zum Eigentlichen Problem der Kommastelle.

TWI_init(FAKTOR, TEILER);
unsigned char temperatur=0;
unsigned char komma=0;

Beim LM75 ists ganz einfach und funktioniert:

temperatur = TWI_empf(ADRESSE_SENSOR3_R); //Für LM75
komma=10/8*(dat2>>5); //Für LM75

Datenblatt:
http://docs-europe.electrocomponents.com/webdocs/0b4c/0900766b80b4c8ed.pdf



Beim LM76 zeigts mir bei der Kommastelle immer 9 an:

temperatur = (TWI_empf(ADRESSE_SENSOR1_R)<<1)|((dat2>>7)); //für LM76
komma=(10*(dat2>>3&0b00001111))/16; //für LM76

Datenblatt:
http://docs-europe.electrocomponents.com/webdocs/06ec/0900766b806ece4e.pdf

Vielleicht habt ihr ne idee, wo mein Denkfehler ist.

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Datenblatt:
> http://docs-europe.electrocomponents.com/webdocs/0...
Du erzählst die ganze Zeit von LM75 und hast einen LM75A? Ich bin von 
9-Bit Auflösung ausgegangen. Deiner hat aber 11.


> temperatur = TWI_empf(ADRESSE_SENSOR3_R); //Für LM75
> komma=10/8*(dat2>>5); //Für LM75
komma=10/8*(dat2>>5); ist sinnlos, weil der Compiler das von links nach 
rechts rechnet:
1
10/8*(dat2>>5) == (10/8)*(dat2>>5) == (1)*(dat2>>5) == (dat2>>5)

Dann wohl eher so herum:
1
komma=(dat2>>5)*10/8;

Aber das funktioniert auch nur für positive Temperaturen. Der 
Temperaturwert ist im 2er-Komplement. Das muss man sich immer vor Augen 
halten, wenn man da selber Hand anlegt.

Teste mal folgenden Temperaturwert in deiner Berechnung:
1
/** 111 1111 1111 == -0.125 °C */
2
dat1 = 0xff;
3
dat2 = 0xe0;

> temperatur = (TWI_empf(ADRESSE_SENSOR1_R)<<1)|((dat2>>7)); //für LM76
> komma=(10*(dat2>>3&0b00001111))/16; //für LM76
Auch das kann nicht für negative Temperaturen funktionieren, weil hier 
ebenfalls ein 2er-Komplement verwendet wird.



Gruß Oliver

von abc (Gast)


Lesenswert?

Ích will nur Temperaturen von ca. 15° bis 35° messen, also sind mir 
negative Zahlen ganz egal, danke für den Tipp mit dem >>.

Werde gleich ein Paar Werte testen.

Sorry ich bin selbst davon ausgegangen dass LM75 und LM75A die selben 
sind, hab aber immer ins Richtige Datenblatt geschaut.

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Ích will nur Temperaturen von ca. 15° bis 35° messen, also sind mir
> negative Zahlen ganz egal, danke für den Tipp mit dem >>.
[ironie]
Das ist die richtige Einstellung. Weiter so.
[/ironie]

So wirds auch für negative Temperaturen funktionieren:
1
/* calculate temp in 1/8 °C */
2
int16_t temp = (dat1<<3) | (dat2>>5);
3
/* restore twos complement */
4
if (dat1 & (1<<7)) temp |= 0xf800;
5
6
/* scale to 1/10 °C */
7
temp = temp*10 / 8;

von abc (Gast)


Lesenswert?

Hab jetzt:
/*    temp_sensor2.temp = TWI_empf(ADRESSE_SENSOR2_R); //Für LM75
    temp_sensor2.komma= (dat2>>5)*10/8; //Für LM75  */


in:

    TWI_empf(ADRESSE_SENSOR2_R);
    temp_sensor2.temp = (dat1<<3) | (dat2>>5);
    if (dat1 & (1<<7)) temp_sensor2.temp |= 0xf800;  /* restore twos 
complement */
      temp_sensor2.temp=temp_sensor2.temp*10 / 8;

geändert, aber angezeigt wird jetzt F0 statt 22.

Ich will übrigens komma und temp getrennt haben, da ich die dann per 
USART übertrage. Am liebesten wär komma einfach 0-9 und Temp halt die 
Temperatur.

von abc (Gast)


Lesenswert?

1
/*    temp_sensor2.temp = TWI_empf(ADRESSE_SENSOR2_R); //Für LM75
2
    temp_sensor2.komma= (dat2>>5)*10/8; //Für LM75  */
1
    TWI_empf(ADRESSE_SENSOR2_R);
2
    temp_sensor2.temp = (dat1<<3) | (dat2>>5);
3
    if (dat1 & (1<<7)) temp_sensor2.temp |= 0xf800;
4
      temp_sensor2.temp=temp_sensor2.temp*10 / 8;

von abc (Gast)


Lesenswert?

Also ich will 8-Bit für Temperatur haben
und
8-Bit für die Kommastelle, wobei ich nur die Kommastelle übertrage.

Das für LM76 und LM75.

Aktueller Code:
1
temp_sensor1.temp = (TWI_empf(ADRESSE_SENSOR1_R)<<1)|((dat2>>7)); //für LM76  
2
temp_sensor1.komma= (dat2>>3&0b00001111)*10/16; //für LM76
3
4
_delay_ms(5);
5
6
temp_sensor2.temp = TWI_empf(ADRESSE_SENSOR2_R); //Für LM75
7
temp_sensor2.komma= (dat2>>5)*10/8; //Für LM75  
8
9
_delay_ms(5);
10
11
temp_sensor3.temp = TWI_empf(ADRESSE_SENSOR3_R); //Für LM75
12
temp_sensor3.komma= (dat2>>5)*10/8; //Für LM75

von Oliver J. (skriptkiddy)


Lesenswert?

Was hat temp_sensor2.temp für einen Datentypen?

Gruß Oliver

von abc (Gast)


Lesenswert?

unsigned char

Gruß,
abc

von abc (Gast)


Lesenswert?

Ich verstehs einfach nicht warum die Kommastelle beim LM76 immer auf 9 
bleibt :(.

von abc (Gast)


Lesenswert?

Niemand eine Idee?

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> unsigned char
>
> Gruß,
> abc
Mach mal int16_t draus und der Wert sollte stimmen. Wie sollen auch mehr 
als 8 Bit in einen unsigned char passen?
Gruß Oliver

von abc (Gast)


Lesenswert?

Wie ich vorher schon verscuht habe zu erklären will ich nur 8Bit, da ich 
dieses Byte dann per USART übertragen will.

Will die Temperatur übertragen in 1Byte, danach die Kommastellen.

Alles funktioniert bis auf die Kommastellen beim LM76.

gruß,
abc

von abc (Gast)


Lesenswert?

1
     if(RxData=='T')  //Temperatur Sensor1 Zahl
2
     {
3
      if(temp_sensor1.temp)
4
        uart_putc(temp_sensor1.temp);  
5
      else 
6
        uart_putc('T');                     
7
     }
8
     if(RxData=='U')  //Temperatur Sensor1 Komma
9
     {
10
      if(temp_sensor1.komma)
11
        uart_putc(temp_sensor1.komma);  
12
      else 
13
        uart_putc('U');                     
14
     }

Ich schaffe es einfach nicht bei den Kommastellen etwas anderes 
rauszubekommen als 9. bzw. 15 ohne *10/16

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Wie ich vorher schon verscuht habe zu erklären will ich nur 8Bit, da ich
> dieses Byte dann per USART übertragen will.

Wenn du meinen Code verwenden willst, dann reichen 8-Bit nicht aus.

Gruß Oliver

von abc (Gast)


Lesenswert?

Also, wie gesagt in meinem Projekt sind negative Werte nicht nötig, da - 
Temperaturen an dem Einsatzort das Ganze Jahr nicht auftreten können.


Ich würde nur gerne wissen wieso dass nicht funktioniert:

temp_sensor1.komma= ((dat2>>3)&0b00001111)*10/16; //für LM76

gruß,
abc

von abc (Gast)


Lesenswert?

Das Problem ist eigentlich dass D3-D6 beim LM76 immer High sind, ist da 
der Sensor Kaputt?

von Michael L. (michaelx)


Lesenswert?

abc schrieb:
> Das Problem ist eigentlich dass D3-D6 beim LM76 immer High sind, ist da
> der Sensor Kaputt?

Hast du schon mal versucht, den Sensor zu konfigurieren? Der LM75A z.B. 
kann zwar 12 bit auflösen, liefert aber per Default nur 9 bit!

HTH
Michael

PS: Sorry, aber wozu gibts eigentlich Datenblätter!?

von abc (Gast)


Lesenswert?

Also ich hab die Datenblätter schon Gründlich durchsucht, finde keine 
Antwort auf meine frage.

Wie kommst du eignetlich darauf dass der LM75A per Default 9Bit liefert? 
Also mir liefert dieser Problemlos 12Bit.

http://docs-europe.electrocomponents.com/webdocs/0b4c/0900766b80b4c8ed.pdf

Wie gesagt mir gehts jetzt um den LM76:
http://docs-europe.electrocomponents.com/webdocs/06ec/0900766b806ece4e.pdf

Bei dem auf den Bits D3,D4,D5,D6 immer ein High ist -> anstatt der 
Kommastelle.

von Werner (Gast)


Lesenswert?

abc schrieb:
> Wie kommst du eignetlich darauf dass der LM75A per Default 9Bit liefert?
> Also mir liefert dieser Problemlos 12Bit.

Woher bekommst du das 12te Bit?
Laut Datenblatt (NXP B.V. 2007, 7.4.3) liegen im Temperaturregister 
genau 11 Bits (D0..D10). Das deckt sich auch mit den 11 Bit des ADC und 
der angegebenen Auflösung von 0.125°C

von abc (Gast)


Lesenswert?

Ich Meinte natürlich 11Bit! und die Frage war wie er auf 9Bits kommt.

Naja wie auch immer beim LM76 habe ich immer noch keine Lösung gefunden 
:(.

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Naja wie auch immer beim LM76 habe ich immer noch keine Lösung gefunden
> :(.
Kommunizierst du auch richtig mit dem Sensor? Poste mal für einen Fall 
beide gelesenen Bytes vom LM76.

Gruß Oliver

von abc (Gast)


Lesenswert?

Raumtemperatur ca. 22,5°:


dat1:
0b00001001

dat2>>3:
0b00011111


temp_sensor1.temp= (dat1<<1)|((dat2>>7));

= 22 DEZ

temp_sensor1.komma= ((dat2>>3)&0b00001111)*10/16; //für LM76

= 9 DEZ

Die High bei dat2 sind das Problem.

Übrigens ich frage ca. alle 2 Sekunden die Sensoren ab.

von abc (Gast)


Lesenswert?

Dat2>>3 ändert sich aber aufjedenfall mit der Temperaturstelle:
0b00011111
0b00001111

je nach dem ob Gerade oder Ungerade Zahl bei der Temperatur. Aber die 
anderen 4 Stellen immer High, und das ist das Problem.

von abc (Gast)


Lesenswert?

Ganz Komischen Phänomen, habe gerade den LM76 direkt beim Controller 
angeschlossen, ohne die Anderen Teilnehmer und jetzt zeigt er neben 9 
als Kommastelle
0b00001111 auch noch 1 an 0b00000011, aber die anderen Kommastellen 
nicht.

Hardware übrigens jetzt 10cm entfernung vom Prozessor, Pull ups 20kOhm. 
100nF entstörkondensator beim LM76.

von abc (Gast)


Lesenswert?

Weiß eigentlich jemand wo man die i2c.h herbekommt die hier verwendet 
wird:
http://www.cursomicros.com/avr/i2c-sensor-temperatura/lm76-programacion.html#uso

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Übrigens ich frage ca. alle 2 Sekunden die Sensoren ab.
Das sollte im grünen Bereich sein.


> je nach dem ob Gerade oder Ungerade Zahl bei der Temperatur. Aber die
> anderen 4 Stellen immer High, und das ist das Problem.
Sicher das es sich um den selben Sensor handelt, der in dem von dir 
verlinkten Datenblatt beschreiben ist? Wie ist die genaue Bezeichnung 
auf dem Chipgehäuse des LM76?


Wie schnell betreibst du den I2C-Bus?

Gruß Oliver

von Oliver J. (skriptkiddy)


Lesenswert?

abc schrieb:
> Weiß eigentlich jemand wo man die i2c.h herbekommt die hier verwendet
> wird:

Das weiß ich nicht, aber ich kenne von Peter Fleury ein gute 
I2C-Library:
http://homepage.hispeed.ch/peterfleury/i2cmaster.zip

Gruß Oliver

von abc (Gast)


Lesenswert?

Vielen dank,
hab echt keinen Plan warums nicht ging, aber jetz mit anderen Libs 
gehts, wahrscheinlich muss man wirklich erst das config register 
ansprechen.

von Michael L. (michaelx)


Lesenswert?

abc schrieb:
> Also ich hab die Datenblätter schon Gründlich durchsucht, finde keine
> Antwort auf meine frage.
>
> Wie kommst du eignetlich darauf dass der LM75A per Default 9Bit liefert?
> Also mir liefert dieser Problemlos 12Bit.

Hattest du geschrieben, um welchen Hersteller es ging?

> http://docs-europe.electrocomponents.com/webdocs/0b4c/0900766b80b4c8ed.pdf

Naja, dann isses wieder was anderes. Ich hatte hier grad ne Doku vom 75A 
von Microchip.

Sorry.

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.