Forum: Compiler & IDEs LM75 Auswerten und Temperatur über terminal ausgeben?


von Ferdinand (Gast)


Lesenswert?

Hallo
Ich möchte einen LM75 Auswerten und Temperatur über terminal ausgeben 
nur scheiter das ein wenig.

2 pullup widerstände 10K von SDA, SCL jeweils auf +5V. Die, A0, A1, A2 
jeweils direkt auf GND
und einen 100nF an VCC und GND. Ein gesetzt Wirt ein ATmega644 mit 8MHz 
auf einem STK500

Das Programm.:

MAIN
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdlib.h>
4
#include <util/delay.h>
5
#include "uart.h"
6
#include "i2c.h"
7
8
int main (void) {
9
10
USART_Init( UBRR_VAL ) ;
11
12
13
uart_puts ("\033[2J");
14
15
uart_puts ("\033[32m");
16
17
18
uart_puts ("Hallo Welt\r\n")  ;
19
20
uart_putc ( 0x01);
21
22
uart_puts ("\r\nHallo Welt 2 ")  ;
23
24
_delay_ms(10000);
25
26
27
28
29
TWI_init(FAKTOR, TEILER);
30
unsigned int temperatur;
31
char s[7];
32
33
    while(1)
34
    {
35
36
    uart_puts ("\033[2J");
37
38
    temperatur = TWI_empf(ADRESSE_R);
39
40
    uart_puts ("\r\nTemperatur ")  ;
41
    uart_puts( utoa( temperatur, s, 10 ) );
42
    //uart_putc ( temperatur);
43
    uart_puts (" C \r\n")  ;
44
45
    _delay_ms(1000);
46
47
    }
48
49
}

uart.h
1
/*
2
  UART-Init:
3
Berechnung des Wertes für das Baudratenregister
4
aus Taktrate und gewünschter Baudrate
5
*/
6
 
7
#ifndef F_CPU
8
9
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 8000000"
10
#define F_CPU 8000000UL  // Systemtakt in Hz - Definition als unsigned long beachten
11
                         // Ohne ergeben sich unten Fehler in der Berechnung
12
#endif
13
 
14
#define BAUD 9600UL      // Baudrate
15
 
16
// Berechnungen
17
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
18
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
19
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
20
 
21
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
22
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
23
#endif
24
25
26
27
28
29
void USART_Init( unsigned int baud )
30
{
31
/* Set baud rate */
32
UBRR0H = (unsigned char)(baud>>8);
33
UBRR0L = (unsigned char)baud;
34
/* Enable receiver and transmitter */
35
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
36
/* Set frame format: 8data, 1stop bit */
37
UCSR0C = 3<<UCSZ00;
38
}
39
40
/* ATmega16 */
41
int uart_putc(unsigned char c)
42
{
43
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich                   */
44
    {
45
    }
46
 
47
    UDR0 = c;                      /* sende Zeichen */
48
    return 0;
49
}
50
 
51
/* puts ist unabhaengig vom Controllertyp */
52
void uart_puts (char *s)
53
{
54
    while (*s)
55
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
56
        uart_putc(*s);
57
        s++;
58
    }
59
}
60
61
void uart_cls (void)
62
{
63
int x;
64
65
    for(x=0;x <= 20;x++ )
66
    {  
67
        uart_puts ("\r\n")  ;
68
       
69
    }
70
}

i2c.h
1
#define TAKT 8000000UL
2
#define ADRESSE_R 0b10010001 //Lesen
3
#define ADRESSE_W 0b10010000 //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
unsigned int TWI_empf(unsigned char adres)
27
{
28
unsigned char dat1, dat2;
29
unsigned int daten;
30
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
31
loop_until_bit_is_set(TWCR, TWINT);
32
TWDR = adres;
33
TWCR = (1<<TWINT)|(1<<TWEN);
34
loop_until_bit_is_set(TWCR, TWINT);
35
TWCR = (1<<TWINT)|(1<<TWEN);
36
loop_until_bit_is_set(TWCR, TWINT);
37
dat1 = TWDR ;
38
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
39
40
TWCR = (1<<TWINT)|(1<<TWEN);
41
loop_until_bit_is_set(TWCR, TWINT);
42
dat2 = TWDR ;
43
44
loop_until_bit_is_set(TWCR, TWINT);
45
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
46
47
daten = dat1 | (dat2 << 8);
48
49
return daten;
50
}

Terminal Ausgabe

1
Hallo Welt
2
3
Hallo Welt 2
4
5
Temperatur 12568 C
6
Temperatur 65303 C
7
Temperatur 65303 C
8
Temperatur 12568 C
9
Temperatur 12568 C
10
Temperatur 65303 C
11
Temperatur 12568 C
12
Temperatur 65303 C
13
Temperatur 65303 C
14
Temperatur 12568 C
15
Temperatur 12568 C
16
Temperatur 65303 C

Ich möchte das er mir so ein wert "26.5C" anzeigt.
Was mach ich falsch?

Danke

by Ferdinand

von Ferdinand (Gast)


Lesenswert?

