Ferdinand
21.05.2011, 11:36
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
#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);
}
}
uart.h
/*
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") ;
}
}
i2c.h
#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;
}
Terminal Ausgabe
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
Ich möchte das er mir so ein wert "26.5C" anzeigt.
Was mach ich falsch?
Danke
by Ferdinand
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
#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);
}
}
uart.h
/*
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") ;
}
}
i2c.h
#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;
}
Terminal Ausgabe
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
Ich möchte das er mir so ein wert "26.5C" anzeigt.
Was mach ich falsch?
Danke
by Ferdinand