Soy nuevo en este tipo de comunicación. Puedo enviar comandos desde la PC al microcontrolador AT90USB1287 y también puedo obtener una respuesta mediante 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 un comando desde la PC a esta placa. 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 la matriz según el resultado. Estoy tratando de 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]='\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;
}
}
}
en el código anterior, puedo obtener una respuesta del controlador USB pero no de ATmega32A. Estoy comprobando que el índice es > 52 (USB_CMD_SIZE) y luego lo envío a ATmega32; de lo contrario, lo envío a USB) = 1287.
me sale error en esta linea
uart_putchar(Compare);
Tengo la función para uart_putchar así.
void uart_putchar (char ch)
{
while(!Uart_tx_ready());
Uart_set_tx_busy(); // Set Busy flag before sending (always)
Uart_send_byte(ch);
return;
}
incluso lo intenté así
uart_puts(Compare);
por eso he escrito asi
void uart_puts(const char *s)
{
while(*s)
{
uart_putchar(*s++);
// printf("*");
}
}
Pero nada me funciona. ¿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.
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;
}
}
}
este código envía todos y cada uno de los caracteres a ambos controladores.
En Compare tengo el comando como "PSCAN".
printf("@%s\r\n",&Compare); //Ack command
esta línea imprimiendo como
@PSCAN
Su variable Compare
es una matriz de caracteres. Espera void uart_putchar(char ch)
un carácter, no una matriz de caracteres, 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 también espera que sea constante! Es posible que desee intentar cambiar eso a void uart_puts(char *s)
.
Además, siempre es una buena idea inicializar su variable, así: unsigned char Compare[COMPBUFSIZE] = {0}
- de esa manera no obtiene resultados inesperados cuando el programa aún no escribió en la variable.
De forma predeterminada, stdout es el módulo UART. Entonces, también puede usar el estándar puts
y putchar
las funciones para escribir una cadena o un carácter en el UART, como este: puts(Compare)
o putchar(Compare[0])
.
Si nada de esto funciona, te recomiendo que uses la printf
función. El compilador debería optimizar eso.
has usado
fflush()
para vaciar todos los datos? Los datos permanecen en el búfer a menos que haga esto. Tuve un problema similar.
abdullah kahraman
rojizo
abdullah kahraman
Compare
, qué contiene? ¿Podrías mostrar más código?rojizo
abdullah kahraman
Compare
no se inicializa con ningún valor y solo se llena cuandoCompIndex >= COMPBUFSIZE
. Intente asignarle algunos valores ficticios, tal vez en la inicialización. Pero no estoy seguro si este es el problema.rojizo
abdullah kahraman
const
la palabra deluart_puts()
argumento de la función. Debe dar el error que está dando en la pregunta.rojizo
abdullah kahraman