- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 3 von 3

Thema: SRF02 am Atmega8

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.08.2007
    Ort
    Delmenhorst
    Alter
    39
    Beiträge
    731

    SRF02 am Atmega8

    Anzeige

    Powerstation Test
    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.

    Code:
    //-------------------------------------------------------------------------
    // 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
    }

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.03.2010
    Beiträge
    161
    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?

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.03.2010
    Beiträge
    161
    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:
    Code:
    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.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests