TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: ayala08 en 27 de Septiembre de 2006, 17:56:24
-
Hola a todos!!! … me encuentro realizando un proyecto con un PIC 16f876a, este consiste en recibir datos provenientes de un tensiómetro digital y de un GPS (A1029-B), de forma serial RS232, la velocidad de transmisión del tensiómetro 9600 baudios sin BIT de paridad ni nada, y pues el GPS tiene su propio protocolo que en el momento no he empezado a mirar debido a que tengo un problema con la transmisión de los datos del tensiómetro al pic. Bueno para no dar mas vueltas el problema es este:
El codigo que estoy usando es el siguiente el cual lo saque de este foro y pues lo altere para mi aplicación, no mucho pero algo lo altere (Que pena el plagio pero me servia):
#include <16F876a.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOCPD
#use delay(clock=4000000)
//#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B0,bits=8,stream=PC,errors)
#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B0,stream=PC2,errors)
//
// baud=38400 maximo usando 4 Mhz
//
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
/* Definicion de buffers para recivir los chars de los puertos PC/PC2 */
#define BUFFER_SIZE2 30 //Tamaño del buffer...depende de la aplicación que queramos.
BYTE buffer2[BUFFER_SIZE2];
BYTE next_in2 = 0; //posición del siguiente carácter de entrada
BYTE next_out2 = 0; //posición del siguiente carácter de salida
ext_isr() {
int t2;
buffer2[next_in2]=fgetc(PC2); // Guarda datos provenientes de PC
t2=next_in2; // en buffer2[];
next_in2=(next_in2+1) % BUFFER_SIZE2;
if(next_in2==next_out2)
next_in2=t2; // Buffer lleno !!
}
char b_getc_2() {
char c2;
while(!b_kbhit_2);
//while(next_in2!=next_out2) ;
c2=buffer2[next_out2];
next_out2=(next_out2+1) % BUFFER_SIZE2;
return (c2);
}
/*************** Rutina Principal ************************/
void main() {
ext_int_edge(H_TO_L); // Habilita interrupcion por flanco H_to_L
// que corresponde a la transision del Start
// bit del protocolo RS232.
enable_interrupts(INT_EXT); // Habilita interrupcion externa en RB0 (rcv=PIN_BO)
enable_interrupts(GLOBAL); // Habilita interrupciones global
fprintf(PC2,"Probando PC2\n\r");
while(1) { // LOOP infinito
fprintf(PC2,"\r\n\Andando...\r\n");
// El programa imprime en el puerto PC lo que recibe en el buffer del puerto PC2
// y viceversa. El buffer es circular (tamaño de 30 bytes)
while(1) {
if(b_kbhit_2) { // Si hay datos provenientes de PC,
fputc(b_getc_2(),PC2); // enviar los char a PC2
}
}
} // FIN funcion de LOOP infinito
}
Bueno el caso es que si yo le mando datos desde el tensiómetro al PC por el hyperterminal me captura la trama muy bien la cual es M1010601060222107055068M200 (por ejemplo) los cuadrados son un 0000 0010 al comienzo y un 0000 0011 al final de la trama… cuando corro el programa usando el debugger de mplab me captura solo un pedazo de la trama 060222107055068M200 (por ejemplo) y después cuando le mando otro dato me captura basura y así con la siguiente vez que le digo que capture datos… a la cuarta vez me empieza capturar “bien” entre comillas por que me captura como la primera vez. 060222107055068M200 lo que esta mal, entonces quisiera saber por que pasa esto, por que no me captura toda la trama, … por otro lado cuando uso interrupciones tipo rda si me captura bien. ¿Por que ?.
Otra pregunta que tengo es como hago para que me reciba de esta forma como lo hago (carácter por carácter) y me los guarde todos en una sola variable para poderla manipular y concatenarla con la trama que me mande el GPS yo se que las funciones en C para concatenar ya existen, pero no he logrado meter los datos en una variable, me gustaría saber como hacerlo.
Para finalizar quisiera decir que este es un EXELENTE foro, yo no pensé que pudiera aprender tanto con los datos y ejemplos que han puesto en el foro, repito EXELENTE, y le agradezco mucho a la gente que se interesa de una buena manera en que otros aprendamos. Gracias !!!
-
Hola Ayala08, yo quizás no te pueda ayudar mucho pues no tengo mucha experiencia y si hay foristas que la tienen, pero te apuntaré algún detalle porque estoy con un tema parecido al tuyo. Puedes ver mi post más abajo "sos control de buffer".( está cono el nombre de santipic_09)
Yo necesitaba leer una trama larga por un puerto y enviarla por otro, pero lo básico, entiendo yo, es que debes leer primero esa trama usando sólo un puerto y enviandola al PC, así comprobaras que el buffer te funciona correctamente.
Ese puerto serie debe leer datos y almacenarlos en un buffer( matríz). Despues debes scanear el caracter por el que empieza tu trama ( si es que empieza siempre por el mismo) hasta el último caracter de la misma, luego haces un printf y ves si sale toda por el hyperter.
De todas maneras, a lo mejor ya has hecho esta prueba.
Bueno , siento no poder darte más ayuda, pero aquí hay gente muy buena que sin duda te indicaran algo.
Saludos a todos.
-
Otro consejo, si usas interrupciones manten las rutinas de interrupción pequeñas.
Tu código es corto pero haces varios cálculos y no es aconsejable ese tipo de operatoria.
Yo que tu primero probaría un software más simple y sobre el bucle principal del programa.
Recibes un dato y lo retransmites, sin hacer un buffer de nada.
Ten en cuenta que las usart por software tienen serias limitaciones.
Saludos
-
¡Hola a todos! ...
Primero quiero agradecer sus respuestas y lo rápido que me las dieron… nunca pensé que la respuesta fuera tan rápida de verdad muchas gracias santi.sl y maunix.
Bueno primero, decidí tomar el consejo de maunix y mejor usar la usart, el tiene razón es mejor tener menos problemas… así que mirando el programa usado por santi.sl en el post “sos en control de buffer” y pues tratándolo de implementar para mi caso… tengo varias preguntas:
La primera es, por que en la parte del código donde se evalúa si la bandera de ejecución de comando esta en uno, es decir:
1. do {
2. if(flagcommand) procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
3. printf("..\r"); // printf CR
4. } while (TRUE);
Por que no se hace agregando {} en el if :
1. do {
2. if(flagcommand) {
3. procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
4. printf("..\r");} // printf CR
5. } while (TRUE);
Yo lo probé y la diferencia es que no se queda mostrando los dos puntos en un loop, si no que espera a que uno le de enter y aparecen lo dos puntos y se queda esperando algo. La verdad no entiendo cuando le debo mandar los datos, después de darle enter o antes, pero igual lo que entendí es que el interrumpe, guarda en el buffer para comparar el caso de los comandos, ejecuta el comando si es correcto y debería mostrar los datos que captura, igual no se cuando decirle que me capture la trama.
La segunda es si importa el pic yo uso un 16f876a y el del ejemplo es un 18f 2550. que problema tendría que mirar?, de pronto es necesario cambiar las direcciones 0x4A o no es necesario.
La tercera es, ¿que se entiende por argumento? en este caso son los datos como tal o el numero de datos, o ninguna de las anteriores?
Yo se que para alguien experimentado mis preguntas son muy simples o triviales, pero la verdad estoy en el proceso de aprendizaje, les agradecería que me dieran una mano.
Muchas gracias
-
La primera es, por que en la parte del código donde se evalúa si la bandera de ejecución de comando esta en uno, es decir:
1. do {
2. if(flagcommand) procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
3. printf("..\r"); // printf CR
4. } while (TRUE);
Por que no se hace agregando {} en el if :
1. do {
2. if(flagcommand) {
3. procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
4. printf("..\r");} // printf CR
5. } while (TRUE);
Yo lo probé y la diferencia es que no se queda mostrando los dos puntos en un loop, si no que espera a que uno le de enter y aparecen lo dos puntos y se queda esperando algo.
Bueno fijate la diferencia.
En el primer caso, no pusiste corchetes a la condicion IF.
Muchos lenguajes soportan que se ignoren los corchetes en ciertas situaciones.
Si no colocas los corchetes, el programa va a tomar el primer algoritmo de esta manera:
1. do {
2. if(flagcommand){ procesa_comando();} // Si hay comando pendiente de procesar ... lo procesa.
3. printf("..\r"); // printf CR
4. } while (TRUE);
Lo que es muy distinto al segundo algoritmo:
1. do {
2. if(flagcommand) {
3. procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
4. printf("..\r");} // printf CR
5. } while (TRUE);
Entonces, miremos logicamente como funciona cada uno:
El primer algoritmo:
REPETIR:
SI flagcommand=Verdadero ENTONCES procesa_comando()
printf ("..\r")
MIENTRAS(VERDADERO)
El segundo algoritmo:
REPETIR:
SI flagcommand=Verdadero ENTONCES procesa_comando() Y printf ("..\r")
MIENTRAS(VERDADERO)
Entonces, el primer algoritmo ejecutara la instruccion printf("..\r"); independientemente de si se cumple o no la condicion del IF.
El segundo algoritmo sólo ejecutara la instruccion printf("..\r"); si la condicion propuesta en el IF se cumple.
La tercera es, ¿que se entiende por argumento? en este caso son los datos como tal o el numero de datos, o ninguna de las anteriores?
Argumento podria explicarse, para lo que creo que estas buscando, como toda expresion que puede ser pasada a una funcion(o devuelta por la mísma) por valor o por referencia.
Ejemplo de pasaje por valor:
void mi_funcion(int numero)
{
////Codigo aqui
}
Si llamamos ala funcion de esta manera:
mi_funcion(12);
El valor que adoptara la variable numero es 12.
En cambio si hacemos:
int cantidad=15;
void mi_funcion(int numero)
{
////Codigo aqui
}
Si llamamos ala funcion de esta manera:
mi_funcion(cantidad);
El valor que adoptara la variable numero es 15.
En este caso, el valor fue pasado por referencia, es decir que se paso una variable a la funcion, y la funcion tomo el valor de dicha variable para utilizarlo en la funcion.
Espero haya quedado un poco claro.
Saludos.
-
Hola a todos, pues bien Ayala 08 algunas preguntas ya te han sido contestadas pero te diré, con la poca experiencia que tengo, los datos que me entrar del gps no tengo ningun problema ya que están entrando continuamente. Además al final estas tramas traen un 0x0D o sea CR.
La primera vez que lo probé me mostraba una vez la trama y despues tenía que apagar y encender el circuito y entonces he añadido esos dos puntos como referencia para visualizar cuantas veces pasaba el programa por allí , sé que aún no está totalmente limpia la trama y estoy mejorándola porque tiene además un pequeño retardo que al llevar estos puntos casi no te das cuenta , pero de momento con los dos puntos a mi me sirve y por lo menos ya he podido meter datos en un buffer, scanear el carácter que deseo y recuperar una trama.
Con respecto al cambio de pic, creo que tan sólo tienes que sustituir la cabecera, es decir, poner la que tienes ya que el patillaje coincide, aunque deberias hacerlo primero con el puerto físico y despues con los dos.
-
Ah, se me olvidó comentarte que por ser un tema importante, lo del puerto y el control del buffer, le había indicado a REd_Pic , sí podía realizará una versión nueva de este ejemplo.
Yo lo poco que he hecho en este tema fué con el ejemplo de Red_Pic, otra parte de Nocturno y alguna aclaración de Badtzdizzy. De todas maneras seguro que te apareceran más respuestas.
Saludos
-
Y tienes otro ejemplo de rs232 en el subforo de telefonia, gps y microcontroladores, publicado por Badtzdizzy.
Chao
-
Hola a todos!!! muchas gracias por sus respuestas, me han quedado muy claras las respuestas que medieron brunof y santi.sl.
Bueno en el momento me encuetro desarrollando el programa con sus ayudas, pero me surgen nuevas preguntas.
Como les habia comentado, el proyecto consiste en recibir datos con el pic del tensiometro digital y del gps para luego ser enviados por Gprs, se que la comunicacion del tensiometro es unidireccional, la del gps es unidireccional. por lo tanto la pregunta es si esto se podria implementar con un solo pic, su usart y definir varias transmiciones por software y pues teniendo en cuenta las limitaciones que esto lleva (no se si aguanten el tamaño de las tramas si se definen por sofware), o si es mejor implementarlo con un pic de dos puertos seriales en hardware y aprovechar que son comunicaciones unidireccionales e implementar un mux en hardware o en el mismo pic (si esto se puede hacer les agradeceria mucho que me dijeran como) para atenderlas. O la otra opcion es implementarlo con dos pics que tengan un solo puerto serial en hardware y hacer que se comuniquen, pero igual necesitaria un mux para la comunicacion. me gustaria que me aconsejaran sobre la implementacion y que me dijeran si conocen algun pic de dos puertos accesible o una solucion mas sencilla y me dieran una mano.
gracias
saludos
-
:-/ Hola a todos nuevamente!! Queria contarles que el programa que santi.sl me recomendo me esta funcionando correctamente para el tensiometro.
GRACIAS SANTI.SL
PD: sigo con la pregunta anterior :D
-
Como les habia comentado, el proyecto consiste en recibir datos con el pic del tensiometro digital y del gps para luego ser enviados por Gprs, se que la comunicacion del tensiometro es unidireccional, la del gps es unidireccional. por lo tanto la pregunta es si esto se podria implementar con un solo pic, su usart y definir varias transmiciones por software y pues teniendo en cuenta las limitaciones que esto lleva (no se si aguanten el tamaño de las tramas si se definen por sofware), o si es mejor implementarlo con un pic de dos puertos seriales en hardware y aprovechar que son comunicaciones unidireccionales e implementar un mux en hardware o en el mismo pic (si esto se puede hacer les agradeceria mucho que me dijeran como) para atenderlas. O la otra opcion es implementarlo con dos pics que tengan un solo puerto serial en hardware y hacer que se comuniquen, pero igual necesitaria un mux para la comunicacion. me gustaria que me aconsejaran sobre la implementacion y que me dijeran si conocen algun pic de dos puertos accesible o una solucion mas sencilla y me dieran una mano.
Mira, habría que analizar cada caso. Para mí las usart por software funcionan cuando tú decides cuando enviar el dato y el dispositivo te responde de inmediato, al menos las usart por software convencionales.
Si tienes una usart por software y otra por hardware, ten en cuenta que la usart por software se vale de algún sistema de polling basado gralmente en un timer o sencillamente en el conteo de instrucciones sin hacer nada.
Todo esto conlleva multiples limitaciones y a la gran chance de que te venga un dato y que justo el pic esté haciendo "otra cosa".
Si los datos que recibes son unidireccionales pero nunca dejan de venir, entonces mi consejo es que no te líes demasiado y uses 2 usart por hardware.
No digo que sea imposible con usart por software pero realmente debieras tener un polling muy preciso, un par de buffers separados para cada usart y que tu aplicación no se meta en ningún recoveco que le demore más que unos pocos microsegundos.
Hay optimizaciones como la de usar la interrupción del puerto RB0 y cosas por el estilo, pero te repito que hay que conocer bien lo que uno quiere hacer y el cómo.
Saludos
-
Hola a todos, no hay de que Ayala 08, con respecto a usar las dos usart precisamente acababa de plantear una pregunta en otro post y ya me la contestó Maunix ( por cierto Maunix no habia leido este post antes).
Yo estoy con el tema tambien, seguiré haciendo unas pruebas y sino me pasaré a un pic de dos uart.
Cualquier novedad que tengo, da por seguro que la pasaré aquí.
Saludos desde A Coruña, España.
-
hola a todos!!! les comento que logre hacer que me funcionara el programa de santi.sl para recibir los datos del tensiometro, pero ahora usando una interrupcion externa RB, bueno realmente no es gran cosa , lo unico que hice fue cambiar la definicion de la interrupcion rda por RB, pero me funciona, bueno y con esto cambia el panorama, ahora que se puedo usar una uart y la usart del pic, el diseño cambia, y con esto surge un nuevo problema,
lo que hice fue habilitar dos interrupciones una rda y la otra rb, y pues el problema es que al poner:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use rs232(baud=9600, xmit=PIN_B4, rcv=PIN_B5)
la comunicacion se daña y no me recibe datos el pic.
el programa es este:
#include <16f876a.h> // Definiciones del PIC 18F2550
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
// Los Fuses de siempre
#use delay(clock=4000000) // Oscilador a 4Mhz
#include <stdlib.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // RS232 Estándar
#use rs232(baud=9600, xmit=PIN_B4, rcv=PIN_B5)
// CONSTANTES /////////////////////////////////////////////////////////////////
int const lenbuff2=28; // Longitud de buffer, Ajustar
// a lo que desees (o te sea posible)
int const lenbuff=28; // Longitud de buffer, Ajustar
// a lo que desees (o te sea posible)
// VARIABLES EN RAM ///////////////////////////////////////////////////////////
int xbuff2=0x00; // Índice: siguiente char en cbuff
char cbuff2[lenbuff2]; // Buffer
char rcvchar2=0x00; // último caracter recibido
int1 flagcommand2=0; // Flag para indicar comando disponible
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último caracter recibido
int1 flagcommand=0; // Flag para indicar comando disponible
// Declaración de Funciones ///////////////////////////////////////////////////
void inicbuff2(void); // Borra buffer
int addcbuff2(char c2); // añade caracter recibido al buffer
void echos2(char c2); // Eco selectivo sobre RS232
void procesa_comando2(void); // Procesa comando
void inicbuff(void); // Borra buffer
int addcbuff(char c); // añade caracter recibido al buffer
void echos(char c); // Eco selectivo sobre RS232
void procesa_comando(void); // Procesa comando
// INTERRUPCIONES /////////////////////////////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
rcvchar=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer y ...
}
}
#INT_RB
void serial_isr2() { // Interrupción recepción serie USART
rcvchar2=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar2=getc(); // lo descargo y ...
addcbuff2(rcvchar2); // lo añado al buffer y ...
}
}
// Desarrollo de Funciones ////////////////////////////////////////////////////
int addcbuff2(char c2){ // Añade a cbuff -----------------------
switch(c2){
case 0x03: // Enter -> Habilita Flag para procesar
flagcommand2=1; // Comando en Main
break;
default:
cbuff2[xbuff2++]=c2; // Añade caracter recibido al Buffer
}
}
void inicbuff2(void){ // Inicia a \0 cbuff -------------------
int i;
for(i=0;i<lenbuff2;i++){ // Bucle que pone a 0 todos los
cbuff2=0x00; // caracteres en el buffer
}
xbuff2=0x00; // Inicializo el indice de siguiente
// caracter
}
int addcbuff(char c){ // Añade a cbuff -----------------------
switch(c){
case 0x03: // Enter -> Habilita Flag para procesar
flagcommand=1; // Comando en Main
break;
default:
cbuff[xbuff++]=c; // Añade caracter recibido al Buffer
}
}
void inicbuff(void){ // Inicia a \0 cbuff -------------------
int i;
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
cbuff=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente
// caracter
}
// Programa Principal /////////////////////////////////////////////////////////
void main() {
printf("\r\n\** prueba buffer **\r\n\r\n"); // Presenta menú
enable_interrupts(int_rda); // Habilita Interrupción RDA
//enable_interrupts(int_rb); // Habilita Interrupción RB
enable_interrupts(global); // Habilita interrupciones
do {
if(flagcommand){
procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
//printf("..\r"); // printf CR
}} while (TRUE);
do {
if(flagcommand)
procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
//printf("..\r"); // printf CR
} while (TRUE);
}
// Procesador de Comandos /////////////////////////////////////////////////////
void procesa_comando(void){
int i, j;
char salida[lenbuff]; // Argumento de comando (si lo tiene)
disable_interrupts(int_rda);
flagcommand=0; // Desactivo flag de comando pendiente.
j=0;
for (i=0;i<xbuff;i++){
if (cbuff == '') // el caracter que buscon en la trama del tensiometro
while((cbuff != 0x4A) & (i<xbuff))
{
salida[j++]=cbuff[i++];
printf ("%c",salida[j-1]); // Monitorizamos el argunmento.
}
i++;
}
inicbuff(); // Borro buffer.
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
salida=0x00; // caracteres en el argumento
}enable_interrupts(int_rda);
}
void procesa_comando2(void){
int i, j;
char salida2[lenbuff2]; // Argumento de comando (si lo tiene)
disable_interrupts(int_rb);
flagcommand2=0; // Desactivo flag de comando pendiente.
j=0;
for (i=0;i<xbuff2;i++){
if (cbuff2 == '') el caracter que busco del gps
while((cbuff2 != 0x4A) & (i<xbuff2))
{
salida2[j++]=cbuff2[i++];
printf ("%c",salida2[j-1]); // Monitorizamos el argunmento.
}
i++;
}
inicbuff2(); // Borro buffer.
for(i=0;i<lenbuff2;i++){ // Bucle que pone a 0 todos los
salida2=0x00; // caracteres en el argumento
}enable_interrupts(int_rb);
}
bueno otra pregunta: es necesario declarar cada funcion, pues cada addbuffer y demas para cada comunicacion??
bueno por ahora es todo, les agradeceria una mano, a y gracias Maunix por la respuesta, y a santi.sl que nos ha ayudado demasiado.
saludos
-
hola a todos!!! modifique un poco el programa anterior, y las dos interrupciones se encuentran habilitadas, si se genera solo interruipcion por rb funciona correctamente, pero al interrumpir por rda no funciona, hay algun parametro que se necesite para funcionar con las dos habilitadas ,
el programa esta asi:
#include <16f876a.h> // Definiciones del PIC 18F2550
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
// Los Fuses de siempre
#use delay(clock=4000000) // Oscilador a 4Mhz
#include <stdlib.h>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // RS232 Estándar
#use rs232(baud=9600, xmit=PIN_B4, rcv=PIN_B5)
// CONSTANTES /////////////////////////////////////////////////////////////////
int const lenbuff=28; // Longitud de buffer, Ajustar
int const lenbuff2=28; // a lo que desees (o te sea posible)
// VARIABLES EN RAM ///////////////////////////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último caracter recibido
int1 flagcommand=0; // Flag para indicar comando disponible
int xbuff2=0x00; // Índice: siguiente char en cbuff
char cbuff2[lenbuff2]; // Buffer
char rcvchar2=0x00; // último caracter recibido
int1 flagcommand2=0;
// Declaración de Funciones ///////////////////////////////////////////////////
void inicbuff(void); // Borra buffer
int addcbuff(char c); // añade caracter recibido al buffer
void echos(char c); // Eco selectivo sobre RS232
void procesa_comando(void); // Procesa comando
void inicbuff2(void); // Borra buffer
int addcbuff2(char d); // añade caracter recibido al buffer
void echos2(char d); // Eco selectivo sobre RS232
void procesa_comando2(void); // Procesa comando
// INTERRUPCIONES /////////////////////////////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
rcvchar=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer y ...
}
}
#int_rb
void serial_isr2() { // Interrupción recepción serie USART
rcvchar2=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar2=getc(); // lo descargo y ...
addcbuff2(rcvchar2); // lo añado al buffer y ...
}
}
// Desarrollo de Funciones ////////////////////////////////////////////////////
int addcbuff(char c){ // Añade a cbuff -----------------------
switch(c){
case 0x03: // Enter -> Habilita Flag para procesar
flagcommand=1; // Comando en Main
break;
default:
cbuff[xbuff++]=c; // Añade caracter recibido al Buffer
}
}
void inicbuff(void){ // Inicia a \0 cbuff -------------------
int i;
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
cbuff=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente
// caracter
}
int addcbuff2(char d){ // Añade a cbuff -----------------------
switch(d){
case 0x03: // Enter -> Habilita Flag para procesar
flagcommand2=1; // Comando en Main
break;
default:
cbuff2[xbuff2++]=d; // Añade caracter recibido al Buffer
}
}
void inicbuff2(void){ // Inicia a \0 cbuff -------------------
int h;
for(h=0;h<lenbuff2;h++){ // Bucle que pone a 0 todos los
cbuff2[h]=0x00; // caracteres en el buffer
}
xbuff2=0x00; // Inicializo el indice de siguiente
// caracter
}
// Programa Principal /////////////////////////////////////////////////////////
void main() {
printf("\r\n\** prueba buffer **\r\n\r\n"); // Presenta menú
enable_interrupts(int_rda); // Habilita Interrupción RDA
enable_interrupts(int_rb);
enable_interrupts(global); // Habilita interrupciones
do {
if(flagcommand){
procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
}
if(flagcommand2){
procesa_comando2();}
} while (TRUE);
}
// Procesador de Comandos /////////////////////////////////////////////////////
void procesa_comando(void){
int i, j;
char salida[lenbuff]; // Argumento de comando (si lo tiene)
disable_interrupts(int_rb);
flagcommand=0; // Desactivo flag de comando pendiente.
j=0;
for (i=0;i<xbuff;i++){
if (cbuff == '')
while((cbuff != 0x4A) & (i<xbuff))
{
salida[j++]=cbuff[i++];
printf ("%c",salida[j-1]); // Monitorizamos el argunmento.
}
i++;
}
inicbuff(); // Borro buffer.
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
salida=0x00; // caracteres en el argumento
}enable_interrupts(int_rb);
}
void procesa_comando2(void){
int h, p;
char salida2[lenbuff2]; // Argumento de comando (si lo tiene)
disable_interrupts(int_rda);
flagcommand2=0; // Desactivo flag de comando pendiente.
p=0;
for (h=0;h<xbuff2;h++){
if (cbuff2[h] == '')
while((cbuff2[h] != 0x4A) & (h<xbuff2))
{
salida2[p++]=cbuff2[h++];
printf ("%c",salida2[p-1]); // Monitorizamos el argunmento.
}
h++;
}
inicbuff2(); // Borro buffer.
for(h=0;h<lenbuff2;h++){ // Bucle que pone a 0 todos los
salida2[h]=0x00; // caracteres en el argumento
}enable_interrupts(int_rda);
}
muchas gracias
saludos
-
Ayala:
Tú codigo no maneja dos canales serie, sólo uno.
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // RS232 Estándar
#use rs232(baud=9600, xmit=PIN_B4, rcv=PIN_B5)
Estas dos declaraciones hacen que solo se tome en cuenta la segunda, redefiniendo la segunda lo definido en la primera de ellas.
Para que tengas dos canales serie vivos tienes que declarar cada uno de ellos con un nombre de stream.
#use rs232(baud=9600, xmit=PIN_B1,rcv=PIN_B2, stream=CANAL1)
#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3, stream=CANAL2)
Dale un vistazo a Una introducción al uso de printf fprintf y sprintf (http://www.todopic.com.ar/foros/index.php?topic=4641.msg72809#msg72809)
-
Hola a todos, Ayala08 te contesté en la otra zona sin ver tu post de aquí, pero sí, con eso es con lo que estoy yo, con los stream.
Por cierto un apunte que me indicó Red_Pic, sobre la inserción del código para que no se pierda ningún trozo y sea bien visible, puedes hacerlo si lo deseas con en lugar de los puntos va tu código sin espacios en blanco.
Venga a seguir cacharreando, gracias y saludos a todos.
-
Lo siento Ayala08, al subirlo al foro se transforma pero lo tienes aquí http://www.todopic.com.ar/foros/index.php?topic=13977.0 (http://)
Saludos
-
Hola a todos!!! Gracias redpic , eso no lo habia tenido en cuenta, ahora tengo una pregunta es posible recibir por un canal a una velocidad y transmitir por otro a otra velocidad:
por ejemplo :
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,STREAM=CANAL1) // RS232 Estándar
#use rs232(baud=4800, xmit=PIN_B4, rcv=PIN_B5,STREAM=CANAL2)
// CONSTANTES /////////////////////////////////////////////////////////////////
int const lenbuff=70; // Longitud de buffer, Ajustar
// a lo que desees (o te sea posible)
// VARIABLES EN RAM ///////////////////////////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último caracter recibido
int1 flagcommand=0; // Flag para indicar comando disponible
// Declaración de Funciones ///////////////////////////////////////////////////
void inicbuff(void); // Borra buffer
int addcbuff(char c); // añade caracter recibido al buffer
void echos(char c); // Eco selectivo sobre RS232
void procesa_comando(void); // Procesa comando
// INTERRUPCIONES /////////////////////////////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
rcvchar=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=fgetc(canal1); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer y ...
}
}
// Desarrollo de Funciones ////////////////////////////////////////////////////
int addcbuff(char c){ // Añade a cbuff -----------------------
switch(c){
case 0x03: // Enter -> Habilita Flag para procesar
flagcommand=1; // Comando en Main
break;
default:
cbuff[xbuff++]=c; // Añade caracter recibido al Buffer
}
}
void inicbuff(void){ // Inicia a \0 cbuff -------------------
int i;
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
cbuff=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente
// caracter
}
// Programa Principal /////////////////////////////////////////////////////////
void main() {
fprintf(canal2,"\r\n\** prueba buffer **\r\n\r\n"); // Presenta menú
enable_interrupts(int_rda); // Habilita Interrupción RDA //// declaramos el puerto B como salidas
enable_interrupts(global); // Habilita interrupciones
do {
if(flagcommand){
procesa_comando(); // Si hay comando pendiente de procesar ... lo procesa.
//printf("..\r"); // printf CR
}} while (TRUE);
SLEEP();
}
// Procesador de Comandos /////////////////////////////////////////////////////
void procesa_comando(void){
int i, j;
char salida[lenbuff]; // Argumento de comando (si lo tiene)
disable_interrupts(int_rda);
flagcommand=0; // Desactivo flag de comando pendiente.
j=0;
for (i=0;i<xbuff;i++){
if (cbuff == '')
while((cbuff != 0x4A) & (i<xbuff))
{
salida[j++]=cbuff[i++];
fprintf (canal2,"%c",salida[j-1]); // Monitorizamos el argunmento.
}
i++;
}
inicbuff(); // Borro buffer.
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
salida=0x00; // caracteres en el argumento
}
enable_interrupts(int_rda);
}
muchas gracias
saludos
-
Hola a todos!!! Gracias redpic , eso no lo habia tenido en cuenta, ahora tengo una pregunta es posible recibir por un canal a una velocidad y transmitir por otro a otra velocidad:
por ejemplo :
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,STREAM=CANAL1) // RS232 Estándar
#use rs232(baud=4800, xmit=PIN_B4, rcv=PIN_B5,STREAM=CANAL2)
Ayala, eso ya me lo podrás decir tú mismo: compila, prueba y si funciona me los dices ... ja, ja, ja :D :D :D
Edito: No lo he hecho nunca, pero no veo por qué no ha de funcionar.