Отправка команды с помощью USART

Я новичок в таком виде общения. Я могу отправить команду с ПК на микроконтроллер AT90USB1287, а также получить ответ, используя связь USB. Теперь я подключил другой микроконтроллер (ATmega32) к этой плате через связь USART. Я пытаюсь отправить команду с ПК на эту плату. Оба контроллера имеют разные команды. Итак, я создал массив, содержащий команды обоих контроллеров в контроллере AT90USB1287. Моя концепция заключается в сравнении входящей команды с ПК со всеми командами в массиве на основе результата, который я пытаюсь отправить на контроллер ATmega32 с помощью USART. У меня есть код, как показано ниже.

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

в приведенном выше коде я могу получить ответ от USB-контроллера, но не от ATmega32A. Я проверяю индекс> 52 (USB_CMD_SIZE), затем отправляю на ATmega32, иначе отправляю на USB) = 1287.

Я получаю ошибку в этой строке

uart_putchar(Compare);

У меня есть такая функция для uart_putchar.

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

даже я пробовал так

  uart_puts(Compare);

для этого я написал так

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

Но у меня ничего не работает. Может ли кто-нибудь помочь мне, как это исправить? Нужна ли мне здесь какая-либо конверсия? Если это так, пожалуйста, помогите мне с примером.

Когда я использую этот код, я могу получить ответ от atmega32, но проблема в том, что этот код отправляет все команды на оба контроллера, поэтому в то время у меня возникла проблема, поэтому я пытаюсь использовать вышеуказанный.

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

этот код отправляет каждый символ на оба контроллера.

В Compare у меня есть такая команда, как «PSCAN».

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

эта строка печатается как

@PSCAN
USB901287, вероятно, AT90USB1287 .
@abdullahkahraman Да
Как вы определяете Compare, что в нем содержится? Не могли бы вы показать больше кода?
@abdullahkahraman конечно, я обновил, теперь взгляните на мой новый обновленный код.
Я вижу, что Compareон не инициализируется никакими значениями и заполняется только тогда, когда CompIndex >= COMPBUFSIZE. Попробуйте присвоить ему некоторые фиктивные значения, возможно, при инициализации. Но я не уверен, что это проблема.
@abdullahkahraman Я пробовал так, не работает. Я думаю, что это значение int, и я пытаюсь поместить символ, но я пытаюсь преобразовать это сравнение в строку, у вас есть идеи?
Извините, у меня нет другой идеи, кроме удаления constслова из uart_puts()аргумента функции. Вы должны указать ошибку, которую он дает в вопросе.
@abdullahkahraman Когда я отлаживаю, я вижу, что в «Сравнить» у меня есть команда типа «PSCAN». вы видите эту строку "printf("@%s\r\n",&Compare); //Подтвердить команду" там она печатает команду. Итак, &Comapare содержит команду, которую я пытаюсь выяснить, как ее отправить. Можете ли вы взглянуть на мое добавленное объяснение вопроса.
Я потерялся, извини. Я надеюсь, что кто-то может помочь вам с хорошим ответом! :)

Ответы (2)

Ваша переменная Compareпредставляет собой массив символов. Вы void uart_putchar(char ch)ожидаете char, а не массив char, поэтому вы не можете использовать его для печати Compare. Ваша функция void uart_puts(const char *s)ожидает массив символов, но также ожидает, что он будет постоянным! Возможно, вы захотите попробовать изменить это на void uart_puts(char *s).

Кроме того, всегда полезно инициализировать вашу переменную, например так: unsigned char Compare[COMPBUFSIZE] = {0}- таким образом вы не получите неожиданных результатов, когда программа еще не записывала в переменную.

По умолчанию стандартный вывод — это модуль UART. Таким образом, вы также можете использовать стандарт putsи putcharфункции для записи строки или символа в UART, например: puts(Compare)или putchar(Compare[0]).

Если ничего из этого не работает, я бы порекомендовал вам использовать эту printfфункцию. Компилятор должен это оптимизировать.

Вы использовали

    fflush() 

сбросить все данные? Данные остаются в буфере, если вы этого не сделаете. У меня была аналогичная проблема.