PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : rnbfra1.1 und i2c



jagdfalke
12.03.2007, 23:48
Hi,
ich versuche zur Zeit das Bascom-Beispiel in dem die LEDs zum leuchten gebracht werden in gcc zu portieren. Ich habe schon was angefangen und bekomme auch nen Fehler beim compilieren aber mittlerweile bin ich mir nicht mehr sicher ob ich die ic2master.h oder die twimaster.c benutzen muss. Am besten jemand beantwortet mir erstmal das bevor ich die Fehlermeldung poste.

mfg
jagdfalke

jagdfalke
13.03.2007, 11:22
okaay, da sich hier scheinbar alle kategorisch weigern mir mit gcc weiterzuhelfen probier ichs nochmal:


#include <avr/io.h>

#include "i2cmaster.h"

#define POWER_PORTS_I2C 0x72

int main(void) {
i2c_init();
uint8_t ret;
ret = i2c_start(POWER_PORTS_I2C + I2C_WRITE);
if ( ret ) {

i2c_stop();
} else {
uint8_t value;
value = 1;
while(1) {
i2c_start_wait(POWER_PORTS_I2C + I2C_WRITE);
i2c_write(value);
i2c_stop();
value = value * 2;
if(value > 16) {
value = 1;
}
}
}
}

Warum kann der Code nicht compilieren?


mathias@mathias-laptop:~/Desktop/avr.programing/avr-gcc/mytest$ make

-------- begin --------
avr-gcc (GCC) 4.1.0
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Linking: LED_Test.elf
avr-gcc -mmcu=atmega32 -I. -gstabs -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=LED_Test.o -std=gnu99 -Wundef -MMD -MP -MF .dep/LED_Test.elf.d LED_Test.o --output LED_Test.elf -Wl,-Map=LED_Test.map,--cref -lm
LED_Test.o: In function `main':
LED_Test.c:15: undefined reference to `i2c_init'
LED_Test.c:17: undefined reference to `i2c_start'
LED_Test.c:25: undefined reference to `i2c_start_wait'
LED_Test.c:26: undefined reference to `i2c_write'
LED_Test.c:27: undefined reference to `i2c_stop'
LED_Test.c:25: undefined reference to `i2c_start_wait'
LED_Test.c:26: undefined reference to `i2c_write'
LED_Test.c:27: undefined reference to `i2c_stop'
LED_Test.c:25: undefined reference to `i2c_start_wait'
LED_Test.c:26: undefined reference to `i2c_write'
LED_Test.c:27: undefined reference to `i2c_stop'
LED_Test.c:25: undefined reference to `i2c_start_wait'
LED_Test.c:26: undefined reference to `i2c_write'
LED_Test.c:27: undefined reference to `i2c_stop'
LED_Test.c:19: undefined reference to `i2c_stop'
make: *** [LED_Test.elf] Fehler 1


Woran liegt das? Die Methoden liegen in i2cmaster.h, was ja auch included ist.

linux_80
13.03.2007, 18:52
Hallo,

da gehört bestimmt auch eine .c-Datei dazu, die muss mitcompiliert werden, sonst gibts die Funktionen nicht.
Dazu muss diese Datei im Makefile mit dabeistehen, dort wo LED_Test auch steht.

Wenn du das AVRStudio benutzt, die Dateien auf der linken Seite einfach hinzufügen, dann werden die mitcompiliert.
Mit der rechten Maustaste auf Source- bzw. HeaderFiles clicken.

jagdfalke
13.03.2007, 19:00
in dem zip file war ein test-program dabei:


/************************************************** **************************

Title: Access serial EEPROM 24C02 using I2C interace

Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury

File: $Id: test_i2cmaster.c,v 1.2 2003/12/06 17:07:18 peter Exp $

Software: AVR-GCC 3.3

Hardware: AT90S8515 at 4 Mhz, any AVR device can be used



Description:

This example shows how the I2C library i2cmaster.S can be used to

access a serial eeprom.

Based on Atmel Application Note AVR300, adapted to AVR-GCC C interface



************************************************** ***************************/

#include <avr/io.h>

#include "i2cmaster.h"





#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet





int main(void)

