Forum: Mikrocontroller und Digitale Elektronik AVR Studio 6 undefined reference Fleury I2C Libary


von Johannes (Gast)


Lesenswert?

Hi,

ich möchte in Atmel Studio 6 die I2C Lib von P.Fleury einbinden.

Ich habe dazu die i2cmaster.h und twimaster.c in die Quellen zur 
Solution hinzugefügt. Die beiden Dateien liegen im gleichen Verzeichnis 
wie meine main.c

Leider bekomme ich beim Build Prozess immer folgende Fehlermeldung und 
komme nicht weiter:

Error  8  undefined reference to `i2c_Write'

Das Programm sieht zum testen erstmal so aus:

#define F_CPU 18432000UL /* evtl. bereits via Compilerparameter 
definiert */
#define BAUD 9600UL

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdint.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <stdbool.h>

#include "can.h"
#include "i2cmaster.h"

#include "rtc.h"
//#include "pcf8574.h"



#define HT16K33 0x70 //Datenblatt
#define HT16K33 0xE0 //Peter Fleury <i2cmaster.h> Adresse mit 8 Bit 
incl. R/_W Bit. x 2 = 0xE0.


void init_pgm()
{
i2c_init();
}

void I2C_WriteRegister(uint8_t busAddr, uint8_t deviceRegister, uint8_t 
data) {
  i2c_Start(busAddr); // send bus address
  i2c_Write(deviceRegister); // first byte = device register address
  i2c_Write(data); // second byte = data for device register
  I2C_Stop();
}

void Test()
{
  //16 segments (ROW=active high when displaying) and 8 commons 
(COM=active low when displaying)
  //ROW/INT Set Register == ROW
  //1010XXX0=A0(10100000)
  //I2C_WriteByte(HT16K33, 0xA0);//== ROW (optional) only needed if used 
as INT before
  I2C_WriteRegister(HT16K33, 0, 0xFF);//COM0
  I2C_WriteRegister(HT16K33, 1, 0xFF);//COM0
  I2C_WriteRegister(HT16K33, 2, 0xFF);//COM1
  I2C_WriteRegister(HT16K33, 3, 0xFF);//COM1
  I2C_WriteRegister(HT16K33, 4, 0xFF);//COM2
  I2C_WriteRegister(HT16K33, 5, 0xFF);//COM2
  I2C_WriteRegister(HT16K33, 6, 0xFF);//COM3
  I2C_WriteRegister(HT16K33, 7, 0xFF);//COM3
  I2C_WriteRegister(HT16K33, 8, 0xFF);//COM4
  I2C_WriteRegister(HT16K33, 9, 0xFF);//COM4
  I2C_WriteRegister(HT16K33, 0xA, 0xFF);//COM5
  I2C_WriteRegister(HT16K33, 0xB, 0xFF);//COM5
  I2C_WriteRegister(HT16K33, 0xC, 0xFF);//COM6
  I2C_WriteRegister(HT16K33, 0xD, 0xFF);//COM6
  I2C_WriteRegister(HT16K33, 0xE, 0xFF);//COM7
  I2C_WriteRegister(HT16K33, 0xF, 0xFF);//COM7
}



int main(void)
{
  init_pgm();

  Test();



    while(1)
    {
        //TODO:: Please write your application code
    }
}


Was mache ich falsch? Wie sage ich AVR Studio das es die twimaster.c 
nutzen soll? Die.s Datei ist nicht mehr in der solution eingebunden, die 
der Hardware TWI des Mega644p genutzt werden soll.

von Sebastian S. (amateur)


Lesenswert?

Ich habe zwar keine Ahnung, aber musst Du nicht:
Entweder twimaster.h UND twimaster.c
oder     i2cmaster.h UND i2cmaster.c
verwenden?

von guest (Gast)


Lesenswert?

Sebastian S. schrieb:
> Ich habe zwar keine Ahnung

Richtig!
Bevor Du Mist postest, entweder RTFM oder Klappe halten.
Es gibt nur einen Header "i2cmaster.h". Der gilt für beide Varianten, 
sowohl für "i2cmaster.S", als auch für "twimaster.c"

Johannes schrieb:
> Wie sage ich AVR Studio das es die twimaster.c
> nutzen soll?

Einfach dem Projekt (nicht Solution!) hinzufügen.

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Ich glaube ich hab es sogar dem Projekt hinzugefügt. Trotzdem 
funktioniert es nicht :(

von htpcler (Gast)


Lesenswert?

Oder fragen wir mal so ab:

Wo ist i2c_Write definiert ?

Ist das in
#include "i2cmaster.h"

irgendwie referenced?
das heißt, ob in der #include "i2cmaster.h" wiederum #include "***.h" 
steht wo diese Funktion definiert ist?

von guest (Gast)


Lesenswert?

htpcler schrieb:
> irgendwie referenced?
> das heißt, ob in der #include "i2cmaster.h" wiederum #include "***.h"
> steht wo diese Funktion definiert ist?

Man hätte auch einfach mal nachschauen können:
in "i2cmaster.h":
1
extern void i2c_start_wait(unsigned char addr);
und in "twimaster.c":
1
unsigned char i2c_write( unsigned char data )
2
{  
3
    uint8_t   twst;
4
    
5
  // send data to the previously addressed device
6
  TWDR = data;
7
  TWCR = (1<<TWINT) | (1<<TWEN);
8
9
  // wait until transmission completed
10
  while(!(TWCR & (1<<TWINT)));
11
12
  // check value of TWI Status Register. Mask prescaler bits
13
  twst = TW_STATUS & 0xF8;
14
  if( twst != TW_MT_DATA_ACK) return 1;
15
  return 0;
16
17
}

von Oliver S. (oliverso)


Lesenswert?

Johannes schrieb:
> Ich glaube ich hab es sogar dem Projekt hinzugefügt. Trotzdem
> funktioniert es nicht :(

Dann zeig doch mal, wo.

Oliver

von guest (Gast)


Lesenswert?

Johannes schrieb:
> Ich glaube ich hab es sogar dem Projekt hinzugefügt.

In dem Screenshot ist es aber nicht zu sehen. Ist "bttf-clock" ein 
Projekt oder ein Ordner, das Icon sieht etwas eigenartig aus, hab aber 
grad kein AVRStudio da um selber nachzusehen.

Du könntest aber auch mal im Compiler-Output schauen, ob die 
"twimaster.c" überhaupt mit kompiliert wird.

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Ist dann ganz unten in der Liste mit drin.

Hier ist der compiler Output:

------ Build started: Project: bttf-clock, Configuration: Debug AVR 
------
Build started.
Project "bttf-clock.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; 
('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Atmel Studio 
6.1\Vs\Compiler.targets" from project 
"Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.cproj" 
(target "Build" depends on it):
  Task "RunCompilerTask"
    C:\Program Files (x86)\Atmel\Atmel Studio 6.1\shellUtils\make.exe 
all
    Building file: .././bttf-clock.c
    Invoking: AVR/GNU C Compiler : 3.4.4
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 
GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-gcc.exe"  -funsigned-char 
-funsigned-bitfields -DDEBUG  -I".."  -O1 -ffunction-sections 
-fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega644p 
-c -std=gnu99 -MD -MP -MF "bttf-clock.d" -MT"bttf-clock.d" 
-MT"bttf-clock.o"   -o "bttf-clock.o" ".././bttf-clock.c"
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(34,0): 
"HT16K33" redefined [enabled by default]
     #define HT16K33 0xE0 //Peter Fleury <i2cmaster.h> Adresse mit 8 Bit 
incl. R/_W Bit. x 2 = 0xE0.
     ^
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(33,0): 
this is the location of the previous definition
     #define HT16K33 0x70 //Datenblatt
     ^
    .././bttf-clock.c: In function 'I2C_WriteRegister':
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(43,2): 
implicit declaration of function 'i2c_Start' 
[-Wimplicit-function-declaration]
      i2c_Start(busAddr); // send bus address
      ^
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(44,2): 
implicit declaration of function 'i2c_Write' 
[-Wimplicit-function-declaration]
      i2c_Write(deviceRegister); // first byte = device register address
      ^
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(46,2): 
implicit declaration of function 'I2C_Stop' 
[-Wimplicit-function-declaration]
      I2C_Stop();
      ^
    Finished building: .././bttf-clock.c
    Building target: bttf-clock.elf
    Invoking: AVR/GNU Linker : 3.4.4
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 
GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-gcc.exe" -o 
bttf-clock.elf  bttf-clock.o rtc.o twimaster.o 
-Wl,-Map="bttf-clock.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group 
-Wl,-L".."  -Wl,--gc-sections -mmcu=atmega644p -lm
    bttf-clock.o: In function `I2C_WriteRegister':
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\Debug/.././bttf-clock 
.c(43,1):  undefined reference to `i2c_Start'
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\Debug/.././bttf-clock 
.c(44,1):  undefined reference to `i2c_Write'
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\Debug/.././bttf-clock 
.c(45,1):  undefined reference to `i2c_Write'
Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\Debug/.././bttf-clock 
.c(46,1):  undefined reference to `I2C_Stop'
collect2.exe(0,0): ld returned 1 exit status
    make: *** [bttf-clock.elf] Error 1
    The command exited with code 2.
  Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "bttf-clock.cproj" -- 
