Enviar comando usando USART

Soy nuevo en este tipo de comunicación. Puedo enviar comandos desde la PC al microcontrolador AT90USB1287 y también puedo obtener una respuesta mediante la comunicación USB. Ahora he conectado otro microcontrolador (ATmega32) a esta placa a través de la comunicación USART. Estoy tratando de enviar un comando desde la PC a esta placa. Ambos controladores tienen diferentes comandos. Así que he creado una matriz que contiene los comandos de ambos controladores en el controlador AT90USB1287. Mi concepto es comparar el comando entrante de la PC con todos los comandos en la matriz según el resultado. Estoy tratando de enviar comandos al controlador ATmega32 usando USART. Tengo el código como se muestra a continuación.

#include <90usb1287.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <interface.h>
#include <uart_drv.h>

#define CMD_SIZE    57 
#define USB_CMD_SIZE    52 

flash unsigned char * flash cmdList[CMD_SIZE] = { 
"",             // [0] no com 
"INFO",          // [1] Displayes version date etc. 
"SET",        // [2] Reset CPU 
"boot",         // [3] Goto boot 
"UMP",         // [4] Display manual debug info 
"AUTO",          // [5] Start automatic scanning 
"STRP",         // [6] Stop scanning 
"STAF",         // [7] Set start frequency 
"STOF",         // [8] Set stop frequency 
"RES",          // [9] Display manual debug info 
"RATES",         // [10] Display manual debug info 
"GAINAD",         // [11] Set gain 
"SCANSD",         // [12] Start custom scan 
"SETUP",        // [13] Display manual scan setup info 
"TEMP",         // [14] Set temperature (Celsius) 
..................... 
......................  
"COM",       // [52] no com 
"PINF",         // [53] Displays version date etc. 
"PSCAN",         // [54] 
"PWGF",          // [55] 
"PADC"          // [56] Clear Flash memmory (stopLog)       
};

unsigned char SerIn[SIBUFSIZE];     // Input buffer (raw data)
unsigned char RxCnt;                // Location of next byte to be written
unsigned char RdCnt;                // Location of next byte to be read
unsigned char BufCnt;               // Size of unread contents in ring buffer
unsigned char CompIndex;            // Index in Copmare array
unsigned char Compare[COMPBUFSIZE]; // Command string tokenizer

 unsigned char Uart_CompIndex;            // Index in Copmare array

 unsigned char Command;              // Current Command is executed
 unsigned int  Param;                // Parameter used in command
   float  Param2;               // Optional (second) parameter used in command
  unsigned long Param3;               // Optional (third) parameter in command

 extern unsigned char Plot;
 unsigned char Step;


 // USART1 Receiver interrupt service routine
 interrupt [USART1_RXC] void usart1_rx_isr(void){   

 char status,data;
 status=UCSR1A;
  data=UDR1;
  printf("%c", data);
 }

 // USB Receive
 void catchString(void){

 while(UEBCLX){

    if(++BufCnt >= SIBUFSIZE){               // Increment & check for buffer overflow  
        BufCnt = SIBUFSIZE-1;                // Set to max value   
        return;                              // Skip char
    }else{                                   // Else: if buffer ok
       if(++RxCnt >= SIBUFSIZE) RxCnt = 0;// Increment read counter, if 10 -> 0 (max 9)
    SerIn[RxCnt] = UEDATX;               // Write to SBUF (load the transmit register)
    }
  }  
  }


 // Read from ringbuffer
 char getcharb(void){

    if(BufCnt){                                 // If anything
    BufCnt--;                               // Decrement buffer counter
    if(++RdCnt >= SIBUFSIZE) RdCnt = 0;   // Increment read counter, if 10 -> 0 (max 9)
    return SerIn[RdCnt];                    // Read from SBUF (access receive register)
 }
 return 0;
 }

