B.Rust
02.11.2004, 09:45
Ich benutze folgenden Quellcode:
/************************************************** ************************************************** *
* Originalprogramm war TWI-Example aus der AVR-LibC *
* Original geschrieben von Joerg Wunsch <joerg@FreeBSD.ORG> , mit der Beerware-License *
************************************************** ************************************************** */
/************************************************** ************************************************** *
* *
* Programm für RN V1.4 Board mit Atmega32 *
* *
* geaendert von Merviux *
* *
* Auslösen von US-Messungen, Einlesen der Messwerte, Übermittlung *
* der Daten über RS232 an Konsole *
* *
************************************************** ************************************************** */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <interrupt.h>
#include <avr/io.h>
#include <avr/twi.h>
#define DEBUG 1
#define OCR_1MS 115
#define SYSCLK 16000000UL
/* Definitionen */
#ifndef UCSRB
# ifdef UCSR1A
# define UCSRA UCSR1A
# define UCSRB UCSR1B
# define UBRR UBRR1L
# define UDR UDR1
# else
# define UCSRA USR
# define UCSRB UCR
# endif
#endif
#ifndef UBRR
# define UBRR UBRRL
#endif
#define SFR_BC 0x00 /* Broadcast Adresse, auf die alle SRF reagieren */
#define SFR_XX 0xe0 /* Default Adresse bei Auslieferung */
/************************************************** ************************************************** *
* Maximale Anzahl der Wiederholungen um auf eine Antwort seitens des *
* I2C-Slaves zu warten. Lang genug, um eine Schreibeoperation auszuführen *
* aber dennoch bei fehlender Rückmeldung abzubrechen. Die Start-Sequenz und *
* Übermittlung der Slave-Adresse, sowie R/W-Befehl, dauert bei 100 kHz *
* TWI Takt ca. 10 µs. Da ein Schreibvorgang etwa 10 ms nicht überschreiten *
* sollte, würden auch 100 Iterationen ausreichen. *
* *
************************************************** ************************************************** */
#define MAX_ITER 255
/************************************************** ************************************************** *
* Sichern des TWI Statusregisters für Fehlermeldungen. Der Status muss in *
* einer Variable gespeichert werden, da das TWSR-Register nur bei aktiven *
* TWINT-Bit des TWCR konsistent bleibt. *
************************************************** ************************************************** */
uint8_t twst;
/************************************************** ************************************************** *
* erg ist eine Zählvariable, buf ein Zeichenfeld für Ausgabe an RS232 *
* ms_count dient dem Timer *
* *
************************************************** ************************************************** */
uint8_t erg;
char buf[8];
volatile uint16_t ms_count;
/************************************************** ************************************************** *
* Ausgabe String *
* Schreibt die einzelnen Zeichen des Zeichenfeldes buf[] in den UDR-Puffer *
* *
************************************************** ************************************************** */
int usartprint(char *buf,int len)
{
int i;
for (i=0;i<len;i++) {
/* wenn das UDRE-Bit gesetzt ist, ist der UDR Puffer leer.
* Neue Daten können übertragen werden. */
while ( !(UCSRA & _BV(UDRE)) )
;
UDR = buf[i];
}
return i;
}
/************************************************** *************************************************
* Die UART-Schnittstelle und der TWI-Takt wird initialisiert *
* *
************************************************** *************************************************/
void
ioinit(void)
{
UCSRB = _BV(TXEN); /* tx enable */
UBRRL=103; /* 9600 Bd */
/* Initialisierung TWI-Takt: 100 kHz Takt, TWPS = 0 => Multiplikator = 1 */
#if defined(TWPS0)
TWSR = 0;
#endif
TWBR = (SYSCLK / 100000UL - 16) / 2;
uint8_t bitrate_div;
// I2C Bitrate
// SCL freq = F_CPU/(16+2*TWBR))
#ifdef TWPS0
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
#endif
// Bitrate ermitteln
bitrate_div = ((16000000/1000l)/100);
if(bitrate_div >= 16)
bitrate_div = (bitrate_div-16)/2;
outb(TWBR, bitrate_div);
}
/************************************************** ************************************************** *
* Zeichen ueber UART ausgeben *
************************************************** ************************************************** */
int
uart_putchar(char c)
{
if (c == '\n')
uart_putchar('\r');
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}
/************************************************** ************************************************** *
* US-Sensor beschreiben *
* Der Sensor mit der Adresse modul_addr wird im Register reg_nr mit dem Befehl befehl *
* angestossen. *
* z.B.: *
* modul_addr : 0xe0 (default) *
* Register : 0x00 (Befehlsregister) *
* Befehl : 0x51 (Messung in cm) *
* *
************************************************** ************************************************** */
int
sfr_schreiben(uint8_t modul_addr, uint8_t reg_nr, uint8_t befehl)
{
uint8_t sla, adr, n = 0;
int rv = 0;
/* Slave-Adresse uebergeben */
sla = modul_addr;
switch(sla){
case 0x00:
adr = 0;
break;
case 0xe0:
adr = 1;
break;
case 0xe2:
adr = 2;
break;
case 0xe4:
adr = 3;
break;
case 0xe6:
adr = 4;
break;
case 0xe8:
adr = 5;
break;
case 0xea:
adr = 6;
break;
case 0xec:
adr = 7;
break;
case 0xee:
adr = 8;
break;
case 0xf0:
adr = 9;
break;
case 0xf2:
adr = 10;
break;
case 0xf4:
adr = 11;
break;
case 0xf6:
adr = 11;
break;
default:
adr = 1;
}
restart:
if (n++ >= MAX_ITER){
printf("Max_Iter ! \n");
return -1;}
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Start Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_REP_START:
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
return -1; /* Fehler: nicht in Start-Bedingung */
/* Keine Stop-Bedingung */
}
/* Slave-Adresse und Schreibebefehl uebermitteln */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* NACK : Modul schreibt = Busy */
goto restart;
case TW_MT_ARB_LOST: /* neue Arbitration/Zuweisung */
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = reg_nr; /* Registernummer */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
rv++;
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = befehl; /* Befehl */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
rv++;
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* Stop-Bedingung senden */
/*printf("\nSensor: %d befehligt mit", adr);
printf(" CMD %d ,", reg_nr);
printf(" Befehl %d \n", befehl);*/
return rv;
error:
rv = -1;
goto quit;
}
/************************************************** ************************************************** *
* US-Sensor Lesen *
* Aus dem Sensor mit der Adresse modul_addr wird das Register reg_nr gelesen *
* z.B.: *
* modul_addr : 0xe0 (default) *
* Register : 0x00 (Befehlsregister) *
* *
************************************************** ************************************************** */
int
sfr_lesen(uint8_t modul_addr, uint8_t reg_nr)
{
uint8_t sla, twcr, adr, n = 0;
int rv = 0;
int len =2;
sla = modul_addr ; /* Adresse uebergeben */
switch(sla){
case 0x00:
adr = 0;
break;
case 0xe0:
adr = 1;
break;
case 0xe2:
adr = 2;
break;
case 0xe4:
adr = 3;
break;
case 0xe6:
adr = 4;
break;
case 0xe8:
adr = 5;
break;
case 0xea:
adr = 6;
break;
case 0xec:
adr = 7;
break;
case 0xee:
adr = 8;
break;
case 0xf0:
adr = 9;
break;
case 0xf2:
adr = 10;
break;
case 0xf4:
adr = 11;
break;
case 0xf6:
adr = 11;
break;
default:
adr = 1;
}
/*
* Erster Zyklus: Master-Mode, schreiben auf BUS
*/
restart:
if (n++ >= MAX_ITER)
return -1;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Start-Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_REP_START:
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
return -1; /* Fehler: nicht in Start-Bedingung */
/* Keine Stop-Bedingung */
}
/* Slave-Adresse und Schreibebefehl uebermitteln */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* NACK : Modul schreibt = Busy */
goto restart;
case TW_MT_ARB_LOST: /* erneute Arbitrierung */
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = reg_nr; /* zu lesendes Register */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
printf("Lesen NACK \n");
goto quit;
case TW_MT_ARB_LOST:
printf("Lesen BUS weg \n");
goto begin;
default:
printf("Lesen Fehler \n");
goto error; /* Stop-Bedingung senden */
}
/*
* Naechsten Zyklen: Master-Mode, lesen
*/
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Wiederholung der Start-Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_START:
case TW_REP_START:
break;
case TW_MT_ARB_LOST:
printf("ARB Lost \n");
goto begin;
default:
printf("Fehler Master mode \n");
goto error;
}
/* send SLA+R */
TWDR = sla | TW_READ;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK:
goto quit;
case TW_MR_ARB_LOST:
goto begin;
default:
printf("Fehler Lesebefehl \n");
goto error;
}
for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
len > 0;
len--)
{
if (len == 1)
twcr = _BV(TWINT) | _BV(TWEN); /* NAK setzen */
TWCR = twcr; /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
break; /* Schleife beenden */
case TW_MR_DATA_ACK:
erg = TWDR; /* Ausgaben */
rv++;
break;
default:
printf("Fehler Datenerhalt \n");
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* Stop-Bedingung */
return rv;
error:
printf("Fehler Routinenausgang mit rv-Satus = %d .",rv);
rv = -1;
goto quit;
}
/************************************************** ************************************************** *
* Verzoegerung (Wartezeit) *
* *
************************************************** ************************************************** */
void ms_sleep(uint16_t ms)
{
TCNT0 = 0;
ms_count = 0;
while (ms_count < ms)
;
}
/************************************************** ************************************************** *
* Millisekundenzaehler fuer Unterbrechung *
* *
************************************************** ************************************************** */
SIGNAL(SIG_OUTPUT_COMPARE0)
{
ms_count++;
}
/************************************************** ************************************************** *
* Timer0 initialisieren um den Quarzkristall und den Output-Compare-Interrupt *
* zu benutzen - auf diese Weise erfolgt eine Unterbrechung etwa einmal pro 1 ms. *
* *
************************************************** ************************************************** */
void init_timer0(void)
{
TCCR0 = 0;
TIFR |= BV(OCIE0)|BV(TOIE0);
TIMSK |= BV(TOIE0)|BV(OCIE0); /* enable output compare interrupt */
TCCR0 = BV(WGM01)|BV(CS02)|BV(CS00); /* CTC, prescale = 128 */
TCNT0 = 0;
OCR0 = OCR_1MS; /* match in aprox 1 ms */
}
/************************************************** ************************************************** *
* Fehler *
* *
************************************************** ************************************************** */
void
error(void)
{
printf("error: TWI status %#x\n", twst);
//exit(0); // Unterbrechen des Programms --> Ende
}
/************************************************** ************************************************** *
* Main *
* *
************************************************** ************************************************** */
void main(void)
{
uint16_t a = 0;
int rv;
int regnr;
int addr = 0xe0;
init_timer0();
ioinit();
sei();
fdevopen(uart_putchar, NULL, 0);
ms_sleep(500);
rv = sfr_schreiben(0x00, 0x01, 0x06);
ms_sleep(100);
rv = sfr_schreiben(0x00, 0x02, 0x4a);
ms_sleep(100);
for(;;){
rv = sfr_schreiben(0x00, 0x00, 0x51);
ms_sleep(40);
printf("Sensor %d ", addr);
for(regnr = 3; regnr < 4; ){
rv = sfr_lesen(addr, regnr);
if (rv <= 0)
error();
if (rv < 1)
printf("warning: short read %d\n", rv);
dtostrf(erg,7,3,buf);
printf("Reg. %d ", regnr);
printf("Wert: ");
usartprint(buf,8);
regnr++;
}
printf("\n");
}
putchar('\n');
a++;
printf("Messung %d beendet \n \n ", a);
}
Ich bekomme als Ausgabe folgendes:
nsor 224 Reg. 3 Wert: se}KyaM
Sensor 224 Reg. 3 Wert: se}KyaM
Sensor 224 Reg. 3 Wert: se}KyaM
Könnte es sein, dass irgendwas mit dem US nicht stimmt? Irgendwie bekomme ich keine vernünftigen werte...
/************************************************** ************************************************** *
* Originalprogramm war TWI-Example aus der AVR-LibC *
* Original geschrieben von Joerg Wunsch <joerg@FreeBSD.ORG> , mit der Beerware-License *
************************************************** ************************************************** */
/************************************************** ************************************************** *
* *
* Programm für RN V1.4 Board mit Atmega32 *
* *
* geaendert von Merviux *
* *
* Auslösen von US-Messungen, Einlesen der Messwerte, Übermittlung *
* der Daten über RS232 an Konsole *
* *
************************************************** ************************************************** */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <interrupt.h>
#include <avr/io.h>
#include <avr/twi.h>
#define DEBUG 1
#define OCR_1MS 115
#define SYSCLK 16000000UL
/* Definitionen */
#ifndef UCSRB
# ifdef UCSR1A
# define UCSRA UCSR1A
# define UCSRB UCSR1B
# define UBRR UBRR1L
# define UDR UDR1
# else
# define UCSRA USR
# define UCSRB UCR
# endif
#endif
#ifndef UBRR
# define UBRR UBRRL
#endif
#define SFR_BC 0x00 /* Broadcast Adresse, auf die alle SRF reagieren */
#define SFR_XX 0xe0 /* Default Adresse bei Auslieferung */
/************************************************** ************************************************** *
* Maximale Anzahl der Wiederholungen um auf eine Antwort seitens des *
* I2C-Slaves zu warten. Lang genug, um eine Schreibeoperation auszuführen *
* aber dennoch bei fehlender Rückmeldung abzubrechen. Die Start-Sequenz und *
* Übermittlung der Slave-Adresse, sowie R/W-Befehl, dauert bei 100 kHz *
* TWI Takt ca. 10 µs. Da ein Schreibvorgang etwa 10 ms nicht überschreiten *
* sollte, würden auch 100 Iterationen ausreichen. *
* *
************************************************** ************************************************** */
#define MAX_ITER 255
/************************************************** ************************************************** *
* Sichern des TWI Statusregisters für Fehlermeldungen. Der Status muss in *
* einer Variable gespeichert werden, da das TWSR-Register nur bei aktiven *
* TWINT-Bit des TWCR konsistent bleibt. *
************************************************** ************************************************** */
uint8_t twst;
/************************************************** ************************************************** *
* erg ist eine Zählvariable, buf ein Zeichenfeld für Ausgabe an RS232 *
* ms_count dient dem Timer *
* *
************************************************** ************************************************** */
uint8_t erg;
char buf[8];
volatile uint16_t ms_count;
/************************************************** ************************************************** *
* Ausgabe String *
* Schreibt die einzelnen Zeichen des Zeichenfeldes buf[] in den UDR-Puffer *
* *
************************************************** ************************************************** */
int usartprint(char *buf,int len)
{
int i;
for (i=0;i<len;i++) {
/* wenn das UDRE-Bit gesetzt ist, ist der UDR Puffer leer.
* Neue Daten können übertragen werden. */
while ( !(UCSRA & _BV(UDRE)) )
;
UDR = buf[i];
}
return i;
}
/************************************************** *************************************************
* Die UART-Schnittstelle und der TWI-Takt wird initialisiert *
* *
************************************************** *************************************************/
void
ioinit(void)
{
UCSRB = _BV(TXEN); /* tx enable */
UBRRL=103; /* 9600 Bd */
/* Initialisierung TWI-Takt: 100 kHz Takt, TWPS = 0 => Multiplikator = 1 */
#if defined(TWPS0)
TWSR = 0;
#endif
TWBR = (SYSCLK / 100000UL - 16) / 2;
uint8_t bitrate_div;
// I2C Bitrate
// SCL freq = F_CPU/(16+2*TWBR))
#ifdef TWPS0
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
#endif
// Bitrate ermitteln
bitrate_div = ((16000000/1000l)/100);
if(bitrate_div >= 16)
bitrate_div = (bitrate_div-16)/2;
outb(TWBR, bitrate_div);
}
/************************************************** ************************************************** *
* Zeichen ueber UART ausgeben *
************************************************** ************************************************** */
int
uart_putchar(char c)
{
if (c == '\n')
uart_putchar('\r');
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}
/************************************************** ************************************************** *
* US-Sensor beschreiben *
* Der Sensor mit der Adresse modul_addr wird im Register reg_nr mit dem Befehl befehl *
* angestossen. *
* z.B.: *
* modul_addr : 0xe0 (default) *
* Register : 0x00 (Befehlsregister) *
* Befehl : 0x51 (Messung in cm) *
* *
************************************************** ************************************************** */
int
sfr_schreiben(uint8_t modul_addr, uint8_t reg_nr, uint8_t befehl)
{
uint8_t sla, adr, n = 0;
int rv = 0;
/* Slave-Adresse uebergeben */
sla = modul_addr;
switch(sla){
case 0x00:
adr = 0;
break;
case 0xe0:
adr = 1;
break;
case 0xe2:
adr = 2;
break;
case 0xe4:
adr = 3;
break;
case 0xe6:
adr = 4;
break;
case 0xe8:
adr = 5;
break;
case 0xea:
adr = 6;
break;
case 0xec:
adr = 7;
break;
case 0xee:
adr = 8;
break;
case 0xf0:
adr = 9;
break;
case 0xf2:
adr = 10;
break;
case 0xf4:
adr = 11;
break;
case 0xf6:
adr = 11;
break;
default:
adr = 1;
}
restart:
if (n++ >= MAX_ITER){
printf("Max_Iter ! \n");
return -1;}
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Start Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_REP_START:
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
return -1; /* Fehler: nicht in Start-Bedingung */
/* Keine Stop-Bedingung */
}
/* Slave-Adresse und Schreibebefehl uebermitteln */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* NACK : Modul schreibt = Busy */
goto restart;
case TW_MT_ARB_LOST: /* neue Arbitration/Zuweisung */
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = reg_nr; /* Registernummer */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
rv++;
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = befehl; /* Befehl */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
rv++;
break;
case TW_MT_DATA_NACK:
goto quit;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* Stop-Bedingung senden */
/*printf("\nSensor: %d befehligt mit", adr);
printf(" CMD %d ,", reg_nr);
printf(" Befehl %d \n", befehl);*/
return rv;
error:
rv = -1;
goto quit;
}
/************************************************** ************************************************** *
* US-Sensor Lesen *
* Aus dem Sensor mit der Adresse modul_addr wird das Register reg_nr gelesen *
* z.B.: *
* modul_addr : 0xe0 (default) *
* Register : 0x00 (Befehlsregister) *
* *
************************************************** ************************************************** */
int
sfr_lesen(uint8_t modul_addr, uint8_t reg_nr)
{
uint8_t sla, twcr, adr, n = 0;
int rv = 0;
int len =2;
sla = modul_addr ; /* Adresse uebergeben */
switch(sla){
case 0x00:
adr = 0;
break;
case 0xe0:
adr = 1;
break;
case 0xe2:
adr = 2;
break;
case 0xe4:
adr = 3;
break;
case 0xe6:
adr = 4;
break;
case 0xe8:
adr = 5;
break;
case 0xea:
adr = 6;
break;
case 0xec:
adr = 7;
break;
case 0xee:
adr = 8;
break;
case 0xf0:
adr = 9;
break;
case 0xf2:
adr = 10;
break;
case 0xf4:
adr = 11;
break;
case 0xf6:
adr = 11;
break;
default:
adr = 1;
}
/*
* Erster Zyklus: Master-Mode, schreiben auf BUS
*/
restart:
if (n++ >= MAX_ITER)
return -1;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Start-Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_REP_START:
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
return -1; /* Fehler: nicht in Start-Bedingung */
/* Keine Stop-Bedingung */
}
/* Slave-Adresse und Schreibebefehl uebermitteln */
TWDR = sla | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK: /* NACK : Modul schreibt = Busy */
goto restart;
case TW_MT_ARB_LOST: /* erneute Arbitrierung */
goto begin;
default:
goto error; /* Stop-Bedingung senden */
}
TWDR = reg_nr; /* zu lesendes Register */
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK:
printf("Lesen NACK \n");
goto quit;
case TW_MT_ARB_LOST:
printf("Lesen BUS weg \n");
goto begin;
default:
printf("Lesen Fehler \n");
goto error; /* Stop-Bedingung senden */
}
/*
* Naechsten Zyklen: Master-Mode, lesen
*/
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* Wiederholung der Start-Bedingung */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_START:
case TW_REP_START:
break;
case TW_MT_ARB_LOST:
printf("ARB Lost \n");
goto begin;
default:
printf("Fehler Master mode \n");
goto error;
}
/* send SLA+R */
TWDR = sla | TW_READ;
TWCR = _BV(TWINT) | _BV(TWEN); /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK:
goto quit;
case TW_MR_ARB_LOST:
goto begin;
default:
printf("Fehler Lesebefehl \n");
goto error;
}
for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
len > 0;
len--)
{
if (len == 1)
twcr = _BV(TWINT) | _BV(TWEN); /* NAK setzen */
TWCR = twcr; /* Interrupt fuer Uebertragung ruecksetzen */
while ((TWCR & _BV(TWINT)) == 0) ; /* Warte auf Uebertragung */
switch ((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
break; /* Schleife beenden */
case TW_MR_DATA_ACK:
erg = TWDR; /* Ausgaben */
rv++;
break;
default:
printf("Fehler Datenerhalt \n");
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* Stop-Bedingung */
return rv;
error:
printf("Fehler Routinenausgang mit rv-Satus = %d .",rv);
rv = -1;
goto quit;
}
/************************************************** ************************************************** *
* Verzoegerung (Wartezeit) *
* *
************************************************** ************************************************** */
void ms_sleep(uint16_t ms)
{
TCNT0 = 0;
ms_count = 0;
while (ms_count < ms)
;
}
/************************************************** ************************************************** *
* Millisekundenzaehler fuer Unterbrechung *
* *
************************************************** ************************************************** */
SIGNAL(SIG_OUTPUT_COMPARE0)
{
ms_count++;
}
/************************************************** ************************************************** *
* Timer0 initialisieren um den Quarzkristall und den Output-Compare-Interrupt *
* zu benutzen - auf diese Weise erfolgt eine Unterbrechung etwa einmal pro 1 ms. *
* *
************************************************** ************************************************** */
void init_timer0(void)
{
TCCR0 = 0;
TIFR |= BV(OCIE0)|BV(TOIE0);
TIMSK |= BV(TOIE0)|BV(OCIE0); /* enable output compare interrupt */
TCCR0 = BV(WGM01)|BV(CS02)|BV(CS00); /* CTC, prescale = 128 */
TCNT0 = 0;
OCR0 = OCR_1MS; /* match in aprox 1 ms */
}
/************************************************** ************************************************** *
* Fehler *
* *
************************************************** ************************************************** */
void
error(void)
{
printf("error: TWI status %#x\n", twst);
//exit(0); // Unterbrechen des Programms --> Ende
}
/************************************************** ************************************************** *
* Main *
* *
************************************************** ************************************************** */
void main(void)
{
uint16_t a = 0;
int rv;
int regnr;
int addr = 0xe0;
init_timer0();
ioinit();
sei();
fdevopen(uart_putchar, NULL, 0);
ms_sleep(500);
rv = sfr_schreiben(0x00, 0x01, 0x06);
ms_sleep(100);
rv = sfr_schreiben(0x00, 0x02, 0x4a);
ms_sleep(100);
for(;;){
rv = sfr_schreiben(0x00, 0x00, 0x51);
ms_sleep(40);
printf("Sensor %d ", addr);
for(regnr = 3; regnr < 4; ){
rv = sfr_lesen(addr, regnr);
if (rv <= 0)
error();
if (rv < 1)
printf("warning: short read %d\n", rv);
dtostrf(erg,7,3,buf);
printf("Reg. %d ", regnr);
printf("Wert: ");
usartprint(buf,8);
regnr++;
}
printf("\n");
}
putchar('\n');
a++;
printf("Messung %d beendet \n \n ", a);
}
Ich bekomme als Ausgabe folgendes:
nsor 224 Reg. 3 Wert: se}KyaM
Sensor 224 Reg. 3 Wert: se}KyaM
Sensor 224 Reg. 3 Wert: se}KyaM
Könnte es sein, dass irgendwas mit dem US nicht stimmt? Irgendwie bekomme ich keine vernünftigen werte...