PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SRF02 am Atmega8



KingTobi
10.10.2009, 20:49
Hi

Ich habe einen SRF02 der sich nicht so recht ansteuern lassen will, aber warum?
Ich bekomme immer die selben Werte.
Die Buchstaben die ausgegeben werden zeigen nur an was er schon gemacht hat.
Ein Großteil des Codes ist automatisch erstellt.



//-------------------------------------------------------------------------
// Titel :
//-------------------------------------------------------------------------
// Funktion :
// Schaltung :
//-------------------------------------------------------------------------
// Prozessor : ATmega8
// Takt : 4000000 Hz
// Sprache : C
// Datum : 10.10.2009
// Version : 1.0
// Autor :
// Programmer:
// Port :
//-------------------------------------------------------------------------
// created by myAVR-CodeWizard
//-------------------------------------------------------------------------
//
#define F_CPU 4000000
#include <avr\io.h>
#include <compat/deprecated.h>

#include <stdio.h>
#include <stdlib.h>

void lcdZahl();
//---------------------------------------------------------------------------------
// TWI-Funktionssammlung
//---------------------------------------------------------------------------------
#ifndef TWI_CLOCK
#define TWI_CLOCK 100000 // Geschwindigkeit des TWI-Busses
#endif
// TWCR - Control-Register-Bits
#define _TWINT 0b10000000
#define _TWEA 0b01000000
#define _TWSTA 0b00100000
#define _TWSTO 0b00010000
#define _TWWC 0b00001000
#define _TWEN 0b00000100
#define _TWIE 0b00000001
#include <util\delay.h>

//------------------------------------------------------------------------
// twiInitMaster
//------------------------------------------------------------------------
void twiInitMaster(uint8_t twiAdr)
{
// Clock
TWBR=((F_CPU/TWI_CLOCK)-16)*2;
// TWI-Status-Register (Vorteiler)
TWSR=0;
// Bus-Addr
TWAR=twiAdr;
// Enable
TWCR=_TWINT|_TWEN;
}
//------------------------------------------------------------------------
// Start TWI (ohne Interrupt)
//------------------------------------------------------------------------
void twiStart()
{
uint8_t x=TWCR;
x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N
TWCR=x|_TWINT|_TWSTA;
// warten bis fertig
while( !(TWCR & _TWINT))
{}
}
//------------------------------------------------------------------------
// Stopp TWI (ohne Interrupt)
//------------------------------------------------------------------------
void twiStop()
{
uint8_t x=TWCR;
x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N
TWCR=x|_TWINT|_TWSTO;
}
//------------------------------------------------------------------------
// Write Byte per TWI (ohne Interrupt)
// PE: data = zu sendende Daten
// ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt
//------------------------------------------------------------------------
void twiWriteByte(uint8_t data, uint8_t ackn)
{
TWDR=data; // Daten bereitlegen
// Befehl zusammenstellen
uint8_t x=TWCR;
x&=_TWEN|_TWIE; //nur Beibehalten von Enable und InterruptJ/N
x|=_TWINT;
if(ackn)
x|=_TWEA; // evt. TWEA setzen, für Datenanforderung
TWCR=x; // senden
// warten bis fertig
while( !(TWCR & _TWINT))
{}
}
//------------------------------------------------------------------------
// Read Byte per TWI (ohne Interrupt)
// PE: ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt
// PA: Data
//------------------------------------------------------------------------
int twiReadByte(uint8_t ackn)
{
// Befehl zusammenstellen
uint8_t x=TWCR;
x&=_TWEN|_TWIE; //nur Beibehalten von Enable und InterruptJ/N
x|=_TWINT;
if(ackn)
x|=_TWEA; // evt. TWEA setzen, für Datenanforderung
TWCR=x; // senden
// warten bis fertig
while( !(TWCR & _TWINT))
{}
return TWDR;
}


/////////////////////////////////////////////////////////////////////////////
// Main-Funktion
/////////////////////////////////////////////////////////////////////////////
main()
{
unsigned int h = 0;
unsigned int l = 0;

char ch[10]="\0";
char cl[10]="\0";

lcdInit(); // Initialisierungen
lcdString("A");

twiInitMaster(0xE0);

lcdString("B");

twiStart();
twiWriteByte(0xE0,0);
twiWriteByte(0,0);
twiWriteByte(81,0);
twiStop();
lcdString("C");

for(int i=0; i<100; i++)
waitMs(1);

twiStart();
twiWriteByte(0xE0,0);
twiWriteByte(2,0);
twiStop();
lcdString("D");

twiStart();
twiWriteByte(0xE0+1,0);
h=twiReadByte(1);
l=twiReadByte(0);
twiStop();
lcdString("E");

itoa(h, ch, 10);
lcdString(ch);
itoa(l, cl, 10);
lcdString(cl);

while (true) // Mainloop-Begin
{
//...
} // Mainloop-Ende
}

s.frings
07.06.2010, 17:30
Ich lese mit meinem eigenen Source immer nur den Wert 0, was auch nicht stimmen kann. Was zeigt denn die Status-LED des Moduls bei Dir an?

s.frings
08.06.2010, 11:01
Beim Initialisieren gibst Du dem AVR die gleiche Adresse, die auch dein Sensor hat. Ich bin nicht sicher, ob dies Deinen Fehler auslöst. In meinem Source lasse ich dieses Register im Default Zustand.

Ich sehe in Deinem Source sonst keinen Fehler. Ich habe meinen Sensor inzwischen ans Laufen bekommen, mein Fehler war, dass ich als Befehl 0x81 anstatt 81 gesendet hatte.

Versuch mal meinen Source:


void i2c_init() {
// I2C Bus ca. 100khz Taktfrequenz
TWBR=75;
}

uint8_t i2c_write(uint8_t slave_id, uint8_t address, uint8_t data) {
// Sende START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
uint8_t status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors
TWDR=slave_id;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x18) goto error;
// Sende Register Nummer
TWDR=address;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende Befehl (Messen in Zentimeter)
TWDR=data;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 0;

error:
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 255;
}


uint8_t i2c_read(uint8_t slave_id, uint8_t address) {
uint8_t result=0;
// Sende START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
uint8_t status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors
TWDR=slave_id;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x18) goto error;
// Sende Register Nummer
TWDR=address;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende wiederholt START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors (read mode)
TWDR=slave_id+1;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x40) goto error;
// lese ein Byte ohne ACK
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x58) goto error;
result=TWDR;
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return result;

error:
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 255;
}

uint16_t distance() {
// Sende Ping Befehl
i2c_write(0xE0,0,81);
// Warte, bis Ergebnis verfügbar ist
while (i2c_read(0xE0,0)==255);
// Lese das Ergebnis aus
return (uint16_t) i2c_read(0xE0,2)*255 +i2c_read(0xE0,3);
}


Ich habe einen ATmega16 mit 15Mhz verwendet.