void getcom(void){

  unsigned char c;

 // Read from ring-buffer and fill in Compare buffer
  while(BufCnt){                          
        c = getcharb();                    
    if(CompIndex >= COMPBUFSIZE) CompIndex = 0;
        // Analyze char
        if(c == '#'){                     
              CompIndex = 0;
        }else if(c == '\r'){                            
              Compare[CompIndex]='\0';    
              break;                      
        }else if(c == '\n'){              
              // Do nothing (ignore)
        }else if(c == 8){                 
              if(CompIndex) CompIndex--;  

        }else if(c == 9){      // Horizontal TAB 
              help();          // Write out cmds

        }else if(c == 27){        // ESC button
              Command = 0;// Stop current command

              Param = 0;       // Clear argument
              Plot = 0;     // Stop plotting
              Step = 0;
        }else{
              Compare[CompIndex++]=c;     
        }if(!BufCnt) return;                                     
  }CompIndex=0;                           

  c = 1;
  while(c<CMD_SIZE){          // For each command       
        if(strncmpf(Compare,cmdList[c],strlenf(cmdList[c])) == 0) break;
        c++; 
  }   

  if(c> USB_CMD_SIZE){    // this is for ATmega32
      Command = c;
       if(isdigit(Compare[strlenf(cmdList[c])])){
              Param = atoi(&Compare[strlenf(cmdList[c])]);
              c = strpos(Compare,':');                 
              if(c > 0){
                    Param2 = atof(&Compare[c+1]);
                    c = strrpos(Compare,':');
                    if(c > strpos(Compare,':')) Param3 = atol(&Compare[c+1]);
                    else  Param3 = 0; 
              }else{ 
                Param2 = 0;
                Param3 = 0;
              }
        }else{
            Param  = 0;
            Param2 = 0;
            Param3 = 0;
        }              
           uart_putchar(Compare);
    //printf("@%s\r\n",&Compare); //Ack command
      }

  if(c<USB_CMD_SIZE){    //If match on normal cmnd in usb
        Command = c;      
        if(isdigit(Compare[strlenf(cmdList[c])])){
              Param = atoi(&Compare[strlenf(cmdList[c])]);
              c = strpos(Compare,':');                 
              if(c > 0){
                    Param2 = atof(&Compare[c+1]);
                    c = strrpos(Compare,':');
                    if(c > strpos(Compare,':')) Param3 = atol(&Compare[c+1]);
                    else  Param3 = 0; 
              }else{ 
                Param2 = 0;
                Param3 = 0;
              }
        }else{
            Param  = 0;
            Param2 = 0;
            Param3 = 0;
        }
        printf("@%s\r\n",&Compare); //Ack command
  }else{

  if(c>CMD_SIZE-1){             // If match on normal commands

        printf("&E;1;\r\n");  // Command not found
       printf("->Unknown command: 's'\r\n",&Compare); // If no match
        Command = 0;
         Param  = 0;
         Param2 = 0;
         Param3 = 0;
}
  }       
}

en el código anterior, puedo obtener una respuesta del controlador USB pero no de ATmega32A. Estoy comprobando que el índice es > 52 (USB_CMD_SIZE) y luego lo envío a ATmega32; de lo contrario, lo envío a USB) = 1287.

me sale error en esta linea

uart_putchar(Compare);

Tengo la función para uart_putchar así.

void uart_putchar (char ch)
{
   while(!Uart_tx_ready());
   Uart_set_tx_busy(); // Set Busy flag before sending (always)
   Uart_send_byte(ch);   
   return;
 }

incluso lo intenté así

  uart_puts(Compare);

por eso he escrito asi

  void uart_puts(const char *s)
  {
    while(*s)
      {
         uart_putchar(*s++);
      //    printf("*");
   }    
   }

Pero nada me funciona. ¿Alguien puede ayudarme a solucionar esto? ¿Necesito alguna conversión aquí? Si es así, por favor ayúdame con un ejemplo.