Hi

Hier habe ich mein Ergebnis:


"i2c.h"
1
#define TAKT 8000000UL
2
#define ADRESSE_R 0b10010001 //Lesen
3
#define ADRESSE_W 0b10010000 //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
}
und die MAIN:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdlib.h>
4
#include <util/delay.h>
5
#include "uart.h"
6
#include "i2c.h"
7
8
int main (void) {
9
10
USART_Init( UBRR_VAL ) ;
11
12
uart_puts ("\033[2J");
13
uart_puts ("\033[32m");
14
uart_puts ("Hallo Welt\r\n")  ;
15
uart_putc ( 0x01);
16
uart_puts ("\r\nHallo Welt 2 ")  ;
17
18
_delay_ms(10000);
19
20
TWI_init(FAKTOR, TEILER);
21
char temperatur;
22
char einer;
23
char zehner;
24
char c = 248;
25
26
    while(1)
27
    {
28
29
    uart_puts ("\033[2J");
30
31
    temperatur = TWI_empf(ADRESSE_R);
32
    einer = ( temperatur % 10 ) + 48;
33
    zehner = ( temperatur / 10 ) + 48;
34
35
    
36
    if (dat2 >= 0b10000000)
37
    {
38
    uart_puts ("\r\nTemperatur ")  ;
39
    uart_putc (zehner);
40
    uart_putc (einer);
41
    uart_puts (",5 ");
42
    uart_putc (c);
43
    uart_puts ("C \r\n")  ;
44
    
45
    }
46
47
    else
48
    {
49
    uart_puts ("\r\nTemperatur ")  ;
50
    uart_putc (zehner);
51
    uart_putc (einer);
52
    uart_puts (",0 ");
53
    uart_putc (c);
54
    uart_puts ("C \r\n")  ;
55
    
56
    }
57
    _delay_ms(1000);
58
59
    }
60
}
Das Problem war das mein terminal Ales in ascii interpretiert hat also 
auch die werte die von dem LM75 kommen man muste diesen wert erst um 
Rechnen so das Er dem ascii Code entspricht und ich auch mein 
gewünschten dezimal werte bekomme.

Das geht so auf http://www.torsten-horn.de/techdocs/ascii.htm kan man 
erkennen das Stele 48 mit 0 beginnt und stelle 57 mit 9 endet, also 
musste ich meinen wert erst mal unterteilen um die einer zu erhalten 
teilt man durch 10 und merkt sich den Rest das geht mit "%10" Dan 
verschiebt man den wert um 48 stellen nach hinten also +48 und erhält 
das gewünschte ascii Zeichen, um die zehner zu erhalten, teilt man das 
ganze durch /10 und verschiebt das Ergebnis um 48 stellen also wider +48 
jetzt nur noch nacheinander ausgeben und fertig.

THX

by Ferdinand

von Karl H. (kbuchegg)


Lesenswert?

Ferdinand schrieb:

> Das Problem war das mein terminal Ales in ascii interpretiert hat
> also auch die werte die von dem LM75 kommen man muste diesen wert erst
> um Rechnen so das Er dem ascii Code entspricht und ich auch mein
> gewünschten dezimal werte bekomme.

Das ergibt keinen Sinn.
In dem Programm, das du gepostet hast, hast du utoa benutzt. utoa macht 
genau diese Konvertierung eines Zahlenwertes in einen String.

> erkennen das Stele 48 mit 0 beginnt und stelle 57 mit 9 endet, also
> musste ich meinen wert erst mal unterteilen um die einer zu erhalten
> teilt man durch 10 und merkt sich den Rest das geht mit "%10" Dan
> verschiebt man den wert um 48 stellen nach hinten also +48 und erhält
> das gewünschte ascii Zeichen, um die zehner zu erhalten, teilt man das
> ganze durch /10 und verschiebt das Ergebnis um 48 stellen also wider +48
> jetzt nur noch nacheinander ausgeben und fertig.

Das ist alles prinzipiell richtig. Nur macht man das nicht so. Genau 
dafür gibt es die Konvertierfunktionen, itoa, utoa, und wie sie noch 
alle heißen.


Deine
unsigned int TWI_empf(unsigned char adres)
sieht jetzt anders aus und dort ist der Schlüssel zur Lösung zu suchen.

von Ferdinand (Gast)


Lesenswert?

Ja schön zu sehen das es Menschen gibt die so hilfsbereit sind ich danke 
dir das wenigstens du den Mut hast mir zu antworten dein Beitrag hilft 
mir zwar nicht, zu mindestens bekomme ich ein wenig Aufmerksamkeit der 
Wille zählt (-;

Wenn ich dich trotzdem bitten, dürfte mir deine Idee oder Empfehlung 
etwas genauer zu erläutern würdest Dan bekomme ich mein Programm noch 
effizienter hin, den ich hatte das mit den beschriebenen Funktionen 
versucht und nicht hin bekommen

P.S.: Da man einem Text keine Emotionen ansieht möchte ich noch mal 
betonen, dass ich mich wirklich freue (-:


THX

by
Ferdinand

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.