Я новичок в таком виде общения. Я могу отправить команду с ПК на микроконтроллер 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
Ваша переменная 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()
сбросить все данные? Данные остаются в буфере, если вы этого не сделаете. У меня была аналогичная проблема.
Абдулла Кахраман
красный
Абдулла Кахраман
Compare
, что в нем содержится? Не могли бы вы показать больше кода?красный
Абдулла Кахраман
Compare
он не инициализируется никакими значениями и заполняется только тогда, когдаCompIndex >= COMPBUFSIZE
. Попробуйте присвоить ему некоторые фиктивные значения, возможно, при инициализации. Но я не уверен, что это проблема.красный
Абдулла Кахраман
const
слова изuart_puts()
аргумента функции. Вы должны указать ошибку, которую он дает в вопросе.красный
Абдулла Кахраман