sast
27.02.2009, 10:37
Ich verwende schon seit längerem die UART Funktionen aus dem Wiki und hatte bisher auch noch nie Probleme, da ich nie mehr als 8 Zeichen gesendet habe um zwischen den Kontrollern zu kommunizieren. Nun hab ich mal bei einem Versuchsaufbau ( will mich an die SPI Schnittstelle wagen) ein Hallo Welt an den Kontroller vom PC aus geschickt.
War auch ok da ich wie im unten stehenden Code für den Empfang ein delay(100) drin hab. Welches nur ein Rudiment aus irgend einem Test war.
Gesendet habe ich :owHallo Welt!
int main( void )
{
char c;
char text[32];
char tag[3];
int i;
initio();
initspi();
ser_init();
sei();
tag[0]=CONTROLLER_TAG;//':'
tag[1]=CONTROLLER_ID;//'o'
tag[2]=0;
while (1)
{
if (ser_chars_present())
{
i=0;
do
{
c = ser_getc_nowait();
text[i++]=c;
} while(ser_chars_present());
text[i]='\0';
delay_ms(100);
if(((i<31) && (strlen(text)<3)) && (ser_chars_present()))
{
do
{
c = ser_getc_nowait();
text[i++]=c;
} while(ser_chars_present());
text[i]='\0';
}
if((strlen(text)>2) && (!strncmp(text, tag, 2)))
{
if(!execution_of_the_order(text[2], text))
{
ser_puts(CONTROLLER_FAIL);
}
}
else
{
//geht uns nichts an
}
}
}
}
Dadurch entsteht aber eine ziemlich große Pause bis die Antwort vom Kontroller kommt.
char execution_of_the_order(char order, char* message)
{
char s[32];
int a;
a=0;
while(a<3)
{
message++;
a++;
}
strncpy(s, message, 32);
if(order=='a')
{
ser_puts(CONTROLLER_RESPONSE);
return 1;
}
if(order=='b')
{
ser_puts(CONTROLLER_NAME);
return 1;
}
if(order=='w')
{
SpiSendString(s);
ser_puts(s);
return 1;
}
if(order=='r')
{
ser_puts(CONTROLLER_RESET);
bootloader();
return 1;
}
return 0;
}
Habe also mal das delay auf 10 runtergesetzt, unter der Annahme, dass man das gar nicht benötigt und siehe, da kommt das raus, was ich mal als Bild versuche anzuhängen.
Kann mir das einer erklären? Es ist auch reproduzierbar immer Hallo W was da als Antwort kommt.
sast
EDIT: Habs wieder mal zu schnell hier eingestellt.
Die Abarbeitung ist natürlich viel schneller als die Daten, welche mit 9600Baud eintrudeln. Werde einfach nach jedem empfangenen Byte eine von Baudrate und Sysclk abhängige Wartezeit einbauen. Das ist dann immer noch kürzer als einfach mal so 100ms zu warten.
Oder hat jemand eine effizientere Idee?
War auch ok da ich wie im unten stehenden Code für den Empfang ein delay(100) drin hab. Welches nur ein Rudiment aus irgend einem Test war.
Gesendet habe ich :owHallo Welt!
int main( void )
{
char c;
char text[32];
char tag[3];
int i;
initio();
initspi();
ser_init();
sei();
tag[0]=CONTROLLER_TAG;//':'
tag[1]=CONTROLLER_ID;//'o'
tag[2]=0;
while (1)
{
if (ser_chars_present())
{
i=0;
do
{
c = ser_getc_nowait();
text[i++]=c;
} while(ser_chars_present());
text[i]='\0';
delay_ms(100);
if(((i<31) && (strlen(text)<3)) && (ser_chars_present()))
{
do
{
c = ser_getc_nowait();
text[i++]=c;
} while(ser_chars_present());
text[i]='\0';
}
if((strlen(text)>2) && (!strncmp(text, tag, 2)))
{
if(!execution_of_the_order(text[2], text))
{
ser_puts(CONTROLLER_FAIL);
}
}
else
{
//geht uns nichts an
}
}
}
}
Dadurch entsteht aber eine ziemlich große Pause bis die Antwort vom Kontroller kommt.
char execution_of_the_order(char order, char* message)
{
char s[32];
int a;
a=0;
while(a<3)
{
message++;
a++;
}
strncpy(s, message, 32);
if(order=='a')
{
ser_puts(CONTROLLER_RESPONSE);
return 1;
}
if(order=='b')
{
ser_puts(CONTROLLER_NAME);
return 1;
}
if(order=='w')
{
SpiSendString(s);
ser_puts(s);
return 1;
}
if(order=='r')
{
ser_puts(CONTROLLER_RESET);
bootloader();
return 1;
}
return 0;
}
Habe also mal das delay auf 10 runtergesetzt, unter der Annahme, dass man das gar nicht benötigt und siehe, da kommt das raus, was ich mal als Bild versuche anzuhängen.
Kann mir das einer erklären? Es ist auch reproduzierbar immer Hallo W was da als Antwort kommt.
sast
EDIT: Habs wieder mal zu schnell hier eingestellt.
Die Abarbeitung ist natürlich viel schneller als die Daten, welche mit 9600Baud eintrudeln. Werde einfach nach jedem empfangenen Byte eine von Baudrate und Sysclk abhängige Wartezeit einbauen. Das ist dann immer noch kürzer als einfach mal so 100ms zu warten.
Oder hat jemand eine effizientere Idee?