{

unsigned char ret;





DDRB = 0xff; // use all pins on port B for output

PORTB = 0xff; // (active low LED's )



i2c_init(); // init I2C interface



/* write 0x75 to eeprom address 0x05 (Byte Write) */

ret = i2c_start(Dev24C02+I2C_WRITE); // set device address and write mode

if ( ret ) {

/* failed to issue start condition, possibly no device found */

i2c_stop();

PORTB=0x00; // activate all 8 LED to show error */

}else {

/* issuing start condition ok, device accessible */

i2c_write(0x05); // write address = 5

i2c_write(0x75); // ret=0 -> Ok, ret=1 -> no ACK

i2c_stop(); // set stop conditon = release bus



/* write ok, read value back from eeprom address 0x05, wait until

the device is no longer busy from the previous write operation */

i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode

i2c_write(0x05); // write address = 5

i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode

ret = i2c_readNak(); // read one byte

i2c_stop();



PORTB = ~ret; // output byte on the LED's



/* write 0x70,0x71,072,073 to eeprom address 0x00..0x03 (Page Write),

wait until the device is no longer busy from the previous write operation */

i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode

i2c_write(0x00); // write start address = 0

i2c_write(0x70); // write data to address 0

i2c_write(0x71); // " " " " 1

i2c_write(0x72); // " " " " 2

i2c_write(0x74); // " " " " 3

i2c_stop(); // set stop conditon = release bus



/* write ok, read value back from eeprom address 0..3 (Sequencial Read),

wait until the device is no longer busy from the previous write operation */

i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode

i2c_write(0x00); // write address = 0

i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode

ret = i2c_readAck(); // read one byte form address 0

ret = i2c_readAck(); // " " " " " 1

ret = i2c_readAck(); // " " " " " 2

ret = i2c_readNak(); // " " " " " 3

i2c_stop(); // set stop condition = release bus



PORTB = ~ret; // output byte on the LED's

}



for(;;);

}




das Makefile, das auch dabei war:



# Makefile to compile and link the I2C Master library and test program

#

# based on

# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.

#

# Note:

# The warnings which appear while converting ELF to AVR Extended COFF (make extcoff)

# can be ignored

#

#

# On command line:

#

# make all = Make software.

#

# make clean = Clean out built project files.

#

# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).

#

# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio

# 4.07 or greater).

#

# make program = Download the hex file to the device, using avrdude. Please

# customize the avrdude settings below first!

#

# make filename.s = Just compile filename.c into the assembler code only

#

# To rebuild project do "make clean" then "make all".

#





# MCU name

MCU = at90s8515



# Output format. (can be srec, ihex, binary)

FORMAT = ihex



# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.

# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)

OPT = s





# Target file name (without extension).

TARGET = test_i2cmaster





# List C source files here. (C dependencies are automatically generated.)

SRC = $(TARGET).c



# List Assembler source files here.

# Make them always end in a capital .S. Files ending in a lowercase .s

# will not be considered source files but generated files (assembler

# output from the compiler), and will be deleted upon "make clean"!

# Even though the DOS/Win* filesystem matches both .s and .S the same,

# it will preserve the spelling of the filenames, and gcc itself does

# care about how the name is spelled on its command-line.

ASRC = i2cmaster.S





# List any extra directories to look for include files here.

# Each directory must be seperated by a space.

EXTRAINCDIRS =





# Optional compiler flags.

# -g: generate debugging information (for GDB, or for COFF conversion)

# -O*: optimization level

# -f...: tuning, see gcc manual and avr-libc documentation

# -Wall...: warning level

# -Wa,...: tell GCC to pass this to the assembler.

# -ahlms: create assembler listing

CFLAGS = -g -O$(OPT) \

-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \

-Wall -Wstrict-prototypes \

-Wa,-adhlns=$(<:.c=.lst) \

$(patsubst %,-I%,$(EXTRAINCDIRS))





# Set a "language standard" compiler flag.

# Unremark just one line below to set the language standard to use.

# gnu99 = C99 + GNU extensions. See GCC manual for more information.

#CFLAGS += -std=c89

#CFLAGS += -std=gnu89

#CFLAGS += -std=c99

CFLAGS += -std=gnu99







# Optional assembler flags.

# -Wa,...: tell GCC to pass this to the assembler.

# -ahlms: create listing

