mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit Winavr und fremder library


Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe hier ein kleines Problem mit WinAVR. Ich verwende die 
I2C-Master Library von Peter Fleury: 
http://homepage.hispeed.ch/peterfleury/avr-softwar...
Das Programm soll die Slave-ID von einem SRF02 ändern.
#include <avr/io.h>          //Library für die AVR-Register
#include <util/delay.h>       //Warteschleifen für die Wartezeit von 50ms
                  //zwischen den Schreibzyklen
#include "i2cmaster.h"         //I²C-Master Library aus dem Projektordner

                  
#define F_CPU 16000000UL      //16Mhz Quarzfrequenz

#define SCL_CLOCK  100000L      //I²C-Takt festlegen

#define SRF02_1 0xE0        //Standard Slave-ID des SRF02
#define SRF02_2 0xE2        //Neue Slave-ID

int main ()              //Hauptprogramm
{
  unsigned char ret;        //Return-Variable
    
    DDRB=0xff;                     //PortB als Output definieren
    PORTB=0xff;                     //LEDs sind Low-Aktiv, sollen zu Beginn nicht leuchten

    i2c_init();           //I²C initialisieren
  ret=i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus setzen
  if (ret)             //Startbedingung fehlgeschlagen
  {                //(Eventuell kein Teilnehmer am I²C-Bus) =>
        i2c_stop();          //I²C-Bus wieder freigeben
        PORTB=0x00;                 //und alle LEDs aktivieren => Fehler
    }
  else 
  {                //Startbedingung OK
        i2c_write(0x00);            //Register0
        i2c_write(0xA0);            //erster Wert zum ändern der Slave-ID
        i2c_stop();                 //Bus freigeben

      _delay_ms(50);        //50ms warten, wie im DB angegeben

    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
        i2c_write(0x00);            //Register0
        i2c_write(0xAA);            //zweiter Wert zum ändern der Slave-ID
        i2c_stop();                 //Bus freigeben

      _delay_ms(50);        //wieder 50ms warten, wie im DB angegeben

    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
        i2c_write(0x00);            //Register0
        i2c_write(0xA5);            //dritter Wert zum ändern der Slave-ID
        i2c_stop();                 //Bus freigeben

      _delay_ms(50);        //wieder 50ms warten, wie im DB angegeben

    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
        i2c_write(0x00);            //Register0
        i2c_write(SRF02_2);         //neue Slave-ID des SRF02
        i2c_stop();                 //Bus freigeben
    }
}

Wenn ich nun auf Build klicke, erhalte ich für jeden i2c_start, 
i2c_write und 12c_stop folgende Fehlermeldung:
C:\****\avr-projekte\005_i2c\default/../005_i2c.c:29: undefined 
reference to `i2c_init'
Ansonsten erhalte ich keine Warnungen oder Fehlermeldungen.

Die Header-Datei ist im Projektordner und auch eingebunden, oder habe 
ich da jetzt noch etwas falsch gemacht? Ich finde nämlich keinen Fehler, 
außerdem habe ich alles genauso wie im Beispielprogramm gemacht, also 
sollte das doch passen. Ich habe bisher nur Assembler programmiert, also 
kenn ich mich mit C noch nicht so sehr aus...

mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gustav_gans schrieb:

> Wenn ich nun auf Build klicke, erhalte ich für jeden i2c_start,
> i2c_write und 12c_stop folgende Fehlermeldung:
> C:\****\avr-projekte\005_i2c\default/../005_i2c.c:29: undefined
> reference to `i2c_init'

das kommt vom Linker, der aus den Einzelteilen das komplette Programm 
zusammenbaut

> Die Header-Datei ist im Projektordner und auch eingebunden,

Das ist schon mal was.
Aber zu wenig.
Vom P.Fleury hast du auch ein c-File bekommen.
Das musst du zu deinem Projekt hinzufügen.

http://www.mikrocontroller.net/articles/FAQ#Ich_ha...


Anders als in Assembler, kann ein C-Projekt aus mehreren unabhängigen 
C-Files bestehen, die alle einzeln kompiliert werden und dann vom Linker 
zum Programm zusammengefasst werden. Aber schau in den Link.

Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AH, das wars, vielen Dank.
Ich hatte die .c-Datei nicht ins Projekt eingebunden, im Ordner war sie 
ja vorhanden.
Jetzt muss ich das Programm nur noch testen. :)

mfg

Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe das Programm gerade auf den Mikrocontroller gespielt und dabei 
festgestellt, dass es sich in der i2c_start Funktion aufhängt.
/*************************************************************************  
  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;

  // 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)) 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)));

  // check value of TWI Status Register. Mask prescaler bits.
  twst = TW_STATUS & 0xF8;
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

  return 0;

}/* i2c_start */

Nach langem suchen und überlegen weiß ich noch immer nicht, wo und wieso 
es das tut. könnte mir da jemand vielleicht helfen?

Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab das Programm gerade simuliert, der Mega32 bleibt in der ersten 
while-Schleife hängen.
  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));

Ich habe gerade ein anderes I2C-Testprogramm, welches die selbe Library 
verwendet und auch schon auf einem Mega32 funktionierte, durchsimuliert 
und es bleibt in der selben Schleife hängen. Verschiedene 
Optimierungsgrade beim kompilieren konnten das auch nicht ändern. Weiß 
vielleicht jemand, wieso das so ist?

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
i2c lässt sich nicht simulieren...

Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, wusste ich nicht.
Der Controller kommt trotzdem nicht über die i2c_start-Funktion hinweg, 
er bleibt dort drinnen hängen.

Autor: gustav_gans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wäre es auch möglich, dass der Wert der PullUp-Widerstände zu groß/zu 
klein ist und deswegen keine Start-Bedingung vom Slave erkannt wird? 
Oder müsste da nicht die Fehlermeldung kommen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.