FAILED.
Done building project "bttf-clock.cproj" -- FAILED.

Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped 
==========

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
> Error  8  undefined reference to `i2c_Write'

guest schrieb:
> und in "twimaster.c":
> unsigned char i2c_write( unsigned char data )

Warum schreibt der TO "i2c_Write" mit großem "W", wo es doch in 
twimaster.c mit kleinem "w" geschrieben ist?

Vermutlich ist der aufrufende Code auch irgendwo kopiert worden, ohne zu 
prüfen, ob er überhaupt für die Fleury-Lib geeignet ist.

von Tr.oll (Gast)


Lesenswert?

Frank M. schrieb:
> Vermutlich ist der aufrufende Code auch irgendwo kopiert worden, ohne zu
> prüfen, ob er überhaupt für die Fleury-Lib geeignet ist.

Das Übliche halt.

Jemand meint dass es reicht die Copy- und die Paste-Taste
drücken zu können, und natürlich die Maus-Taste ....

von Tr.oll (Gast)


Lesenswert?

Sicherlich muss man der Source

bttf-clock.c

auch mal per include mitteilen wo denn die I2C-Routinen
zu finden sein sollen.

von guest (Gast)


Lesenswert?

Frank M. schrieb:
> Warum schreibt der TO "i2c_Write" mit großem "W", wo es doch in
> twimaster.c mit kleinem "w" geschrieben ist?

Das hab ich doch glatt übersehen. Das kommt halt davon, wenn jemand nur 
Bruchteile der Fehlermeldung postet.
Das hier hätte einem schon viel früher zu Denken gegeben:

Johannes schrieb:
> Z:\immekeppel\atmel\bttf_clock\programm\bttf-clock\bttf-clock.c(43,2):
> implicit declaration of function 'i2c_Start'

von Johannes (Gast)


Lesenswert?

Danke, das war das Problem. Ich war mir gar nicht bewusst, dass das 
unter Win mit AVR Studio ein Problem sein könnte.

Übrigends ist das HT16K33 Programmd as Beispielprogramm hier von der 
Seite;) Da sollte man vielleicht das Beispiel mal anpassen...

von htpcler (Gast)


Lesenswert?

guest schrieb:
> htpcler schrieb:
>> irgendwie referenced?
>> das heißt, ob in der #include "i2cmaster.h" wiederum #include "***.h"
>> steht wo diese Funktion definiert ist?
>
> Man hätte auch einfach mal nachschauen können:
> in "i2cmaster.h":extern void i2c_start_wait(unsigned char addr);
> und in "twimaster.c":unsigned char i2c_write( unsigned char data )
> {
>     uint8_t   twst;
>
>   // send data to the previously addressed device
>   TWDR = data;
>   TWCR = (1<<TWINT) | (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_MT_DATA_ACK) return 1;
>   return 0;
>
> }

Ich konnte sein Projekt nicht 1 zu 1 nachzaubern...
Letztendlich sollte man immer sauber, ordentlich und strukturiert 
arbeiten. Sonst kommen Fehler und / oder man verliert im Projekt schnell 
die Übersicht.
Es handelt sich hier um einen blutigen Anfänger alles schnell kopieren 
und klick klick feuer!
Arbeite doch erst mal echte Tut's durch nach Lehrbuch.
Verschaffe Dir Übersicht und arbeite sauberer, diese doxy files haben da 
doch nix zu suchen???

von Oliver S. (oliverso)


Lesenswert?

Johannes schrieb:
> Danke, das war das Problem. Ich war mir gar nicht bewusst, dass das
> unter Win mit AVR Studio ein Problem sein könnte.

Das sollte allerdings unter jedem Betriebssystem und für jeden Prozessor 
ein „Problem“ sein. C ist halt C, egal, wo und wie.

Oliver

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.