# -gstabs: have the assembler create line number information; note that

# for use in COFF files, additional information about filenames

# and function names needs to be present in the assembler source

# files -- see avr-libc docs [FIXME: not yet described there]

ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs







# Optional linker flags.

# -Wl,...: tell GCC to pass this to linker.

# -Map: create map file

# --cref: add cross reference to map file

LDFLAGS = -Wl,-Map=$(TARGET).map,--cref







# Additional libraries



# Minimalistic printf version

#LDFLAGS += -Wl,-u,vfprintf -lprintf_min



# Floating point printf version (requires -lm below)

#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt



# -lm = math library

LDFLAGS += -lm









# Programming support using avrdude. Settings and variables.



# Programming hardware: alf avr910 avrisp bascom bsd

# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500

#

# Type: avrdude -c ?

# to get a full listing.

#

AVRDUDE_PROGRAMMER = stk500





AVRDUDE_PORT = com1 # programmer connected to serial device

#AVRDUDE_PORT = lpt1 # programmer connected to parallel port



AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex

#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep



AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)



# Uncomment the following if you want avrdude's erase cycle counter.

# Note that this counter needs to be initialized first using -Yn,

# see avrdude manual.

#AVRDUDE_ERASE += -y



# Uncomment the following if you do /not/ wish a verification to be

# performed after programming the device.

#AVRDUDE_FLAGS += -V



# Increase verbosity level. Please use this when submitting bug

# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>

# to submit bug reports.

#AVRDUDE_FLAGS += -v -v









# ---------------------------------------------------------------------------



# Define directories, if needed.

DIRAVR = c:/winavr

DIRAVRBIN = $(DIRAVR)/bin

DIRAVRUTILS = $(DIRAVR)/utils/bin

DIRINC = .

DIRLIB = $(DIRAVR)/avr/lib





# Define programs and commands.

SHELL = sh



CC = avr-gcc



OBJCOPY = avr-objcopy

OBJDUMP = avr-objdump

SIZE = avr-size





# Programming support using avrdude.

AVRDUDE = avrdude





REMOVE = rm -f

COPY = cp



HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex

ELFSIZE = $(SIZE) -A $(TARGET).elf







# Define Messages

# English

MSG_ERRORS_NONE = Errors: none

MSG_BEGIN = -------- begin --------

MSG_END = -------- end --------

MSG_SIZE_BEFORE = Size before:

MSG_SIZE_AFTER = Size after:

MSG_COFF = Converting to AVR COFF:

MSG_EXTENDED_COFF = Converting to AVR Extended COFF:

MSG_FLASH = Creating load file for Flash:

MSG_EEPROM = Creating load file for EEPROM:

MSG_EXTENDED_LISTING = Creating Extended Listing:

MSG_SYMBOL_TABLE = Creating Symbol Table:

MSG_LINKING = Linking:

MSG_COMPILING = Compiling:

MSG_ASSEMBLING = Assembling:

MSG_CLEANING = Cleaning project:









# Define all object files.

OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)



# Define all listing files.

LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)



# Combine all necessary flags and optional flags.

# Add target processor to flags.

ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)

ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)







# Default target.

all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \

$(TARGET).lss $(TARGET).sym sizeafter finished end





# Eye candy.

# AVR Studio 3.x does not check make's exit code but relies on

# the following magic strings to be generated by the compile job.

begin:

@echo

@echo $(MSG_BEGIN)



finished:

@echo $(MSG_ERRORS_NONE)



end:

@echo $(MSG_END)

@echo





# Display size of file.

sizebefore:

@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi



sizeafter:

@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi







# Display compiler version information.

gccversion :

@$(CC) --version









# Convert ELF to COFF for use in debugging / simulating in

# AVR Studio or VMLAB.

COFFCONVERT=$(OBJCOPY) --debugging \

--change-section-address .data-0x800000 \

--change-section-address .bss-0x800000 \

--change-section-address .noinit-0x800000 \

--change-section-address .eeprom-0x810000





coff: $(TARGET).elf

@echo

@echo $(MSG_COFF) $(TARGET).cof

$(COFFCONVERT) -O coff-avr $< $(TARGET).cof





extcoff: $(TARGET).elf

@echo

@echo $(MSG_EXTENDED_COFF) $(TARGET).cof

