Mandando comando usando USART

1

Soy nuevo en este tipo de comunicación. Soy capaz de enviar comandos desde la PC al microcontrolador AT90USB1287, así como obtener respuesta a través de 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 el comando desde la PC a este tablero. 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 una matriz según el resultado que estoy intentando 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]='
uart_putchar(Compare);
'; 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 respuesta del controlador USB pero no de ATmega32A. Estoy comprobando que el índice es > 52 (USB_CMD_SIZE) y luego enviarlo a ATmega32, de lo contrario enviarlo a USB) = 1287.

Estoy recibiendo un error en esta línea

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

Tengo la función para uart_putchar de esta manera.

  uart_puts(Compare);

Incluso lo intenté así

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

para eso he escrito así

 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]='
printf("@%s\r\n",&Compare); //Ack command
'; // 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; } } }

Pero nada está funcionando para mí. ¿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.

@PSCAN

este código está enviando todos y cada uno de los caracteres a ambos controladores.

En Comparar tengo el comando como "PSCAN".

#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]='
uart_putchar(Compare);
'; 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; } } }

esta línea se imprime como

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

2 respuestas

2

Su variable Compare es una matriz de caracteres. Su void uart_putchar(char ch) espera un carácter char, no una matriz char, 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 espera que también sea constante! Es posible que desee intentar cambiar eso a void uart_puts(char *s) .

Además, siempre es una buena idea inicializar tu variable, como esto: unsigned char Compare[COMPBUFSIZE] = {0} : de esa manera no obtendrás resultados inesperados cuando el programa no haya escrito aún en la variable.

Por defecto, stdout es el módulo UART. Por lo tanto, también puede usar las funciones estándar puts y putchar para escribir una cadena o un carácter en el UART, como esto: puts(Compare) o putchar(Compare[0]) .

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

    
respondido por el Keelan
0

Has usado

    fflush() 

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

    
respondido por el Ravin

Lea otras preguntas en las etiquetas