PCMan
17.12.2008, 21:10
Hallo Leute,
mal wieder komme ich nicht weiter und möchte nun mal die Experten an die harte Nuss lassen.
Ich möchte meinen AVR mit dem PC kommunizieren lassen. Dazu verwende ich das Terminalprogram puTTY.
Ich möchte, dass mein AVR empfangene Befehle erkennt und ausführt.
Im Großen und Ganzen realisiere ich das mit P.Fleuries UART-Library.
Dort habe ich aber in der uart.c einige Modifikationen vorgenommen.
Zunächst etwas Code:
volatile struct {
... jede Menge zeugs...
uint8_t command_ptr;
char command[255];
} system;
// Die Kommandostruktur
char p_unknown[] PROGMEM = "Unbekannter Befehl: ";
typedef struct
{
void (*func)(uint8_t); // Zeiger auf die auszuführende Funktion
//uint8_t arg; // das Argument, das mitübergeben wird
uint8_t arg;
char text[255]; // Text, maximal TEXT_LEN Zeichen lang
} command_t;
//Sprungtabelle: welche Funktion mit welchem Parameter bei welchem eingegangenem Befehl?
const command_t commands[] PROGMEM =
{
{ execute, 1, "ping" },
{ execute, 2, "help" }
};
...
//zunächst alles beim alten...
SIGNAL(UART0_RECEIVE_INTERRUPT)
/************************************************** ***********************
Function: UART Receive Complete interrupt
Purpose: called when the UART has received a character
************************************************** ************************/
{
unsigned char tmphead;
unsigned char data;
unsigned char usr;
unsigned char lastRxError;
/* read UART status register and UART data register */
usr = UART0_STATUS;
data = UART0_DATA;
/* */
#if defined( AT90_UART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART0 )
lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
#elif defined ( ATMEGA_UART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#endif
/* calculate buffer index */
tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
if ( tmphead == UART_RxTail ) {
/* error: receive buffer overflow */
lastRxError = UART_BUFFER_OVERFLOW >> 8;
}else{
/* store new index */
UART_RxHead = tmphead;
/* store received data in buffer */
UART_RxBuf[tmphead] = data;
}
UART_LastRxError = lastRxError;
//AB HIER MODIFIZIERT
uint8_t c = uart_getc(); //es wurde Zeichen empfangen, dann hole es ab!
if (!(c & UART_NO_DATA) && !( c & UART_FRAME_ERROR ) && !( c & UART_OVERRUN_ERROR ) && !( c & UART_BUFFER_OVERFLOW )&& c != 0) //es wurde ein Zeichen empfangen und kein Fehler o.Ä.
{
uart_putc(c); //zeichen ausgeben
if (c == 13) //es wurde Enter-Taste im puTTY gedrückt.
{
uart_puts("\n\r"); //neue Zeile in puTTY
system.command[system.command_ptr]='\0';
system.command_ptr = 0;
lcd_clrscr();
lcd_puts((char*)system.command);
const command_t * cmd = commands;
uint8_t i;
for (i=0; i < sizeof(commands) / sizeof(command_t); i++)
{
// Ist das der gesuchte String?
if (strcmp_P ((char*)system.command, cmd->text))
{
// Nein, dann weitersuchen
cmd++;
continue;
}
else
{
// Ja
uint8_t (*func)(uint8_t), arg;
// Dann Funktionszeiger und Argument besorgen,
func = (uint8_t(*)(uint8_t)) pgm_read_word (& cmd->func);
arg = (uint8_t) pgm_read_word (& cmd->arg);
// Funktion ausführen und deren Wert zurückliefern
func (arg);
break;
}
}
if (i==2) //es wurden alle Befehle abgegrast, aber der richtige war nicht dabei
{
uart_puts_P("Unbekannter Befehl: "); //<- HIER ENTSTEHT DER FEHLER
uart_puts((char*)system.command);
uart_puts("\n\r#");
}
}
else
{
system.command[system.command_ptr] = c;
system.command_ptr++;
}
}
}
Es kommen keine Warnings nach dem Kompilieren.
Wenn ich nun folgendes in putty eingebe:
"ping": ich erhalte wie erwartet antwort
"ping.": Meldung dass Befehl nicht gefunden wurde
"ping.." (oder irgendetwas anderes was mehr als 7 Zeichen hat führt zum Absturz des Programmes. Ich weiß aber, dass die Codezeilen ausgeführt werden, aber ich weiß nicht, warum nix über den UART rausgesendet wird.
Ich hoffe ihr habt ein paar Ideen,
Grüße Simon
P.S.: ATMega32, 12MHz
mal wieder komme ich nicht weiter und möchte nun mal die Experten an die harte Nuss lassen.
Ich möchte meinen AVR mit dem PC kommunizieren lassen. Dazu verwende ich das Terminalprogram puTTY.
Ich möchte, dass mein AVR empfangene Befehle erkennt und ausführt.
Im Großen und Ganzen realisiere ich das mit P.Fleuries UART-Library.
Dort habe ich aber in der uart.c einige Modifikationen vorgenommen.
Zunächst etwas Code:
volatile struct {
... jede Menge zeugs...
uint8_t command_ptr;
char command[255];
} system;
// Die Kommandostruktur
char p_unknown[] PROGMEM = "Unbekannter Befehl: ";
typedef struct
{
void (*func)(uint8_t); // Zeiger auf die auszuführende Funktion
//uint8_t arg; // das Argument, das mitübergeben wird
uint8_t arg;
char text[255]; // Text, maximal TEXT_LEN Zeichen lang
} command_t;
//Sprungtabelle: welche Funktion mit welchem Parameter bei welchem eingegangenem Befehl?
const command_t commands[] PROGMEM =
{
{ execute, 1, "ping" },
{ execute, 2, "help" }
};
...
//zunächst alles beim alten...
SIGNAL(UART0_RECEIVE_INTERRUPT)
/************************************************** ***********************
Function: UART Receive Complete interrupt
Purpose: called when the UART has received a character
************************************************** ************************/
{
unsigned char tmphead;
unsigned char data;
unsigned char usr;
unsigned char lastRxError;
/* read UART status register and UART data register */
usr = UART0_STATUS;
data = UART0_DATA;
/* */
#if defined( AT90_UART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#elif defined( ATMEGA_USART0 )
lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
#elif defined ( ATMEGA_UART )
lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
#endif
/* calculate buffer index */
tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
if ( tmphead == UART_RxTail ) {
/* error: receive buffer overflow */
lastRxError = UART_BUFFER_OVERFLOW >> 8;
}else{
/* store new index */
UART_RxHead = tmphead;
/* store received data in buffer */
UART_RxBuf[tmphead] = data;
}
UART_LastRxError = lastRxError;
//AB HIER MODIFIZIERT
uint8_t c = uart_getc(); //es wurde Zeichen empfangen, dann hole es ab!
if (!(c & UART_NO_DATA) && !( c & UART_FRAME_ERROR ) && !( c & UART_OVERRUN_ERROR ) && !( c & UART_BUFFER_OVERFLOW )&& c != 0) //es wurde ein Zeichen empfangen und kein Fehler o.Ä.
{
uart_putc(c); //zeichen ausgeben
if (c == 13) //es wurde Enter-Taste im puTTY gedrückt.
{
uart_puts("\n\r"); //neue Zeile in puTTY
system.command[system.command_ptr]='\0';
system.command_ptr = 0;
lcd_clrscr();
lcd_puts((char*)system.command);
const command_t * cmd = commands;
uint8_t i;
for (i=0; i < sizeof(commands) / sizeof(command_t); i++)
{
// Ist das der gesuchte String?
if (strcmp_P ((char*)system.command, cmd->text))
{
// Nein, dann weitersuchen
cmd++;
continue;
}
else
{
// Ja
uint8_t (*func)(uint8_t), arg;
// Dann Funktionszeiger und Argument besorgen,
func = (uint8_t(*)(uint8_t)) pgm_read_word (& cmd->func);
arg = (uint8_t) pgm_read_word (& cmd->arg);
// Funktion ausführen und deren Wert zurückliefern
func (arg);
break;
}
}
if (i==2) //es wurden alle Befehle abgegrast, aber der richtige war nicht dabei
{
uart_puts_P("Unbekannter Befehl: "); //<- HIER ENTSTEHT DER FEHLER
uart_puts((char*)system.command);
uart_puts("\n\r#");
}
}
else
{
system.command[system.command_ptr] = c;
system.command_ptr++;
}
}
}
Es kommen keine Warnings nach dem Kompilieren.
Wenn ich nun folgendes in putty eingebe:
"ping": ich erhalte wie erwartet antwort
"ping.": Meldung dass Befehl nicht gefunden wurde
"ping.." (oder irgendetwas anderes was mehr als 7 Zeichen hat führt zum Absturz des Programmes. Ich weiß aber, dass die Codezeilen ausgeführt werden, aber ich weiß nicht, warum nix über den UART rausgesendet wird.
Ich hoffe ihr habt ein paar Ideen,
Grüße Simon
P.S.: ATMega32, 12MHz