$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof









# Program the device.

program: $(TARGET).hex $(TARGET).eep

$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)









# Create final output files (.hex, .eep) from ELF output file.

%.hex: %.elf

@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@



%.eep: %.elf

@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \

--change-section-lma .eeprom=0 -O $(FORMAT) $< $@



# Create extended listing file from ELF output file.

%.lss: %.elf

@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@



# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@







# Link: create ELF output file from object files.

.SECONDARY : $(TARGET).elf

.PRECIOUS : $(OBJ)

%.elf: $(OBJ)

@echo

@echo $(MSG_LINKING) $@

$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)





# Compile: create object files from C source files.

%.o : %.c

@echo

@echo $(MSG_COMPILING) $<

$(CC) -c $(ALL_CFLAGS) $< -o $@





# Compile: create assembler files from C source files.

%.s : %.c

$(CC) -S $(ALL_CFLAGS) $< -o $@





# Assemble: create object files from assembler source files.

%.o : %.S

@echo

@echo $(MSG_ASSEMBLING) $<

$(CC) -c $(ALL_ASFLAGS) $< -o $@













# Target: clean project.

clean: begin clean_list finished end



clean_list :

@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex

$(REMOVE) $(TARGET).eep

$(REMOVE) $(TARGET).obj

$(REMOVE) $(TARGET).cof

$(REMOVE) $(TARGET).elf

$(REMOVE) $(TARGET).map

$(REMOVE) $(TARGET).obj

$(REMOVE) $(TARGET).a90

$(REMOVE) $(TARGET).sym

$(REMOVE) $(TARGET).lnk

$(REMOVE) $(TARGET).lss

$(REMOVE) $(OBJ)

$(REMOVE) $(LST)

$(REMOVE) $(SRC:.c=.s)

$(REMOVE) $(SRC:.c=.d)





# Automatically generate C source code dependencies.

# (Code originally taken from the GNU make user manual and modified

# (See README.txt Credits).)

#

# Note that this will work with sh (bash) and sed that is shipped with WinAVR

# (see the SHELL variable defined above).

# This may not work with other shells or other seds.

#

%.d: %.c

set -e; $(CC) -MM $(ALL_CFLAGS) $< \

| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \

[ -s $@ ] || rm -f $@





# Remove the '-' if you want to see the dependency files generated.

-include $(SRC:.c=.d)







# Listing of phony targets.

.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \

clean clean_list program






Hier ist als SRC auch nur das eine File eingetragen.


EDIT: Habs raus:
ASRC = i2cmaster.S hat gefehlt.

Hier ist aber schon der nächste Fehler:

mathias@mathias-laptop:~/Desktop/avr.programing/avr-gcc/mytest/led$ make

-------- begin --------
avr-gcc (GCC) 4.1.0
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

make: *** Keine Regel vorhanden, um das Target »LED_Test.elf«,
benötigt von »elf«, zu erstellen. Schluss.


Ich hasse make-files jetzt schon ...

jagdfalke
15.03.2007, 10:57
so ich habe jetzt herausgefunden, dass in twimaster.c ein Fehler war: "#include <i2cmaster.h>" muss "#include "i2cmaster.h"" heißen, da es ja im selber Verzeichnis ist und nicht im include-Verzeichnis. Aber jetzt bekomme ich "multiple definition"-Fehler ...

Kann mir nicht irgendwer helfen?

triplebit
16.03.2007, 14:55
Hallo Jagdfalke,

ich probiers mal. Ich stehe übrigens mit den Make-Files genauso auf Kriegsfuss wie Du!!! Deshalb kann ich Dir bei dem Problem mit dem Kompilieren nicht helfen!!!

Bevor ich meinen Dragon zum debuggen genutzt habe, habe ich KAMAVR benutzt. Der funzt ganz gut, und ist kostenlos.

Seit ich den Dragon habe nutze ich zwangsläufig AVR_Studio, und wenn man sich mal dran gewöhnt hat, ist das auch I.O.

Bei den beiden hast Du den Vorteil das Du Dich mit den MakeFiles net rumschlagen musst.

Was die TWI-Sache anbelangt. Hast DU nen AVR der ein TWI-Interface hat? (Wenn ich die TWIMASTER.h richtig im Kopf habe dann ja)

