Siéntete en la libertad de divulgar nuestro sitio y códigos en tus redes sociales, danos de tu ayuda para hacer crecer esta comunidad.
Solución:
** EDITAR 19/06/2012 *************************************** *****************
Ok, luego de que agregaste tu código, hice algunos cambios para que los pruebes (¡y los entiendas!)
En primer lugar, hemos declarado nuestro carácter. array volátil para que el compilador sepa que puede cambiar inesperadamente debido a una interrupción. Asimismo, hemos creado una variable para realizar un seguimiento de nuestra posición en el índice en el array:
/**************************************************
* Global Variables
*/
int trigger=0, length=0;
int i=0, n=0;
uint8_t data;
volatile char arr[8];
volatile char arr_idx = 0;
A continuación, he editado su código de inicialización UART basado en la hoja de datos ATMega16L y sus comentarios:
//USART SETUP
UCSRA = 0x00; //no Frame Error, no parity error, no Data OverRun
UCSRB = 0xD8; //receiver enable, transmitter enable (0x18)
UCSRC = 0x86; //Asynchronous USART mode, no parity, 1 stop bit, 8-bit character size, Data transmitted on rising edge and received on falling edge of the clock
UBRRL = 51; //Baud rate of 9600bps (8MHz clock?)
UBRRH = 0;
Mire de cerca la hoja de datos (página ~ 166). Creo que he configurado correctamente el UART ahora en función de sus comentarios. No voy a repasar cada bit, pero deberías. Haga preguntas si cree que cometí un error o si no obtiene algo.
Finalmente, he editado su rutina ISR:
ISR(USART_RXC_vect)
arr[arr_idx] = UDR;
arr_idx++;
arr_idx %= 7; //make sure index stays within array
trigger = 1;
Tenga en cuenta que el ISR se ejecuta cada vez que se recibe un solo byte (o carácter). Esto significa que queremos procesar el carácter único (agréguelo a nuestro array), incrementamos la ubicación de nuestro índice y salimos de él rápidamente para que estemos listos para que entre el siguiente carácter.
Ahora necesitas mirar el arr[] a través de cualquier método que haya estado usando y vea si ahora está recibiendo sus personajes correctamente.
** FIN DE EDICIÓN **************************************
Una opción es usar una de las bibliotecas disponibles incluidas en AVR Studio:
#include
y luego en algún lugar de su código …
char num2[5]; //create a buffer for the ascii string
itoa(num1,num2,10); //convert the integer (num1) to an ascii string (num2) in base 10
Si luego está mostrando esto en una pantalla LCD de caracteres, puede enviar el num2 array a la función de impresión lcd que está utilizando.
Si le preocupa el espacio de código, puede escribir con bastante facilidad su propia función simple itoa (entero a ascii). Deberá tomar cada posición “decenas” de su número entero usando los operadores “/” y “%” y convertirlo a ascii:
(fuente: asciitable.com)
En la tabla anterior, puede ver que una vez que tome el valor de cada dígito (0-9), simplemente agregue 48 para convertirlo en la representación de caracteres ascii.
EDITAR
Bien, luego de agregar su información y asumir:
- Ha inicializado correctamente la velocidad en baudios UART, etc.en su ATMEGA
- El código de Android está enviando correctamente los bytes ascii a través de WiFly y fuera de su UART
Entonces, el microcontrolador ya debería recibir estos caracteres como Ascii, y la función ITOA no es lo que se necesita aquí y, de hecho, estropearía su string datos que ingresan.
Sin embargo, podrían ser muchas cosas diferentes … ¿Cómo ve los datos de uart que recibe su microcontrolador?
Un carácter ASCII es simplemente un número de 8 bits que se muestra como un carácter cuando llama a funciones como “printf” que están destinadas a mostrar caracteres.
En C, un string es un array de estos caracteres (o números de 8 bits) que terminan con el valor 0
o “null-terminado”.
Entonces, cuando envías un string como “Eclipse”, ya estás enviando números. De hecho, así es como se ve cuando lo envía:
[69, 99, 108, 105, 112, 115, 101, 0]
Pasando esto a printf
, por ejemplo, imprimirá “Eclipse”. Nota la null-terminador. También tenga en cuenta que no necesita ninguna función para convertir esto.
itoa
es una función que se utiliza para convertir números a su string representación. Por ejemplo:
char str[32];
itoa(223, str, 10);
printf("%s", str);
Esto imprimiría “223”. Los valores numéricos reales que residen en str[]
que sabemos con certeza: [50, 50, 51, 0]
. Por tu descripción, estoy bastante seguro de que esto no es lo que quieres.
No asuma siempre ASCII codificación. Aquí hay una codificación de caracteres muy utilizada a nivel de aplicación y desarrollo web: UTF-8: estos caracteres no siempre son de 8 bits, algunos de ellos son de 16 bits para representar caracteres en otros idiomas, por ejemplo.
EDITAR:
Hay algo que necesita saber sobre un periférico UART típico en un AVR (no pretende ser una declaración general para todos los UART en todos los uC, solo la familia que está utilizando). Funcionan así: cuando entra un byte, se coloca en una ubicación de memoria de un solo byte: UDR
– Cuando haga una lectura de este registro, se borrará. ¿Si ingresan nuevos datos en la UART y aún no ha leído de este registro? Se sobrescribirá con el nuevo valor. Aquí no se colocarán cadenas enteras. Solo personajes individuales. Todo esto se describe en la hoja de datos de su uC, le recomiendo que se familiarice con él.
Con suerte, eso le dará suficiente información para comprender por qué strlen(data)
no funcionará. Si aún no está seguro de por qué, lea la hoja de datos, lea lo que sucede cuando realiza esta tarea en C data = UDR;
y también leer lo que strlen
Los parámetros son, y tenga en cuenta que uno de ellos es un puntero a un string. Si no tiene un buen conocimiento de los punteros, le sugiero encarecidamente esto: http://www.cplusplus.com/doc/tutorial/pointers/
Si todo esto le parece demasiado trabajo, le sugiero que elija un Arduino. No me malinterpretes, sería increíble si pudieras comprender todo esto y usar C simple en tu AVR, pero si hay demasiadas lagunas en tu conocimiento en este momento, entonces puede ser un poco abrumador.
Ahora, pasemos a lo que desea lograr. Mencionaste en tu comentario que querías hacer un bucle hasta que obtengas un string fuera del UART, almacenándolo en un búfer, donde luego lo procesará como un comando. Está bien. Totalmente factible, de hecho, una técnica algo común.
Aquí hay un código psuedo para ti:
i = 0;
char str[32];
while(forever)
if (data_byte_is_available)
if (i == 31)
i = 0;
str[i] = UDR;
i++;
print(str);
Trate de averiguar qué debe hacer para un data_byte_is_available
función. La hoja de datos es tu amiga. Además, ¿cómo muestra lo que ingresa en el UART de la uC? Sea lo que sea, sustituya el print
Tengo ahí arriba con eso. Espero que no haya problemas con lo que esté usando allí …
Puntuaciones y reseñas
Al final de todo puedes encontrar las críticas de otros creadores, tú igualmente puedes insertar el tuyo si lo crees conveniente.