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


von gustav_gans (Gast)


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-software.html#libs
Das Programm soll die Slave-ID von einem SRF02 ändern.
1
#include <avr/io.h>          //Library für die AVR-Register
2
#include <util/delay.h>       //Warteschleifen für die Wartezeit von 50ms
3
                  //zwischen den Schreibzyklen
4
#include "i2cmaster.h"         //I²C-Master Library aus dem Projektordner
5
6
                  
7
#define F_CPU 16000000UL      //16Mhz Quarzfrequenz
8
9
#define SCL_CLOCK  100000L      //I²C-Takt festlegen
10
11
#define SRF02_1 0xE0        //Standard Slave-ID des SRF02
12
#define SRF02_2 0xE2        //Neue Slave-ID
13
14
int main ()              //Hauptprogramm
15
{
16
  unsigned char ret;        //Return-Variable
17
    
18
    DDRB=0xff;                     //PortB als Output definieren
19
    PORTB=0xff;                     //LEDs sind Low-Aktiv, sollen zu Beginn nicht leuchten
20
21
    i2c_init();           //I²C initialisieren
22
  ret=i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus setzen
23
  if (ret)             //Startbedingung fehlgeschlagen
24
  {                //(Eventuell kein Teilnehmer am I²C-Bus) =>
25
        i2c_stop();          //I²C-Bus wieder freigeben
26
        PORTB=0x00;                 //und alle LEDs aktivieren => Fehler
27
    }
28
  else 
29
  {                //Startbedingung OK
30
        i2c_write(0x00);            //Register0
31
        i2c_write(0xA0);            //erster Wert zum ändern der Slave-ID
32
        i2c_stop();                 //Bus freigeben
33
34
      _delay_ms(50);        //50ms warten, wie im DB angegeben
35
36
    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
37
        i2c_write(0x00);            //Register0
38
        i2c_write(0xAA);            //zweiter Wert zum ändern der Slave-ID
39
        i2c_stop();                 //Bus freigeben
40
41
      _delay_ms(50);        //wieder 50ms warten, wie im DB angegeben
42
43
    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
44
        i2c_write(0x00);            //Register0
45
        i2c_write(0xA5);            //dritter Wert zum ändern der Slave-ID
46
        i2c_stop();                 //Bus freigeben
47
48
      _delay_ms(50);        //wieder 50ms warten, wie im DB angegeben
49
50
    i2c_start(SRF02_1+I2C_WRITE);  //Slave-ID und Schreibmodus
51
        i2c_write(0x00);            //Register0
52
        i2c_write(SRF02_2);         //neue Slave-ID des SRF02
53
        i2c_stop();                 //Bus freigeben
54
    }
55
}

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

von Karl H. (kbuchegg)


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_hab_da_mehrere_.2A.c_und_.2A.h_Dateien._Was_mache_ich_damit.3F


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.

von gustav_gans (Gast)


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

von gustav_gans (Gast)


Lesenswert?

Hallo,

Ich habe das Programm gerade auf den Mikrocontroller gespielt und dabei 
festgestellt, dass es sich in der i2c_start Funktion aufhängt.
1
/*************************************************************************  
2
  Issues a start condition and sends address and transfer direction.
3
  return 0 = device accessible, 1= failed to access device
4
*************************************************************************/
5
unsigned char i2c_start(unsigned char address)
6
{
7
    uint8_t   twst;
8
9
  // send START condition
10
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
11
12
  // wait until transmission completed
13
  while(!(TWCR & (1<<TWINT)));
14
15
  // check value of TWI Status Register. Mask prescaler bits.
16
  twst = TW_STATUS & 0xF8;
17
  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
18
19
  // send device address
20
  TWDR = address;
21
  TWCR = (1<<TWINT) | (1<<TWEN);
22
23
  // wail until transmission completed and ACK/NACK has been received
24
  while(!(TWCR & (1<<TWINT)));
25
26
  // check value of TWI Status Register. Mask prescaler bits.
27
  twst = TW_STATUS & 0xF8;
28
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
29
30
  return 0;
31
32
}/* 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?

von gustav_gans (Gast)


Lesenswert?

Hab das Programm gerade simuliert, der Mega32 bleibt in der ersten 
while-Schleife hängen.
1
  // wait until transmission completed
2
  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?

von ... .. (docean) Benutzerseite


Lesenswert?

i2c lässt sich nicht simulieren...

von gustav_gans (Gast)


Lesenswert?

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

von gustav_gans (Gast)


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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.