Ich habe hier die Bibi von Atmel, die ich modifiziert habe. Ich kann die Dir anpassen wenn Du willst. So wie ich das in deinem Code gesehen habe, willst Du einfach nur mal Werte in den Slave schreiben(Was ist das für ein Slave?)

bis dann

Cu

Martin

jagdfalke
16.03.2007, 15:04
Hi,
das ist das rnbfra 1.1 mit atmega32 von robotikhardware.de. Da hängen einige Ports an so einem PCF Baustein, die will ich ansprechen.
Wäre nett wenn du mir da helfen könntest.

triplebit
16.03.2007, 18:04
Hallo Jagdfalke,

da ich nicht weiss was Du genau machen möchtest, lade ich Dir die einzelnen Code-Teile hoch, Du bastelst die dann zusammen. Wenn was net funzt, lade mir bitte deinen kompletten Source-Code hoch.

Die Lösung von Atmel basiert auf der ISR-Routine die aufgerufen wird sobald sich am TWI was getan hat. Hier der Code für die ISR:





ISR(TWI_vect)
{

if (i2c_initiated == 0) return;
switch (TWSR & 0b11111000)
{
//Slave
case TW_SR_GCALL_ACK:
case TW_SR_ARB_LOST_GCALL_ACK:
case TW_SR_SLA_ACK:

case TW_SR_ARB_LOST_SLA_ACK:

TWI_bufPtr = 0;
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_SR_DATA_ACK:
case TW_SR_GCALL_DATA_ACK:
TWI_buf[TWI_bufPtr++] = TWDR;
TWCR = (1<<TWEN)| (1<<TWIE)|(1<<TWINT)| (1<<TWEA);

break;
case TW_SR_STOP:
TWCR = (0<<TWIE);


break;




//Master Transeiver
case TW_START:
case TW_REP_START:

TWI_bufPtr = 0;
case TW_MT_SLA_ACK:
case TW_MT_DATA_ACK:
if (TWI_bufPtr <= TWI_msgSize)
{
TWDR = TWI_buf[TWI_bufPtr++];
TWCR = (1<<TWINT) | (1<<TWIE) | (1<<TWEN);
}
else
{
TWCR = (1<<TWIE) | (1<<TWEN)|(1<<TWINT)| (1<<TWSTO);
while(TWCR & (1<<TWSTO));
TWCR = (1<<TWEN)| (1<<TWIE)|(1<<TWINT)| (1<<TWEA);
}
break;
//SR-Error
case TW_SR_DATA_NACK:
case TW_SR_GCALL_DATA_NACK:
case TW_ST_LAST_DATA:
//MT-Error
case TW_MT_SLA_NACK: // SLA+W has been tramsmitted and NACK received
case TW_MR_SLA_NACK: // SLA+R has been tramsmitted and NACK received
case TW_MT_DATA_NACK: // Data byte has been tramsmitted and NACK received
case TW_BUS_ERROR: // Bus error due to an illegal START or STOP condition
default:
PORTB |= (1<<PB0);
do{} while(1); // Reset TWI Interface
}

}



Folgende Variablen brauchst Du um die ISR zu betreiben:

static volatile uint8_t TWI_buf[20];
static volatile unsigned char TWI_msgSize = 3;
static volatile unsigned char TWI_bufPtr;
static volatile uint8_t i2c_initiated = 0;

Den Buffer kannst Du an die größe Deiner maximalen Nachrichtengröße einrichten (Da hier auch die Slave-Adresse reinmuss +1). Atmel hat hier einen RingPuffer eingerichtet, den ich aber net brauche(müsste mich auch erstmal damit beschäftigen)

static volatile ist notwendig, damit die Variablen auch in der ISR bekannt sind. Ich glaube static wäre nicht notwendig, hatte aber noch keine Zeit das auszuprobieren.

Der Zeiger auf den Buffer wird benutzt um auf das nächste zu sendende Byte zu zeigen.

Die msgSize ist notwendig damit die ISR weiss wann Stop zu senden ist.

Bei einem Bus-Fehler geht der PortB,Pin0 an, ich nutze das um festzustellen ob auf dem Bus was schiefgelaufen ist, musst Du bestimmt anpassen.


Der Code zum initialisieren des TWI




