PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Eigres 4 Bit Protokoll zum verbinden von Atmega8 und 32



ChRiZ
17.09.2006, 14:02
Hallo Zusammen!

Ich habe 2 Atmegas mit einem 4Bit Bus untereinander verbunden. (16 Mhz.)
beim Atmega 8 ist es PC0-3, beim Atmega32 PB0-3. (direkt parallel)

PD0 und PD1 sind cross miteinander verbunden und dienen als Steuerleitungen.

Das Protokoll ist sehr einfach gehalten, aber dazu später mehr.
Das Problem ist nun, wenn ich auf dem 4 Bit Bus Daten übertrage mit mehr als einem Bit aktiviert, allso "3" zum Beispiel. stürzt das Protokoll ab und bleibt hängen.
Mit mehreren Delays funktionierts dann wieder einigermassen, aber langsam.

Nun die überraschung, wenn ich irgend eine Zahl übetrage wo nur 1 Bit aktiv ist funktioneirts Prima!!!

allso, 1,2,4,8 funktioniert alles wunderbar... (und erst noch mit einem mega speed ;) )

kann mir jemand sagen wo das Problem liegen könnte?
Ist es ein kapazitive sache, das der uC zuviel Strom verliert und länger hat um 4 Bits zu aktivieren??

es werden jeweils 20*4bit gesendet und empfangen pro aufruf.

Ich wäre wirklich sehr froh wenn mir jemand helfen könnte!!! ;)
vielen Dank!!

hier das Protokoll:

volatile uint8_t toSend[20];
volatile uint8_t empfangen[20];

void resc(int t){
short i=0;
short p=1;

PORTD = 0x00;
DDRD =0x00; //alles Eindgang
DDRD |= (1 << PD1); //Port D1 als Ausgang

DDRC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) ); /* Alles Eingang ausser I2C BUS Ports */

for(i=0;i<t;i++){
p=1;
while (p) { //Warten auf Senderequest CPU 1
if(PIND & ((1<<PD0))) p=0;
else p=1;
}
empfangen[i]=PINC;
PORTD|=(1<<PD1); //Ack senden

p=1;
while (p) { //Warten bis PD0 = 0
if ( !(PIND & (1<<PD0)) )p=0;
else p=1;
}

PORTD&=~(1<<PD1); //Ack Löschen Transfer beendet.
}
}

void send (int x){
PORTD = 0x00;
DDRD = 0x00; //alles Eindgang
DDRD |= (1 << PD1); //Port D1 als Ausgang
DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC3); /*Alles Ausgang*/

short i;
short p;

for(i=0;i<x;i++){
PORTC = toSend[i]; //Daten bereitstellen
PORTD|=(1<<PD1); //Leitung Aktiv, Master will Daten Senden PD1

p=1;
while (p) { //Warten auf Ack von Slave, PD0(atmega32)=1 (Byte erhalten.)
if(PIND & ((1<<PD0))) p=0;
else p=1;
}

PORTD&=~(1<<PD1); //Leitung Ausschalten -> Atmega32 wartet solange bis PD0=0

p=1;
while (p) { //Warten auf Atmega32 PD1 = 0
if( !(PIND & (1<<PD0)) ) p=0;
else p=1;
}
}
resc(20);
}

ChRiZ
17.09.2006, 19:53
ich konnte das Problem etwas eindämmen..
ist ein Interrupt Problem, ich werde jetzt alle sensiblen Befehle mit CLI und SEI umrahmen ;)