Cuando uso este código, puedo obtener una respuesta de atmega32, pero el problema es que este código está enviando todos los comandos a ambos controladores, por lo que en ese momento tengo un problema, así que estoy probando el anterior.

 void getcom(void){

  unsigned char c;

  // Read from ring-buffer and fill in Compare buffer
  while(BufCnt){                          // while unread contents in ring-buffer
        c = getcharb();                    // fetch next byte

        if(CompIndex >= COMPBUFSIZE) CompIndex = 0;// overflow protection                    
        // Analyze char
        if(c == '#'){                     // Manual start
              CompIndex = 0;
      uart_putchar(c);
        }else if(c == '\r'){              // CR continue (end of cmd without argument)                         
              Compare[CompIndex]='\0';    // fill in end character of comp string
       uart_putchar(c);
              break;                      // possible valid cmd received -> check out
        }else if(c == '\n'){              // New line (ignore)                         
              // Do nothing (ignore)
        }else if(c == 8){                 // Backspace
              if(CompIndex) CompIndex--;  // decrement index
          uart_putchar(c);
        }else if(c == 9){                 // Horizontal TAB 
              help();                     // Write out cmds
            uart_putchar(c);

        }else if(c == 27){                // ESC button
              Command = 0;                // Stop current command
    uart_putchar(c);

              Param = 0;                  // Clear argument
              Plot = 0;                   // Stop plotting
              Step = 0;
        }else{
              Compare[CompIndex++]=c;     // Default action: Store character

        uart_putchar(c);
        }if(!BufCnt) return;              // if no more data to read -> exit                                          
  }CompIndex=0;                           // reset, ready for next command

  c = 1;


  while(c<CMD_SIZE){          // For each command       
        if(strncmpf(Compare,cmdList[c],strlenf(cmdList[c])) == 0) break;
        c++; 
  }   

  if(c<USB_CMD_SIZE){             // If match on normal commands
        Command = c;      
        if(isdigit(Compare[strlenf(cmdList[c])])){
              Param = atoi(&Compare[strlenf(cmdList[c])]);
              c = strpos(Compare,':');                 
              if(c > 0){
                    Param2 = atof(&Compare[c+1]);
                    c = strrpos(Compare,':');
                    if(c > strpos(Compare,':')) Param3 = atol(&Compare[c+1]);
                    else  Param3 = 0; 
              }else{ 
                Param2 = 0;
                Param3 = 0;
              }
        }else{
            Param  = 0;
            Param2 = 0;
            Param3 = 0;
        }
        printf("@%s\r\n",&Compare); //Ack command
  }else{

  if(c>CMD_SIZE-1){             // If match on normal commands

     //   printf("&E;1;\r\n");  // Command not found
    //    printf("->Unknown command: '%s'\r\n",&Compare); // If no match
        Command = 0;
         Param  = 0;
         Param2 = 0;
         Param3 = 0;
}
  }      
 }

este código envía todos y cada uno de los caracteres a ambos controladores.

En Compare tengo el comando como "PSCAN".

printf("@%s\r\n",&Compare); //Ack command

esta línea imprimiendo como

@PSCAN
USB901287 es probablemente un AT90USB1287 .
@abdullahkahraman Sí
¿Cómo se define Compare, qué contiene? ¿Podrías mostrar más código?
@abdullahkahraman seguro, he actualizado ahora mira mi nuevo código actualizado.
Veo que Compareno se inicializa con ningún valor y solo se llena cuando CompIndex >= COMPBUFSIZE. Intente asignarle algunos valores ficticios, tal vez en la inicialización. Pero no estoy seguro si este es el problema.
@abdullahkahraman Lo intenté así y no funcionó. Estoy pensando en su valor int y estoy tratando de poner un carácter, pero estoy tratando de convertir esa comparación en una cadena, ¿tienes alguna idea?
Lo siento, no tengo otra idea que eliminar constla palabra del uart_puts()argumento de la función. Debe dar el error que está dando en la pregunta.
@abdullahkahraman Cuando depuro, veo que en "Comparar" tengo el comando como "PSCAN". ve que esta línea es "printf("@%s\r\n",&Compare); //Ack command" allí está imprimiendo el comando. Entonces & Comapare contiene el comando que estoy tratando de averiguar cómo enviar eso. ¿Puedes echar un vistazo a mi explicación añadida a la pregunta?
Estoy perdido, lo siento. Espero que alguien te pueda ayudar con una buena respuesta! :)

Respuestas (2)

Su variable Comparees una matriz de caracteres. Espera void uart_putchar(char ch)un carácter, no una matriz de caracteres, por lo que no puede usar ese para imprimir Compare. Su función void uart_puts(const char *s)espera una matriz de caracteres, ¡pero también espera que sea constante! Es posible que desee intentar cambiar eso a void uart_puts(char *s).

Además, siempre es una buena idea inicializar su variable, así: unsigned char Compare[COMPBUFSIZE] = {0}- de esa manera no obtiene resultados inesperados cuando el programa aún no escribió en la variable.

De forma predeterminada, stdout es el módulo UART. Entonces, también puede usar el estándar putsy putcharlas funciones para escribir una cadena o un carácter en el UART, como este: puts(Compare)o putchar(Compare[0]).

Si nada de esto funciona, te recomiendo que uses la printffunción. El compilador debería optimizar eso.

has usado

    fflush() 

para vaciar todos los datos? Los datos permanecen en el búfer a menos que haga esto. Tuve un problema similar.