void TWI_Initialise(void)
{
TWSR = (1<<TWPS1) | (1<<TWPS0); // Prescaler
TWBR=32;


TWAR = TW_Slave_Adr; //Setzen der TW-Adresse (Slave)
TWCR |= (1<<TWEN) | (1<<TWIE);

}



Die Slave-Adresse musst Du natürlich nur einrichten, wenn der AVR auch als Slave fungieren soll. Das TWI wird hier erstmal vorbereitet, und kann dann auch als Master benutzt werden.

Für den Slave-Betrieb muss TWEA=TW Enable Ack gesetzt werden:
TWCR = (1<<TWEN)| (1<<TWIE)|(1<<TWINT)| (1<<TWEA);

Für den Test als Master kannst Du das erstmal rauslassen.

Sobald das TWI eingerichtet ist, kannst Du

i2c_initiated =1;

schreiben. Das ist notwendig, für den Fall das die ISR aufgerufen wird obwohl Sie noch nicht richtig eingerichtet ist.

Wenn Du jetzt was senden willst, musst du den Buffer mit der Nachricht befüllen. Ich mach das so:






tmp_bufPtr=1;
TWI_msgSize= strlen(Str2Send) ;
do
TWI_buf[tmp_bufPtr++]=*Str2Send;
while (*Str2Send++);
TWI_buf[0] = recipient;

TWCR = (1<<TWEN)| (1<<TWIE)|(1<<TWINT)| (1<<TWSTA);


an die Adresse0 des Puffers muss die Empfänger-Adresse des Slave(bei mir recipient)

wenn Du schreiben möchtest(MT), muss das LSB der Adresse 0 sein, wenn Du vom Slave lesen möchtest(MR) musst Du das LSB auf 1 setzten. Wenn das LSB schon auf 0 steht (bei recipient) reicht es wenn Du 1 dazu addierst.

Mit
TWCR = (1<<TWEN)| (1<<TWIE)|(1<<TWINT)| (1<<TWSTA);

wirfst Du dann die Maschinerie an. (Durch das setzen von TWSTA). Die ISR übernimmt dann den Rest.

Was jetzt aber wichtig ist: Dein Programm sollte jetzt in eine Warteschleife gehen(Zum testen am besten: while(1)). Dadurch das das ganze über eine ISR gelöst ist, läuft dein normales Programm während der Übertragung weiter. Wenn Du jetzt nochmal Anweisung gibst etwas über den TWI-Bus zu senden läuft Du auf einen Bus-fehler, weil mitten in der Übertragung z.B nochmal Start gesendet wird.

Ich muss mich nochmal umschauen, wie man das am besten löst. Irgendwo habe ich was in der Art gesehen, das man solange der Master nichts zu senden hat das TWIE-Flag auf 0 setzt. Zum senden muss es ja auf 1 gesetzt werden. Dann kann man mit TWCR & (1<<TWIE) abfragen ob momentan eine Sendung läuft, und z.B. etwas anderes machen, oder aber warten.

hoffe das hilft

Cu

Martin

triplebit
16.03.2007, 18:06
Was vergessen:

du must natürlich die

#include <util/twi.h>

mit einbinden ;-)

jagdfalke
17.03.2007, 19:21
Wow, also vielen Dank, aber etwas Erklärungsbedarf ist noch da. Warum auf einmal TWI? Ich dachte I2C muss ich benutzen. Oder ist das das Gleiche? Warum kann ich diese Bibliothek nicht benutzen?
Ich möchte eigentlich nur diesen Code in C übersetzen:



Const Writepowerport_adr = &H72
Const Readpowerport_adr = &H73

Dim I2cdaten As Byte

Dim I As Byte

$crystal = 8000000
$baud = 9600
Config Scl = Portc.0
Config Sda = Portc.1

I2cinit


I = 0
I2cdaten = 1
Do
I2cdaten = I2cdaten * 2
If I2cdaten > 16 Then I2cdaten = 1

I2cstart
I2cwbyte Writepowerport_adr
I2cwbyte I2cdaten
I2cstop
Incr I
Waitms 100
Print "hallo"
Loop


End


Achja und nochwas: Was ist der Unterschied zwischen einer Variablendeklaration über #define und der "normalen" Version z.B. static uint8_t var ??

