Andun
17.02.2006, 16:29
Moin
Also ich hab ein ganz komisches Problem: Ich hab hier das Pollin Board mit dem ich eine Meßstation aufbaue. (Mega16) Nun möchte ich dafür auch gerne eine Uhr ansprechen. Dafür habe ich den DS1307. (Datasheet zu finden, bei z.b. Reichelt)
Das lässt sich laut Datasheet über I²C ansprechen. Da ich keine Lust hatte mir das alles selbst zu schreiben, habe ich die twimaster.c verwendet die ich hier im Download Bereich gefunden habe. Aber irgendwie funktioniert das nicht. Das Problem ist, dass schon die i2c_start() in ner Endlosschleife wohl hängen bleibt, da das BIT nicht gesetzt wird, welches eine erfolgreiche Start kombination anzeigt. Das selbe passiert viel seltsamer sogar, wenn cih den DS1307 herausnehme und somit also eigentlich ncihts an den Bus angeschloßen ist.
Daraus spekuliere ich, dass es irgendwas mit den Zeiten zu tun hat, oder so. Kann da mal bitte einer drüber schauen? Danke. Hier die main.c und die twimaster.c ganz unten die Ausgabe die ich im Terminal bekomme.
/* -- main.c --
Dieses Programm steuert den ATmega16 des SUBMS.
Selbstfahrendes Umwelt Beobachtungs System - Johannes Kreuzer - 2006
johanneskreuzer@gmx.de
Arbeit für: Jugend Forscht 2006
*/
#ifndef F_CPU
#define F_CPU 8000000 /* Oszillator-Frequenz in Hz */
#endif
#define DS1307 208
#include "avr/io.h"
#include "sht71.h"
#include "uart.h"
#include "i2cmaster.h"
#include <stdint.h>
#include <util/delay.h>
void init_pwm(void);
void PrintInt(int);
void Msleep(int dauer);
uint16_t ReadChannel(uint8_t mux);
uint16_t gibDruck(uint8_t channel);
uint8_t min, sek, hour, wday, date, mon, year;
int main(void)
{
Msleep(50);
uart_init();
i2c_init(); // initialize I2C library
//init_pwm();
FEUCHTE_CONNECTIONRESET();
/*i2c_start_wait(DS1307+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x75); // write value 0x75 to EEPROM
i2c_stop(); // set stop conditon = release bus
*/
while(1) {
uart_puts("\r\nBitte Befehl eingeben: ");
int befehl;
befehl = uart_getc_wait();
uart_puts("\r\nDer eingegebene Befehl lautet: "); PrintInt(atoi(&befehl)); uart_puts("\r\n");
switch (atoi(&befehl)) {
case 0:
uart_puts("Alles messen und ausgeben . . .\r\n");
uart_puts("Luftdruck: "); PrintInt(gibDruck(3)); uart_puts("\r\n");
FEUCHTE_CONNECTIONRESET();
FEUCHTE_MESSUNG(TEMPERATUR);
FEUCHTE_MESSUNG(FEUCHTE);
FEUCHTE_LINEARISIERUNG();
uart_puts("Komp. Feuchte: "); PrintInt(Sensordaten.feuchte_komp); uart_puts("\r\n");
uart_puts("Lin. Temp.: "); PrintInt(Sensordaten.temperatur_lin); uart_puts("\r\n");
uart_puts("Ende!\r\n");
break;
case 8:
uart_puts("Uhrzeit anzeigen: ");
uint8_t min, sek, hour, wday, date, mon, year;
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_rep_start(DS1307+I2C_READ);
sek = i2c_readAck();
min = i2c_readAck();
hour = i2c_readAck();
wday = i2c_readAck();
date = i2c_readAck();
mon = i2c_readAck();
year= i2c_readNak();
i2c_stop();
PrintInt(hour>>4); PrintInt((hour&15));
uart_puts(":");
PrintInt(min>>4); PrintInt((min&15));
uart_puts(":");
PrintInt(sek>>4); PrintInt((sek&15));
uart_puts(" ");
PrintInt(date>>4); PrintInt((date&15));
uart_puts(".");
PrintInt(mon>>4); PrintInt((mon&15));
uart_puts(".");
PrintInt(year>>4); PrintInt((year&15));
break;
case 9:
/*
Dieses Case sollte auskommentiert werden, wenn es nicht benötigt wird, da es sehr viel Speicher belegt.*/
uart_puts("Uhrzeit einstellen . . . \r\n");
uint8_t min2, hour2, date2, mon2, year2;
uart_puts(" vars ");
i2c_init();
uart_puts(" init ");
PrintInt(i2c_start(DS1307+I2C_WRITE));
uart_puts(" start ");
PrintInt(i2c_write(0x00));
PrintInt(i2c_write(128)); //Uhr anhalten
uart_puts("Sekunden: 0 \r\n");
uart_puts("Bitte geben sie die Minuten ein: ");
min = atoi(uart_getc_wait());
min2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x01);
i2c_write(((min<<4)+min2));
uart_puts("Bitte geben sie die Stunden ein (mit 0): ");
hour = atoi(uart_getc_wait());
hour2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x02);
i2c_write(((hour<<4)+(hour2)));
uart_puts("Bitte geben sie den Tag ein (0-7): ");
wday = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x03);
i2c_write(wday);
uart_puts("Bitte geben sie den Monatstag ein (0-31): ");
date = atoi(uart_getc_wait());
date2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x04);
i2c_write(((date<<4)+(date2)));
uart_puts("Bitte geben sie den Monat ein (1-12): ");
mon = atoi(uart_getc_wait());
mon2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x05);
i2c_write(((mon<<4)+(mon2)));
uart_puts("Bitte geben sie das Jahr ein (z.B: 06): ");
year = atoi(uart_getc_wait());
year2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x06);
i2c_write(((year<<4)+(year2)));
//Starten der Uhr:
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_write(0);
i2c_stop();
break;
}
}
while(1);
return 0;
}
/*Initialisiert die PWM Komponente des Controllers*/
void init_pwm() {
DDRD |= (1 << PD4) | (1 << PD5); // OCR1A und B an PD4 und 5 (mega16)
PORTD = 0;
TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10); // 10 Bit Pwm, invertierend
TCCR1B = (1<<CS11) | (1<<CS10); // Prescaler 64
DDRB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3); // Datenleitungen für L298 - Richtung
PORTB = (0 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3); // Datenleitungen für L298 - Bremsen
OCR1A = OCR1B = 1024;
}
/*Liest an dem angegeben Chanel die Spannung aus*/
uint16_t ReadChannel(uint8_t mux) {
uint8_t i;
uint16_t result = 0; //Initialisieren wichtig, da lokale Variablen
//nicht automatisch initialisiert werden und
//zufällige Werte haben. Sonst kann Quatsch rauskommen
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
// setzen auf 8 (1) und ADC aktivieren (1)
ADMUX = mux; // Kanal waehlen
ADMUX |= (0<<REFS1) | (0<<REFS0); // externe Referenzspannung nutzen
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
for(i=0;i<4;i++)
{
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
result += ADCW; // Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
result /= 4; // Summe durch vier teilen = arithm. Mittelwert
return result;
}
/*Schläft die angegeben Zeit in Millisekunden. (Achtung: Genauigkeit nicht bekannt!) */
void Msleep(int dauer) {
int z;
for(z=0;z<dauer;z+=10) _delay_ms(10);
}
/*Liefert den Luftdruck der durch den MPX4115 gemessen wurde.
Als Parameter muss der Channel des AD Converters angegeben werden. */
uint16_t gibDruck(uint8_t channel) {
uint32_t temp;
uint16_t rohWert;
uint8_t ergebnis;
rohWert = ReadChannel(channel);
/*Um den Controller nicht mit Float operationen zu belasten, werden die Zahlen so groß gewählt, */
temp = ((rohWert*10000)/93636)+105000;
ergebnis = temp/10000;
return ergebnis;
}
/************************************************** ***********************
* Title: I2C master library using hardware TWI interface
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: twimaster.c,v 1.2 2005/02/27 21:56:13 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device with hardware TWI
* Usage: API compatible with I2C Software Library i2cmaster.h
************************************************** ************************/
#include <stdint.h>
#include <compat/twi.h>
#include <i2cmaster.h>
#include "uart.h"
/* define CPU frequency in Mhz here if not defined in Makefile */
//Wurde in main.c schon richitg als 8000000 definiert
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
/* I2C clock in Hz */
#define SCL_CLOCK 100000L
/************************************************** ***********************
Initialization of the I2C bus interface. Need to be called only once
************************************************** ***********************/
void i2c_init(void)
{
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
TWSR = 0; /* no prescaler */
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
}/* i2c_init */
/************************************************** ***********************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
************************************************** ***********************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;
uart_puts("\r\n - - i2c_start - "); PrintInt(address); uart_puts(" - \r\n");
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
uart_puts("\r\n - - twi controll - "); PrintInt(TWCR); uart_puts(" - \r\n");
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
uart_puts("\r\n - - Start komplett - - \r\n");
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
uart_puts("\r\n - - address komplett - - \r\n");
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_SLA_ACK) return 1;
return 0;
}/* i2c_start */
/************************************************** ***********************
Issues a start condition and sends address and transfer direction.
If device is busy, use ack polling to wait until device is ready
Input: address and transfer direction of I2C device
************************************************** ***********************/
void i2c_start_wait(unsigned char address)
{
uint8_t twst;
while ( 1 )
{
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
{
/* device busy, send stop condition to terminate write operation */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}
}/* i2c_start_wait */
/************************************************** ***********************
Issues a repeated start condition and sends address and transfer direction
Input: address and transfer direction of I2C device
Return: 0 device accessible
1 failed to access device
************************************************** ***********************/
unsigned char i2c_rep_start(unsigned char address)
{
return i2c_start( address );
}/* i2c_rep_start */
/************************************************** ***********************
Terminates the data transfer and releases the I2C bus
************************************************** ***********************/
void i2c_stop(void)
{
/* send stop condition */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
}/* i2c_stop */
/************************************************** ***********************
Send one byte to I2C device
Input: byte to be transfered
Return: 0 write successful
1 write failed
************************************************** ***********************/
unsigned char i2c_write( unsigned char data )
{
uint8_t twst;
// send data to the previously addressed device
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}/* i2c_write */
/************************************************** ***********************
Read one byte from the I2C device, request more data from device
Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readAck */
/************************************************** ***********************
Read one byte from the I2C device, read is followed by a stop condition
Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readNak */
Hier die Ausgabe am Terminal:
Bitte Befehl eingeben: 9
Der eingegebene Befehl lautet: 9
Uhrzeit einstellen . . .
vars init
- - i2c_start - 208 -
- - twi controll - 36 -
Herzlichen Dank
Andun
Also ich hab ein ganz komisches Problem: Ich hab hier das Pollin Board mit dem ich eine Meßstation aufbaue. (Mega16) Nun möchte ich dafür auch gerne eine Uhr ansprechen. Dafür habe ich den DS1307. (Datasheet zu finden, bei z.b. Reichelt)
Das lässt sich laut Datasheet über I²C ansprechen. Da ich keine Lust hatte mir das alles selbst zu schreiben, habe ich die twimaster.c verwendet die ich hier im Download Bereich gefunden habe. Aber irgendwie funktioniert das nicht. Das Problem ist, dass schon die i2c_start() in ner Endlosschleife wohl hängen bleibt, da das BIT nicht gesetzt wird, welches eine erfolgreiche Start kombination anzeigt. Das selbe passiert viel seltsamer sogar, wenn cih den DS1307 herausnehme und somit also eigentlich ncihts an den Bus angeschloßen ist.
Daraus spekuliere ich, dass es irgendwas mit den Zeiten zu tun hat, oder so. Kann da mal bitte einer drüber schauen? Danke. Hier die main.c und die twimaster.c ganz unten die Ausgabe die ich im Terminal bekomme.
/* -- main.c --
Dieses Programm steuert den ATmega16 des SUBMS.
Selbstfahrendes Umwelt Beobachtungs System - Johannes Kreuzer - 2006
johanneskreuzer@gmx.de
Arbeit für: Jugend Forscht 2006
*/
#ifndef F_CPU
#define F_CPU 8000000 /* Oszillator-Frequenz in Hz */
#endif
#define DS1307 208
#include "avr/io.h"
#include "sht71.h"
#include "uart.h"
#include "i2cmaster.h"
#include <stdint.h>
#include <util/delay.h>
void init_pwm(void);
void PrintInt(int);
void Msleep(int dauer);
uint16_t ReadChannel(uint8_t mux);
uint16_t gibDruck(uint8_t channel);
uint8_t min, sek, hour, wday, date, mon, year;
int main(void)
{
Msleep(50);
uart_init();
i2c_init(); // initialize I2C library
//init_pwm();
FEUCHTE_CONNECTIONRESET();
/*i2c_start_wait(DS1307+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x75); // write value 0x75 to EEPROM
i2c_stop(); // set stop conditon = release bus
*/
while(1) {
uart_puts("\r\nBitte Befehl eingeben: ");
int befehl;
befehl = uart_getc_wait();
uart_puts("\r\nDer eingegebene Befehl lautet: "); PrintInt(atoi(&befehl)); uart_puts("\r\n");
switch (atoi(&befehl)) {
case 0:
uart_puts("Alles messen und ausgeben . . .\r\n");
uart_puts("Luftdruck: "); PrintInt(gibDruck(3)); uart_puts("\r\n");
FEUCHTE_CONNECTIONRESET();
FEUCHTE_MESSUNG(TEMPERATUR);
FEUCHTE_MESSUNG(FEUCHTE);
FEUCHTE_LINEARISIERUNG();
uart_puts("Komp. Feuchte: "); PrintInt(Sensordaten.feuchte_komp); uart_puts("\r\n");
uart_puts("Lin. Temp.: "); PrintInt(Sensordaten.temperatur_lin); uart_puts("\r\n");
uart_puts("Ende!\r\n");
break;
case 8:
uart_puts("Uhrzeit anzeigen: ");
uint8_t min, sek, hour, wday, date, mon, year;
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_rep_start(DS1307+I2C_READ);
sek = i2c_readAck();
min = i2c_readAck();
hour = i2c_readAck();
wday = i2c_readAck();
date = i2c_readAck();
mon = i2c_readAck();
year= i2c_readNak();
i2c_stop();
PrintInt(hour>>4); PrintInt((hour&15));
uart_puts(":");
PrintInt(min>>4); PrintInt((min&15));
uart_puts(":");
PrintInt(sek>>4); PrintInt((sek&15));
uart_puts(" ");
PrintInt(date>>4); PrintInt((date&15));
uart_puts(".");
PrintInt(mon>>4); PrintInt((mon&15));
uart_puts(".");
PrintInt(year>>4); PrintInt((year&15));
break;
case 9:
/*
Dieses Case sollte auskommentiert werden, wenn es nicht benötigt wird, da es sehr viel Speicher belegt.*/
uart_puts("Uhrzeit einstellen . . . \r\n");
uint8_t min2, hour2, date2, mon2, year2;
uart_puts(" vars ");
i2c_init();
uart_puts(" init ");
PrintInt(i2c_start(DS1307+I2C_WRITE));
uart_puts(" start ");
PrintInt(i2c_write(0x00));
PrintInt(i2c_write(128)); //Uhr anhalten
uart_puts("Sekunden: 0 \r\n");
uart_puts("Bitte geben sie die Minuten ein: ");
min = atoi(uart_getc_wait());
min2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x01);
i2c_write(((min<<4)+min2));
uart_puts("Bitte geben sie die Stunden ein (mit 0): ");
hour = atoi(uart_getc_wait());
hour2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x02);
i2c_write(((hour<<4)+(hour2)));
uart_puts("Bitte geben sie den Tag ein (0-7): ");
wday = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x03);
i2c_write(wday);
uart_puts("Bitte geben sie den Monatstag ein (0-31): ");
date = atoi(uart_getc_wait());
date2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x04);
i2c_write(((date<<4)+(date2)));
uart_puts("Bitte geben sie den Monat ein (1-12): ");
mon = atoi(uart_getc_wait());
mon2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x05);
i2c_write(((mon<<4)+(mon2)));
uart_puts("Bitte geben sie das Jahr ein (z.B: 06): ");
year = atoi(uart_getc_wait());
year2 = atoi(uart_getc_wait());
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x06);
i2c_write(((year<<4)+(year2)));
//Starten der Uhr:
i2c_rep_start(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_write(0);
i2c_stop();
break;
}
}
while(1);
return 0;
}
/*Initialisiert die PWM Komponente des Controllers*/
void init_pwm() {
DDRD |= (1 << PD4) | (1 << PD5); // OCR1A und B an PD4 und 5 (mega16)
PORTD = 0;
TCCR1A = (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10); // 10 Bit Pwm, invertierend
TCCR1B = (1<<CS11) | (1<<CS10); // Prescaler 64
DDRB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3); // Datenleitungen für L298 - Richtung
PORTB = (0 << PB0) | (0 << PB1) | (0 << PB2) | (0 << PB3); // Datenleitungen für L298 - Bremsen
OCR1A = OCR1B = 1024;
}
/*Liest an dem angegeben Chanel die Spannung aus*/
uint16_t ReadChannel(uint8_t mux) {
uint8_t i;
uint16_t result = 0; //Initialisieren wichtig, da lokale Variablen
//nicht automatisch initialisiert werden und
//zufällige Werte haben. Sonst kann Quatsch rauskommen
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
// setzen auf 8 (1) und ADC aktivieren (1)
ADMUX = mux; // Kanal waehlen
ADMUX |= (0<<REFS1) | (0<<REFS0); // externe Referenzspannung nutzen
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
for(i=0;i<4;i++)
{
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
result += ADCW; // Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
result /= 4; // Summe durch vier teilen = arithm. Mittelwert
return result;
}
/*Schläft die angegeben Zeit in Millisekunden. (Achtung: Genauigkeit nicht bekannt!) */
void Msleep(int dauer) {
int z;
for(z=0;z<dauer;z+=10) _delay_ms(10);
}
/*Liefert den Luftdruck der durch den MPX4115 gemessen wurde.
Als Parameter muss der Channel des AD Converters angegeben werden. */
uint16_t gibDruck(uint8_t channel) {
uint32_t temp;
uint16_t rohWert;
uint8_t ergebnis;
rohWert = ReadChannel(channel);
/*Um den Controller nicht mit Float operationen zu belasten, werden die Zahlen so groß gewählt, */
temp = ((rohWert*10000)/93636)+105000;
ergebnis = temp/10000;
return ergebnis;
}
/************************************************** ***********************
* Title: I2C master library using hardware TWI interface
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: twimaster.c,v 1.2 2005/02/27 21:56:13 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device with hardware TWI
* Usage: API compatible with I2C Software Library i2cmaster.h
************************************************** ************************/
#include <stdint.h>
#include <compat/twi.h>
#include <i2cmaster.h>
#include "uart.h"
/* define CPU frequency in Mhz here if not defined in Makefile */
//Wurde in main.c schon richitg als 8000000 definiert
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
/* I2C clock in Hz */
#define SCL_CLOCK 100000L
/************************************************** ***********************
Initialization of the I2C bus interface. Need to be called only once
************************************************** ***********************/
void i2c_init(void)
{
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
TWSR = 0; /* no prescaler */
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
}/* i2c_init */
/************************************************** ***********************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
************************************************** ***********************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;
uart_puts("\r\n - - i2c_start - "); PrintInt(address); uart_puts(" - \r\n");
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
uart_puts("\r\n - - twi controll - "); PrintInt(TWCR); uart_puts(" - \r\n");
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
uart_puts("\r\n - - Start komplett - - \r\n");
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
uart_puts("\r\n - - address komplett - - \r\n");
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_SLA_ACK) return 1;
return 0;
}/* i2c_start */
/************************************************** ***********************
Issues a start condition and sends address and transfer direction.
If device is busy, use ack polling to wait until device is ready
Input: address and transfer direction of I2C device
************************************************** ***********************/
void i2c_start_wait(unsigned char address)
{
uint8_t twst;
while ( 1 )
{
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
{
/* device busy, send stop condition to terminate write operation */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}
}/* i2c_start_wait */
/************************************************** ***********************
Issues a repeated start condition and sends address and transfer direction
Input: address and transfer direction of I2C device
Return: 0 device accessible
1 failed to access device
************************************************** ***********************/
unsigned char i2c_rep_start(unsigned char address)
{
return i2c_start( address );
}/* i2c_rep_start */
/************************************************** ***********************
Terminates the data transfer and releases the I2C bus
************************************************** ***********************/
void i2c_stop(void)
{
/* send stop condition */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
}/* i2c_stop */
/************************************************** ***********************
Send one byte to I2C device
Input: byte to be transfered
Return: 0 write successful
1 write failed
************************************************** ***********************/
unsigned char i2c_write( unsigned char data )
{
uint8_t twst;
// send data to the previously addressed device
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}/* i2c_write */
/************************************************** ***********************
Read one byte from the I2C device, request more data from device
Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readAck */
/************************************************** ***********************
Read one byte from the I2C device, read is followed by a stop condition
Return: byte read from I2C device
************************************************** ***********************/
unsigned char i2c_readNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}/* i2c_readNak */
Hier die Ausgabe am Terminal:
Bitte Befehl eingeben: 9
Der eingegebene Befehl lautet: 9
Uhrzeit einstellen . . .
vars init
- - i2c_start - 208 -
- - twi controll - 36 -
Herzlichen Dank
Andun