Es geht nur um die Ausgabe? Hast du es schon mal mit dtostrf(); probiert? Kenn mich damit nicht so aus, aber die Werte müssten doch irgendwie in °C umgerechnet werden, oder nicht?
mfg
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
uart.hCode:#include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include <util/delay.h> #include "uart.h" #include "i2c.h" int main (void) { USART_Init( UBRR_VAL ) ; uart_puts ("\033[2J"); uart_puts ("\033[32m"); uart_puts ("Hallo Welt\r\n") ; uart_putc ( 0x01); uart_puts ("\r\nHallo Welt 2 ") ; _delay_ms(10000); TWI_init(FAKTOR, TEILER); unsigned int temperatur; char s[7]; while(1) { uart_puts ("\033[2J"); temperatur = TWI_empf(ADRESSE_R); uart_puts ("\r\nTemperatur ") ; uart_puts( utoa( temperatur, s, 10 ) ); //uart_putc ( temperatur); uart_puts (" C \r\n") ; _delay_ms(1000); } }
i2c.hCode:/* UART-Init: Berechnung des Wertes für das Baudratenregister aus Taktrate und gewünschter Baudrate */ #ifndef F_CPU #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 8000000" #define F_CPU 8000000UL // Systemtakt in Hz - Definition als unsigned long beachten // Ohne ergeben sich unten Fehler in der Berechnung #endif #define BAUD 9600UL // Baudrate // Berechnungen #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler. #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! #endif void USART_Init( unsigned int baud ) { /* Set baud rate */ UBRR0H = (unsigned char)(baud>>8); UBRR0L = (unsigned char)baud; /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN0)|(1<<TXEN0); /* Set frame format: 8data, 1stop bit */ UCSR0C = 3<<UCSZ00; } /* ATmega16 */ int uart_putc(unsigned char c) { while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */ { } UDR0 = c; /* sende Zeichen */ return 0; } /* puts ist unabhaengig vom Controllertyp */ void uart_puts (char *s) { while (*s) { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ uart_putc(*s); s++; } } void uart_cls (void) { int x; for(x=0;x <= 20;x++ ) { uart_puts ("\r\n") ; } }
Terminal AusgabeCode:#define TAKT 8000000UL #define ADRESSE_R 0b10010001 //Lesen #define ADRESSE_W 0b10010000 //Schreiben #define FAKTOR 32 #define TEILER 1 void TWI_init(unsigned char faktor, unsigned char teiler) { TWBR = faktor; TWSR = teiler; } void TWI_send(unsigned char adres, unsigned char daten) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = adres; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = daten; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); } unsigned int TWI_empf(unsigned char adres) { unsigned char dat1, dat2; unsigned int daten; TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = adres; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); dat1 = TWDR ; TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN); TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); dat2 = TWDR ; loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); daten = dat1 | (dat2 << 8); return daten; }
Ich möchte das er mir so ein wert "26.5C" anzeigt.Code:Hallo Welt Hallo Welt 2 Temperatur 12568 C Temperatur 65303 C Temperatur 65303 C Temperatur 12568 C Temperatur 12568 C Temperatur 65303 C Temperatur 12568 C Temperatur 65303 C Temperatur 65303 C Temperatur 12568 C Temperatur 12568 C Temperatur 65303 C
Was mach ich falsch?
Danke
by Ferdinand
habe schreiben erst heute gelernt.
bin legasteniger.
by Ferdinand.
Es geht nur um die Ausgabe? Hast du es schon mal mit dtostrf(); probiert? Kenn mich damit nicht so aus, aber die Werte müssten doch irgendwie in °C umgerechnet werden, oder nicht?
mfg
mfg crowdy
Das Beispiel ist zwar mit Bascom, aber man sieht, wie der LM75 gestrickt ist
http://www.rn-wissen.de/index.php/Se...ur-Sensor_LM75
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
hi
ich habs verstanden.
nur wen ich das 1. beit als char sende dan kommt so was "Temperatur -> C" und kein zahlen wert ?
habe schreiben erst heute gelernt.
bin legasteniger.
by Ferdinand.
Hi
Hier habe ich mein Ergebnis:
"i2c.h"
und die MAIN:Code:#define TAKT 8000000UL #define ADRESSE_R 0b10010001 //Lesen #define ADRESSE_W 0b10010000 //Schreiben #define FAKTOR 32 #define TEILER 1 void TWI_init(unsigned char faktor, unsigned char teiler) { TWBR = faktor; TWSR = teiler; } void TWI_send(unsigned char adres, unsigned char daten) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = adres; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = daten; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); } char dat1, dat2; char TWI_empf(unsigned char adres) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWDR = adres; TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); dat1 = TWDR ; TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN); TWCR = (1<<TWINT)|(1<<TWEN); loop_until_bit_is_set(TWCR, TWINT); dat2 = TWDR ; loop_until_bit_is_set(TWCR, TWINT); TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); return dat1; }
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.Code:#include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include <util/delay.h> #include "uart.h" #include "i2c.h" int main (void) { USART_Init( UBRR_VAL ) ; uart_puts ("\033[2J"); uart_puts ("\033[32m"); uart_puts ("Hallo Welt\r\n") ; uart_putc ( 0x01); uart_puts ("\r\nHallo Welt 2 ") ; _delay_ms(10000); TWI_init(FAKTOR, TEILER); char temperatur; char einer; char zehner; char c = 248; while(1) { uart_puts ("\033[2J"); temperatur = TWI_empf(ADRESSE_R); einer = ( temperatur % 10 ) + 48; zehner = ( temperatur / 10 ) + 48; if (dat2 >= 0b10000000) { uart_puts ("\r\nTemperatur ") ; uart_putc (zehner); uart_putc (einer); uart_puts (",5 "); uart_putc (c); uart_puts ("C \r\n") ; } else { uart_puts ("\r\nTemperatur ") ; uart_putc (zehner); uart_putc (einer); uart_puts (",0 "); uart_putc (c); uart_puts ("C \r\n") ; } _delay_ms(1000); } }
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
habe schreiben erst heute gelernt.
bin legasteniger.
by Ferdinand.
Hallo,
ich weiß der Thread ist schon sehr alt.
Habe deinen code für mein Projekt übernommen, dazu ne frage, gibt es eine Möglichkeit auch die Kommastelle anzuzeigen?
Hi
Welche Komma Stele?
Also die von dem LM75, das habe ich so gelöst:
viel erfolg!!!Code:if (dat2 >= 0b10000000) { uart_puts ("\r\nTemperatur "); uart_putc (zehner); uart_putc (einer); uart_puts (",5 "); uart_putc (c); uart_puts ("C \r\n"); } else { uart_puts ("\r\nTemperatur "); uart_putc (zehner); uart_putc (einer); uart_puts (",0 "); uart_putc (c); uart_puts ("C \r\n"); }
habe schreiben erst heute gelernt.
bin legasteniger.
by Ferdinand.
Danke sehr, habs einfach durch 32 geteilt erstmal, damit hab ich so halbwegs die kommastellen.
Hast du eigentlich auch mal mit dem LM76 gearbeitet? Muss das Programm jetzt so umschreiben dass es auch für LM76 funzt.
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:
#define F_CPU 16000000UL //Takt 16MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <util/twi.h>
#include "i2c.h"
/* Programm Libs */
#include "defines.h"
volatile uint8_t IRFlag;
volatile uint8_t IR_zaehl=0;
volatile uint8_t RxData;
int main(void)
{
/* TIMER INIT */
SETBIT(TCCR0,CS00);// Prescaler von 1024 16MHz/1024 = 15,6kHz = 64us
SETBIT(TCCR0,CS02);
TCNT0 = 255; // Reload Wert 0-255 250*4us*8 = 8ms = 125Hz
SETBIT(TIMSK,TOIE0); // Timer IR Aktivieren
// DDRD=0xFB; //D0-D1 & D3-D7 as Output
// SETBIT(MCUCR,ISC01); //Fallende Flanke
// SETBIT(GICR,INT0); //Taster IR Aktivieren
sei(); //Globale IRs aktivieren
/* Lokale Variablen: */
/* Ports as Outputs: */
DDRA=0xFF;
DDRB=0xFF;
DDRC=0xFF;
uart_init();
//SETBIT(PORTB,1);
SETBIT(PORTA,3);//VCC für Temp
TWI_init(FAKTOR, TEILER);
unsigned char temperatur=0;
unsigned char komma=0;
char test=0;
while (1)
{
if(IRFlag == 1 && !((UCSRA & (1<<RXC))))
{
IRFlag=0;
SETBIT(PORTB,1);//LED
// temperatur = TWI_empf(ADRESSE_R);
komma=dat2;
CLEARBIT(PORTB,1);//LED
}
//if ( (UCSRA & (1<<RXC)) ) //Zeichen Empfangen?
else
{
RxData=uart_getc();
if(RxData=='R') //Relais Einschalten
{
// SETBIT(PORTB,1);//LED
SETBIT(PORTA,6);//Relais
uart_putc('R');
}
if(RxData=='S') //Relais Ausschalten
{
// CLEARBIT(PORTB,1);//LED
CLEARBIT(PORTA,6);//Relais
uart_putc('S');
}
if(RxData=='T') //Relais Ausschalten
{
if(temperatur)
uart_putc(temperatur);
}
if(RxData=='U') //Relais Ausschalten
{
if(komma)
uart_putc(komma);
}
RxData=0;
}
_delay_ms(20);
/*
uart_putc('f');
_delay_ms(1000);
uart_putc('A');
_delay_ms(1000);
uart_putc(uart_getc());*/
}
}
/* TIMER 0 IR HANDLER */
ISR( TIMER0_OVF_vect ) //Wenn Timer IR kommt Led ausschalten + IR Flag auf 1
{
IR_zaehl++;
if(IR_zaehl==160)
{
IRFlag=1;
IR_zaehl=0;
}
}
/* Taster 0 IR HANDLER */
ISR( INT0_vect )
{
}
Geändert von kremsy (02.06.2012 um 21:03 Uhr)
Aber es tritt auch nicht immer auf, sondern zufällig. Zurzeit tritt es gar nicht auf.
Ich mach mich mal an den LM76.
Lesezeichen