triplebit
17.03.2007, 21:22
Also TWI und I2C sind dasselbe. I2C stammt von Grundig, und der Name ist geschützt. Atmel hat das deswegen TWI=TwoWireInterface genannt. Die beiden sind weitgehend kompatibel(glaube der I2C unterstützt noch 10bit-Adressen (eine Erweiterung des normalen I2C), soweit ich das weiss kann der TWI das nicht). Das ganze funzt aber zusammen auf jeden Fall, es sei den es werden eben 10 bit Adressen anstatt 7 bit Adressen verwendet.

roboternetz hat da ein hevorragendes wiki! unbedingt mal lesen.

Zu dem Basic-Programm:

Das Teil schreibt anscheinend unendlich Zahlen von 1 bis 15 auf den Bus. Wo das Hallo ausgegeben wird weiss ich net, weil ich die HW net kenne.
(Genau das hatte ich übersehen.... Data wird immer mit 2 multipliziert... also 1 2 4 8 usw...also 1Led an 2Led an usw)


Prinzipiell ist es egal, was Du auf den Bus schreibst(zum testen) du kannst ja die Funktionen 2x aufrufen, das ist dann das selbe.

Ich habe den Code von Atmel verwendet, da ich das ganze über die ISR handeln möchte. Dadurch das das ganze über Interrupts (Wiki) gehandelt wird ist es möglich, wärend einer TWI-Sendung oder TWI-Empfang den AVR relativ normal zu benutzen(Berechnungen, Eingaben usw.) Bei Fleury ist der AVR mit der Sendung bzw dem Empfang beschäftigt und kann wärenddessen nix anderes machen.

Ich habe Dir diesen Code hochgeladen, weil ich den Code von Fleury nicht kenne, und mich da auch gar nicht erst einarbeiten will.

define (ebenfalls Wiki) behandelt einen String wie eine Variable, verschwendet aber keine Variable, weil beim Kompilieren diese "Variable" als Konstante eingebunden wird.

Generell solltest Du Dir mal das Wiki durchlesen und vielleicht erstmal andere Codes lesen bzw schreiben um mit C etwas vertrauter zu werden. TWI und C zu lernen ist etwas happig!!! Bei roboternetz ist das C und AVR-Tutorial (2 unterschiedliche Artikel) bei RN-Wissen versteckt.

Besorge Dir erstmal nen Compiler (meinetwegen auch ohne makefile) wie z.B AVR-Studio oder KAMAVR!

Schreibe mal ein Progi in C (und TWI-IF) und schau ob Du das durch den Compiler durchbekommst, wenn es dann net funzt, dann poste mir die Fehler und deinen Code.

cu

Martin

triplebit
17.03.2007, 23:21
Okay,

ich habe das Progi mal fertig gemacht. Hoffe das läuft bei deiner HW

cu

Martin

triplebit
17.03.2007, 23:37
Ups,

hatte im Bascom-Progi was übersehen, hier die korrigierte version.

Cu

Martin

jagdfalke
18.03.2007, 12:46
Hi, vielen Danke für die Hilfe.
Nur compilieren tut das leider nicht:


avr-gcc.exe -I"E:\mathias\projects\avr.projects\rnbfra_led\." -mmcu=atmega32 -Wall -gdwarf-2 -O0 -fsigned-char -MD -MP -MT rnbfra_led.o -MF dep/rnbfra_led.o.d -c ../rnbfra_led.c
../rnbfra_led.c: In function 'main':
../rnbfra_led.c:44: error: expected expression before '=' token
../rnbfra_led.c:44: error: 'H72' undeclared (first use in this function)
../rnbfra_led.c:44: error: (Each undeclared identifier is reported only once
../rnbfra_led.c:44: error: for each function it appears in.)
make: *** [rnbfra_led.o] Error 1
Build failed with 4 errors and 0 warnings...


Zeile 44 ist diese hier:

TWI_buf[0] = Writepowerport_adr;
kA was da falsch sein soll.

triplebit
18.03.2007, 16:15
besser das bitte zu


#define Writepowerport_adr 0x72;


aus


cu martin

jagdfalke
19.03.2007, 14:58
klappt thx :D

jetzt muss ich den code nur noch verstehen :D