Muchas gracias Alcaparrones por tu respuesta puesto que mi post ya iba para las 100 vistas y ninguna respuesta je je
. Bueno primero decirte que utilizo un crystal externo de 4MHz, en el programa TX utilizo puts(); que funciona igual que putc(); con la diferencia que que puts(); envía char por char como tambien return y line feed (10 o sea el 0x0A que recibo al final debido ha que dimensiono a 5 la longitud del array COMANDO), pero probare tu concejo de utilizar putc(); y enviar /0 al final.
Revisando los Ejemplos de Vzener encontré este
INT por RS-232 donde por así decirlo; la mayoría del código destinado a la captura, evaluación y salida de información, estaba dentro de la función #INT_RDA colocando al principio la instrucción desable_interrupts(GLOBAL); y al final de todo el código la instrucción que lo complementa enable_interrupts(GLOBAL);.
En base a esto me propuse a re-diseñar el código pero aun pasaba otros de los errores que ocurrían (no lo mencione por cuestiones de solo apuntar el tema a una falencia) con otros prototipos de programa destinados a esta tarea; este problema radicaba a la hora de volver a configurar o habilitar todas las interrupciones o incluso solo la interrupción por comunicación serial; realizado esto el programa volvía o saltaba el contador del programa a la dirección de la interrupción ejecutando desable_interrupts(GLOBAL); y todo lo demás. Como el programa esta destinado a realizar las tareas en el orden siguiente:
Etapa 1
Al momento de encender el sistema
1- Configurar los fuses, puertos, interrupciones, etc.
2- Entrar en modo SLEEP; y esperar hasta que ocurra una interrupción por la recepción de datos seriales.
Etapa 2
Al detectar una interrupción #INT_RDA
1- Recibir el tren de caracteres del puerto serial y moverlo a la variable global COMANDO[];
2- Analizar y comparar la variable COMANDO[]; y realizar la tarea correspondiente.
3- Entrar en modo SLEEP; (realizar paso 1, 2 y 3 3 veces).
El problema se encontraba en el paso 3 de la etapa 2; después de las 3 veces que se realizaba esta etapa surgía lo que indique anteriormente puesto que si intentaba ejecutar la instrucción enable_interrupts(GLOBAL); (o cualquier otra forma como ser hurgando el registro INTCON 0Bh, 8Bh, 10Bh, 18Bh), realizaba un salto incondicional hacia el interior de la interrupcion #INT_RDA y quedandoce en la instrucción GETS(COMANDO); esperando información y dejando al uControlador ON.
Si dejaba o mejor dicho no intentaba reactivar las interrupciones el programa llegaba a quedarse en modo SLEEP después de las 3 veces que recibe y compara el dato
; lo malo es que cuando el sistema TX envíe otro o el mismo comando al sistema RX, este ultimo no despertaba y no realizaba ninguna tarea.
Cansado de tener estos errores opte por estructurar mi programa de la siguiente manera, de todas formas el programa se quedara esperando información serial pero esta vez no contaba con unas de las frases informáticas que se dicta cuando se cuelga la PC "YA PROBASTE RE-INICIÁNDOLA?" entonces implemente WDT al sistema y funciona de maravillas.
Bueno aquí se los dejo el code del uC RX si existe una forma de mejorarlo o mejor dicho que quitarle de mas.
#include <16f88.h>
#include <string.h>
#fuses HS, NOWDT, PUT, NOPROTECT, NOWRT, NOLVP
#USE delay (CLOCK = 4000000)
#use rs232(baud=300, xmit=PIN_B5, rcv=pin_b2)
//PROTOTIPO DE FUNCIONES////////
void CONFING(); //
void DORMIR(); //
void COMP_COM(); //
void REV_CADENA(); //
void WEAK(); //
void GET_CADENA(); //
////////////////////////////////
///////CADENAS DE COMANDOS///
CHAR COMB1ON []= "ONB1"; //
CHAR COMB1OFF []= "OFF1"; //
/////////////////////////////
//DECLARACIONES DE VARIABLES GLOBALES//
int8 CONT_COM=0; //
char COMANDO[5]; //
///////////////////////////////////////
#INT_RDA
void D_IN_RS()
{
IF(!(CONT_COM==3))
{
setup_wdt(WDT_2304MS); //configuro el WDT a 2.3s
WEAK();
GET_CADENA();
REV_CADENA();
COMP_COM();
CONT_COM+=1; //contador de comandos recibidos
}
}
void main()
{
CONFING();
DORMIR();
}
/*FUNCION DESTINADA A CONFIGURAR LOS PUERTOS*/
void CONFING()
{
restart_wdt();
enable_interrupts(INT_RDA);//ACTIVA LA INTERRUPCION DEL PUERTO SERIAL
enable_interrupts(GLOBAL);
SET_TRIS_B(0b11010101); //B7, B6, B4, B2, B0 ENTRADA
//B5, B3, B1 SALIDA
SET_TRIS_A(0X00); //TODOS LOS PUERTOS A COMO SALIDA
output_a(0X00);
}
/*FUNION ENCARGADA DEL COMPROBACION DE COMANDOS
PARA EL CONTROL DE LAS BOMBAS HIDRAULICAS*/
void COMP_COM()
{
restart_wdt();
if(!(strcmp(COMANDO, COMB1ON)))
{
output_high(PIN_A0);
DELAY_MS(300);
restart_wdt();
output_low(PIN_A0);
}
else if (!(strcmp(COMANDO, COMB1OFF)))
{
output_high(PIN_A1);
DELAY_MS(300);
restart_wdt();
output_low(PIN_A1);
}
else
{
break;
}
}
void REV_CADENA()
{
restart_wdt();
int8 i,sum=0;
if (COMANDO[0]==0x0A)
{
for(i=0;i<4;i++)
{
sum++;
COMANDO[i]=COMANDO[sum];
}
COMANDO[4]=0;
}
}
/*FUNCION ENCARGADA DEL CAMBIO DE ESTADO
PARA LOS LEDS PILOTOS QUE REPRESENTAN
LAS ETAPAS DE SLEEP Y BUSY DEL SISTEMA uCONTROLADO */
void WEAK()
{
restart_wdt();
output_high(pin_a3);
output_low(pin_a2);
}
void GET_CADENA()
{
restart_wdt();
if(kbhit())
{
GETS(COMANDO);
}
}
/*FUNCION ENCARGADA DE PONER EN ESTADO
SLEEP AL uC PARA AHORRAR ENERGIA
ASTA QUE OCURRA UNA INTERRUPCION*/
void DORMIR()
{
output_low(pin_a3);
output_high(pin_a2);
setup_wdt(WDT_OFF);
SLEEP();
}
Bueno como dije igualmente se queda esperando un dato por RS-232 y también recibo el comando con el error /0x0A pero con la función REV_CADENA y el WDT asunto arreglado.
Para descargar les dejo funcionando codigo RX y TX; + el circuito de simulación.