So hab ich gemacht komplett rauskopiert und in i2cslave.c gespeichert und im programm included. Hab nur den Pfad für #include <compat/twi.h> angepasst.
Immer noch gleiches Problem 
main.c
Code:
// AVR Bibs
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h> // I/O Ports
#include <inttypes.h> // Datentypen
#include <avr/pgmspace.h> // Stringfunktionen
#include <string.h> // Stringfunktionen
#include <avr/interrupt.h> // Interrupts
#include <avr/signal.h> // Timer
#include <math.h>
/*************************************************** Globale Variablen ************************************************/
/*************************************************** Init defines *******************************************************/
// Werte zur Berechnung der Interrupt-Rate bei AVR-Fuses,
// die auf 1MHz eingestellt sind (Werkseinstellung für internen RC-Oszillator)
#define F_CPU 16000000
// Geräteadressen
#define KEYLCD 0x40
#define RELAIS 0x76
#define Servos 0x68
#define PCFA 0x9E
#define PCF1 0x72
#define PCF2 0x7E
#define PCF3 0x74
#define PCF4 0x7C
#define PCF5 0x7A
#define PCF6 0x78
// Eigene Bibs
#include "func.h" // Allgemeine Funktionen
#include "sens.h" // Sensorfunktionen
#include "i2cslave.c"
int main(void) {
/*******************************************************************************************************************/
/* Initialisierung */
/*******************************************************************************************************************/
//*** Alle Ports an PortD als Ausgang definieren
DDRB = 0xFF;
PORTB = 0x00;
DDRD = 0xFF; //Alle PortD Pins auf Ausgang gesetzt (PD0-3 für BCD, PD4-7 für Ziffer 1-4)
PORTD = 0x00; //Alles auf Low, Anzeige aus
DDRC = 0xFF;
PORTC= 0x00;
PORTC &= ~(1<<DDC1);
init_twi_slave(0x60); // Init I2C interface
Delay(1000);
PORTC |= (1<<DDC1);
Delay(400);
PORTC &= ~(1<<DDC1);
Delay(400);
rxbuffer[0]=0;
for(;;){
if (rxbuffer[0]!= 0){
PORTC |= (1<<DDC1);
Delay(2000);
}
}
/*********************************************************************************************************************/
}
i2cslave.c
Code:
/*
Dieses Programm kann in einer separaten Datei (z.B. twislave.c) abgespeichert und in anderen Programmen
eingebunden werden.
Betrieb eines AVRs mit Hardware-TWI-Schnittstelle als Slave. Zu Beginn muss init_twi_slave mit der gewünschten
Slave-Adresse als Parameter aufgerufen werden. Der Datenaustausch mit dem Master erfolgt über die Buffer
rxbuffer und txbuffer, auf die von Master und Slave zugegriffen werden kann.
rxbuffer und txbuffer sind globale Variablen (Array aus uint8_t).
Die Ansteuerung des rxbuffers, in den der Master schreiben kann, erfolgt ähnlich wie bei einem normalen I2C-EEPROM.
Man sendet zunächst die Bufferposition, an die man schreiben will, und dann die Daten. Die Bufferposition wird
automatisch hochgezählt, sodass man mehrere Datenbytes hintereinander schreiben kann, ohne jedesmal
die Bufferadresse zu schreiben.
Um den zxbuffer vom Amster aus zu lesen, überträgt man zunächst in einem Schreibzugriff die gewünschte Bufferposition und
liest dann nach einem repeated start die Daten aus. Die Bufferposition wird automatisch hochgezählt, sodass man mehrere
Datenbytes hintereinander lesen kann, ohne jedesmal die Bufferposition zu schreiben.
Autor: Uwe Große-Wortmann (uwegw), Juli 2006.
Status: Testphase, keine Garantie für ordnungsgemäße Funktion! Empfangen scheint zu funktionieren.
letze Änderungen: Senden über den txbuffer implementiert, noch weitgehend ungetestet!
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <compat/twi.h>
uint8_t buffer_adr; //"Adressregister" für den Buffer
/*Der Buffer, in dem die empfangenen Daten gespeichert werden. Der Slave funktioniert ähnlich wie ein normales
Speicher-IC [I2C-EEPROM], man sendet die Adresse, an die man schreiben will, dann die Daten, die interne Speicher-Adresse
wird dabei automatisch hochgezählt*/
volatile uint8_t rxbuffer[8];
#define rx_PWM_L 2
#define rx_PWM_R 3
#define rx_DIR 1
/*Der Sendebuffer, der vom Master ausgelesen werden kann. [noch nicht implementiert!]*/
volatile uint8_t txbuffer[8];
void init_twi_slave (uint8_t adr)
{
TWAR= adr; //Adresse setzen
TWCR|= (1<<TWEA) | (1<<TWEN)|(1<<TWIE);
TWCR &= ~(1<<TWSTA)|(1<<TWSTO);
buffer_adr=0xFF;
sei();
}
ISR (TWI_vect) //ISR, die bei einem Ereignis auf dem Bus ausgelöst wird. Im Register TWSR befindet sich dann
//ein Statuscode, anhand dessen die Situation festgestellt werden kann.
{
uint8_t data=0;
switch (TWSR) //TWI-Statusregister prüfen und nötige Aktion bestimmen
{
case TW_SR_SLA_ACK: // 0x60 Slave Receiver, wurde adressiert
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Expect ACK on this transmission
(0<<TWWC); //
buffer_adr=0xFF; //Bufferposition ist undefiniert
break;
case TW_SR_DATA_ACK: // 0x80 Slave Receiver,Daten empfangen
data=TWDR;
if (buffer_adr == 0xFF) //erster Zugriff, Bufferposition setzen
{
buffer_adr= data; //Bufferposition wie adressiert setzen
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next reception
(0<<TWWC);
}
else //weiterer Zugriff, Daten empfangen
{
rxbuffer[buffer_adr]=data; //Daten in Buffer schreiben
buffer_adr++; //autoincrement Buffer-Adresse
if(buffer_adr<7)
{
//nächstes Byte lesen, ACK danach
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next reception
(0<<TWWC);
}
else
{
//letztes Byte lesen, dann NACK
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
(0<<TWWC);
}
}
break;
case TW_ST_SLA_ACK:
case TW_ST_DATA_ACK: //0xB0 weitere Daten gefordert
TWDR = txbuffer[buffer_adr];
buffer_adr++;
TWCR = (1<<TWEN)|
(1<<TWIE)|(1<<TWINT)|
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
(0<<TWWC);
break;
case TW_ST_DATA_NACK: //0xC0 Keine Daten mehr gefordert
case TW_SR_DATA_NACK: //0x88
case TW_ST_LAST_DATA: //0xC8 Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
case TW_SR_STOP: // 0xA0 STOP empfangen
default:
TWCR = (1<<TWEN)|
(1<<TWIE)|(1<<TWINT)|
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
(0<<TWWC);
//buffer_adr=0xFF; //Bufferposition ist undefiniert
break;
} //end.switch
} //end.twi_ISR
Lesezeichen