Jimmybot
05.11.2011, 16:14
Moin Moin,
bin schon seit Wochen daran, das TWI zwischen zwe Controller an laufen zu bringen.
Dabei bin ich auf meine suche im Internet nirgendwo darauf gestoßen, wie der Slave die Daten aus dem TWDR abholt, bzw. wie er überhaupt zu programmieren ist.
^^
das ist mein Hauptproblem.
Da ich nicht weis, wie der Slave reagieren soll, weis ich noch nicht mal, ob das Programm für den Master richtig ist.
Hier mal meine C-Codes:
Master:
/*
Test Programm für TWI zwischen zwei ATmega8.
+++
Master sendet ein Byte an Slave. Byte wird an Port B über zwei Taster (B0 und B1) eingegeben und an Port D dargestellt
Über ein dritten Taser (B2) wird die TWI-Übertragung ausgeführt
+++
Slave gibt das Byte an Port B aus.
*/
#include <avr/io.h>
#include <avr\delay.h>
#define empfanger 0x10 // Empfänger Adresse (1) plus Schreibbit (0) in Hex
void send(unsigned char adres, unsigned char data) // Sende Funktion
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWI Starten, Startbedinung
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x08) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWDR=adres; // Zieladresse ins Register schreiben
TWCR=(1<<TWINT)|(1<<TWEN); // Zieladresse senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x18) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWDR=data; // Daten ins Register
TWCR=(1<<TWINT)|(1<<TWEN); // Daten senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x28) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // TWI beenden, Stopbedingung
}
int main(void)
{
DDRD=0xFF; // Port D als Ausgang
PORTD=0x00; // Port D auf Null
DDRC=0x01; // Port C0 als Ausgang
DDRB=0x00; // Port B als Eingang
int bit[8]={1,3,7,15,31,63,127,255}, a=0;
unsigned char data;
TWBR=44; // Bitraten Erzeugung
TWSR=0x01; // Vorteiler 1
while(1)
{
if(bit_is_clear(PINB,PINB0)) // ausführen, wenn PB0 0 ist
{
_delay_ms(170); // 170ms Warten (Prellen abwarten)
if(a<=6)
{
a=a+1;
PORTD=bit[a]; // Arraywert ausgeben
}
else
a=6;
}
if(bit_is_clear(PINB,PINB1)) // ausführen, wenn PB1 0 ist
{
_delay_ms(170);
if(a!=0)
{
a--;
PORTD=bit[a]; // Arraywert ausgeben
}
else
a=0;
}
if(bit_is_clear(PINB,PINB2)) // ausführen, wenn PB2 0 ist
send(empfanger, PORTD);
}
}
Slave:
/*
Test Programm für TWI zwischen zwei ATmega8.
+++
Master sendet ein Byte an Slave. Byte wird an Port B über zwei Taster (B0 und B1) eingegeben und an Port D dargestellt
Über ein dritten Taser (B2) wird die TWI-Übertragung ausgeführt
+++
Slave gibt das Byte an Port B aus.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char Daten;
int main(void)
{
DDRB=0xFF; // Port B als Ausgang
PORTB=0x00; // Port B aus Null
TWAR=0x10; // Slave Adresse 0x10
SREG=128; // Interrupts Global aktivieren
while(1)
{
PORTB=Daten; // Byte ausgeben
}
}
SIG_2WIRE_SERIAL(void) // TWI Interrupt
{
TWCR=(1<<TWEA)|(1<<TWEN); // Bestätigung senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
Daten=TWDR; // Daten aus dem Register in den Speicher
TWCR=(1<<TWEA)|(1<<TWEN); // Bestätigung senden
}
Wie gesagt, der Code vom Slave ist jetzt einfach mal frei geraten, das ich nirgend wo infos gefunden habe.
Kann mir irgend wer sagen, wie das ganze funktioniert?
Und bitte keine Links zu euren RN-Wissen artikel und Mikrocontroller.net.
Die kenne ich mittlerweile auswendig.:(
Ich bin soweit gekommen, dass die Fehler LED leuchtet, wenn ich auf den Senden-taster drücke. Das Byte kann ich auch einstellen.
Wo ist jetzt der Fehler, wo sind die Fehlern?:(
bin schon seit Wochen daran, das TWI zwischen zwe Controller an laufen zu bringen.
Dabei bin ich auf meine suche im Internet nirgendwo darauf gestoßen, wie der Slave die Daten aus dem TWDR abholt, bzw. wie er überhaupt zu programmieren ist.
^^
das ist mein Hauptproblem.
Da ich nicht weis, wie der Slave reagieren soll, weis ich noch nicht mal, ob das Programm für den Master richtig ist.
Hier mal meine C-Codes:
Master:
/*
Test Programm für TWI zwischen zwei ATmega8.
+++
Master sendet ein Byte an Slave. Byte wird an Port B über zwei Taster (B0 und B1) eingegeben und an Port D dargestellt
Über ein dritten Taser (B2) wird die TWI-Übertragung ausgeführt
+++
Slave gibt das Byte an Port B aus.
*/
#include <avr/io.h>
#include <avr\delay.h>
#define empfanger 0x10 // Empfänger Adresse (1) plus Schreibbit (0) in Hex
void send(unsigned char adres, unsigned char data) // Sende Funktion
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWI Starten, Startbedinung
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x08) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWDR=adres; // Zieladresse ins Register schreiben
TWCR=(1<<TWINT)|(1<<TWEN); // Zieladresse senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x18) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWDR=data; // Daten ins Register
TWCR=(1<<TWINT)|(1<<TWEN); // Daten senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
PORTC=0<PINC0; // Fehler-LED "aus"
if ((TWSR & 0xF8) != 0x28) // Fehlerausgabe, wenn ein Fehler auftritt
PORTC=1<<PINC0; // Fehler-LED "ein"
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN); // TWI beenden, Stopbedingung
}
int main(void)
{
DDRD=0xFF; // Port D als Ausgang
PORTD=0x00; // Port D auf Null
DDRC=0x01; // Port C0 als Ausgang
DDRB=0x00; // Port B als Eingang
int bit[8]={1,3,7,15,31,63,127,255}, a=0;
unsigned char data;
TWBR=44; // Bitraten Erzeugung
TWSR=0x01; // Vorteiler 1
while(1)
{
if(bit_is_clear(PINB,PINB0)) // ausführen, wenn PB0 0 ist
{
_delay_ms(170); // 170ms Warten (Prellen abwarten)
if(a<=6)
{
a=a+1;
PORTD=bit[a]; // Arraywert ausgeben
}
else
a=6;
}
if(bit_is_clear(PINB,PINB1)) // ausführen, wenn PB1 0 ist
{
_delay_ms(170);
if(a!=0)
{
a--;
PORTD=bit[a]; // Arraywert ausgeben
}
else
a=0;
}
if(bit_is_clear(PINB,PINB2)) // ausführen, wenn PB2 0 ist
send(empfanger, PORTD);
}
}
Slave:
/*
Test Programm für TWI zwischen zwei ATmega8.
+++
Master sendet ein Byte an Slave. Byte wird an Port B über zwei Taster (B0 und B1) eingegeben und an Port D dargestellt
Über ein dritten Taser (B2) wird die TWI-Übertragung ausgeführt
+++
Slave gibt das Byte an Port B aus.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char Daten;
int main(void)
{
DDRB=0xFF; // Port B als Ausgang
PORTB=0x00; // Port B aus Null
TWAR=0x10; // Slave Adresse 0x10
SREG=128; // Interrupts Global aktivieren
while(1)
{
PORTB=Daten; // Byte ausgeben
}
}
SIG_2WIRE_SERIAL(void) // TWI Interrupt
{
TWCR=(1<<TWEA)|(1<<TWEN); // Bestätigung senden
loop_until_bit_is_set(TWCR,TWINT); // Warten bis fertig
Daten=TWDR; // Daten aus dem Register in den Speicher
TWCR=(1<<TWEA)|(1<<TWEN); // Bestätigung senden
}
Wie gesagt, der Code vom Slave ist jetzt einfach mal frei geraten, das ich nirgend wo infos gefunden habe.
Kann mir irgend wer sagen, wie das ganze funktioniert?
Und bitte keine Links zu euren RN-Wissen artikel und Mikrocontroller.net.
Die kenne ich mittlerweile auswendig.:(
Ich bin soweit gekommen, dass die Fehler LED leuchtet, wenn ich auf den Senden-taster drücke. Das Byte kann ich auch einstellen.
Wo ist jetzt der Fehler, wo sind die Fehlern?:(