Senden von Befehlen mit USART

Ich bin neu in dieser Art der Kommunikation. Ich kann Befehle vom PC an den Mikrocontroller AT90USB1287 senden und über USB-Kommunikation eine Antwort erhalten. Jetzt habe ich einen anderen Mikrocontroller (ATmega32) über USART-Kommunikation an dieses Board angeschlossen. Ich versuche, Befehle vom PC an dieses Board zu senden. Beide Controller haben unterschiedliche Befehle. Also habe ich ein Array erstellt, das beide Controller-Befehle im AT90USB1287-Controller enthält. Mein Konzept ist, den eingehenden Befehl vom PC mit allen Befehlen im Array zu vergleichen, basierend auf dem Ergebnis, das ich versuche, Befehle mit USART an den ATmega32-Controller zu senden. Ich habe den Code wie unten gezeigt.

#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;
}
  }       
}

Im obigen Code kann ich eine Antwort vom USB-Controller erhalten, aber nicht von ATmega32A. Ich überprüfe, dass der Index> 52 (USB_CMD_SIZE) ist, dann an ATmega32 senden, sonst an USB senden) = 1287.

Ich bekomme Fehler in dieser Zeile

uart_putchar(Compare);

Ich habe die Funktion für uart_putchar so.

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

sogar ich habe es so versucht

  uart_puts(Compare);

dafür habe ich so geschrieben

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

Aber nichts funktioniert bei mir. Kann mir jemand helfen, wie ich das beheben kann? Brauche ich hier eine Umrechnung? Wenn ja, helfen Sie mir bitte mit einem Beispiel.

Wenn ich diesen Code verwende, kann ich eine Antwort von atmega32 erhalten, aber was das Problem war, ist, dass dieser Code alle Befehle an beide Controller sendet, also habe ich zu diesem Zeitpunkt ein Problem, also versuche ich das obige.

 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;
}
  }      
 }

Dieser Code sendet jedes einzelne Zeichen an beide Controller.

Im Vergleich habe ich den Befehl wie "PSCAN".

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

dieser Zeilendruck gefällt

@PSCAN
USB901287 ist wahrscheinlich ein AT90USB1287 .
@abdullahkahraman Ja
Wie definiert man Compare, was beinhaltet es? Könntest du mehr Code zeigen?
@abdullahkahraman Sicher, ich habe aktualisiert, schau dir jetzt meinen neuen aktualisierten Code an.
Ich sehe, dass das Comparenicht mit irgendwelchen Werten initialisiert ist und nur gefüllt wird, wenn CompIndex >= COMPBUFSIZE. Versuchen Sie, ihm einige Dummy-Werte zuzuweisen, vielleicht bei der Initialisierung. Aber ich bin mir nicht sicher, ob dies das Problem ist.
@abdullahkahraman Ich habe es so versucht, es funktioniert nicht. Ich denke an seinen int-Wert und ich versuche, Zeichen zu setzen, aber ich versuche, diesen Vergleich in eine Zeichenfolge umzuwandeln. Haben Sie eine Idee?
Entschuldigung, ich habe keine andere Idee, als constdas Wort aus uart_puts()dem Argument der Funktion zu entfernen. Sie sollten den Fehler in der Frage angeben.
@abdullahkahraman Wenn ich debugge, sehe ich, dass ich in "Compare" den Befehl "PSCAN" habe. Sie sehen, dass diese Zeile "printf("@%s\r\n",&Compare); //Ack command" ist, dort wird der Befehl ausgegeben. &Comapare enthält also den Befehl, den ich versuche herauszufinden, wie ich das senden soll. Können Sie sich meine hinzugefügte Erklärung zur Frage ansehen?
Ich bin verloren, tut mir leid. Ich hoffe jemand kann dir mit einer guten Antwort weiterhelfen! :)

Antworten (2)

Ihre Variable Compareist ein Array von Zeichen. Sie void uart_putchar(char ch)erwarten ein Zeichen, kein Zeichenfeld, also können Sie dieses nicht zum Drucken verwenden Compare. Ihre Funktion void uart_puts(const char *s)erwartet ein char-Array, erwartet aber auch, dass es konstant ist! Vielleicht möchten Sie versuchen, das zu ändern void uart_puts(char *s).

Außerdem ist es immer eine gute Idee, Ihre Variable wie folgt zu initialisieren: unsigned char Compare[COMPBUFSIZE] = {0}- Auf diese Weise erhalten Sie keine unerwarteten Ergebnisse, wenn das Programm noch nicht in die Variable geschrieben hat.

Standardmäßig ist stdout das UART-Modul. Sie können also auch die Standard- putsund putcharFunktionen verwenden, um eine Zeichenfolge oder ein Zeichen wie folgt in den UART zu schreiben: puts(Compare)oder putchar(Compare[0]).

Wenn nichts davon funktioniert, würde ich Ihnen empfehlen, die printfFunktion zu verwenden. Der Compiler sollte das optimieren.

Haben Sie ... benutzt

    fflush() 

um alle Daten auszuspülen? Die Daten bleiben im Puffer, es sei denn, Sie tun dies. Ich hatte ein ähnliches Problem.