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
Ihre Variable Compare
ist 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- puts
und putchar
Funktionen 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 printf
Funktion 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.
abdullah kahraman
rötlich
abdullah kahraman
Compare
, was beinhaltet es? Könntest du mehr Code zeigen?rötlich
abdullah kahraman
Compare
nicht mit irgendwelchen Werten initialisiert ist und nur gefüllt wird, wennCompIndex >= COMPBUFSIZE
. Versuchen Sie, ihm einige Dummy-Werte zuzuweisen, vielleicht bei der Initialisierung. Aber ich bin mir nicht sicher, ob dies das Problem ist.rötlich
abdullah kahraman
const
das Wort ausuart_puts()
dem Argument der Funktion zu entfernen. Sie sollten den Fehler in der Frage angeben.rötlich
abdullah kahraman