Autor Tema: Problemas con codigo para Proyecto de Grado  (Leído 2661 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Problemas con codigo para Proyecto de Grado
« en: 27 de Abril de 2011, 18:47:27 »
Hi, buenas y primeramente agradecerles a los moderadores y colaboradores de esta sección del foro por los tutoriales y ejemplos que me han ayudado en mucho con la programación de micro controladores en C.

Ya tengo base en la programación de C-ANSI en programas para computadoras en plataforma windows es por esto que no me costo demasiado entender la sintaxis.

Bueno para empezar estoy por defender mi proyecto de grado el cual se trata de un control automático de subministro continuo de agua potable en una localidad rural de mi país. Este consta de un tanque acuífero  de tipo elevado y dos centrales de bombeo (casetas contenedoras de las bombas hidráulicas subterráneas), debido ha que tanto las centrales de bombeo y el tanque elevado están separados uno del otro por distancias de 300m y 450m opto por realizar la comunicación de comandos ON y OFF para las respectivas bombas hidráulicas de forma inalambrica utilizando modems RF con adaptadores RS-232 modelo DigiMesh 900.

El tipo de medida del nivel de liquido es un arreglo de 2 boyas o flotadores de tipo switch que se acoplaran al sistema de uControl compuesto por un micro controlador PIC16F88A, este enviara los comandos al modem DigiMesh 900 por comunicación serial RS-232.

El problema surge a la hora de simular el sistema puesto que no hace nada con las interrupciones y las luces piloto pues de echo e estado practicando con el PIC16F84A (claro que los comandos no los puedo enviar por la carencia de la comunicación serial) y todo me anda de fabula.

Bueno para abreviar las cosas les dejo los archivos del código fuente del sistema TX con el compilador CCSv4.114 y el circuito simulado en Proteus v7.6 SP0.

#include <16f88.h>                              
#fuses HS, NOWDT, PUT, NOPROTECT, NOWRT, NOLVP  
#USE delay (CLOCK = 4000000)                
#use rs232(baud=9600, xmit=pin_b5, rcv=pin_b2)
//ESTAS 2 DIRECTIVAS NO LAS COMPRENDO MUY BIEN PERO VERE TUS OTROS TUTORIALES
//Y EL MANUAL DE AYUDA CCS                      
#use standard_io(a)      
#use fast_io(b)                    
                                                                                                            
                      
//PROTOTIPO DE FUNCIONES//
void CONFING();         //  
void DORMIR();          //        
//////////////////////////  
                                
//DECLARACIONES DE VARIABLES GLOBALES//                        
int1 START=0;                        //  
int1 NIVEL;                          //
int1 ALTO=1;                         //
int1 BAJO=0;                         //
enum Bomba {BOMBA1, BOMBA2};         //
int1 SetBomba=0;                     //
int CONTADOR=0;                      //
///////////////////////////////////////                    
                
// CADENAS DE COMANDOS//
CHAR COMB1ON = "ONB1";//    
CHAR COMB1OFF= "OFF1";//    
CHAR COMB2ON = "ONB2";//        
CHAR COMB2OFF= "OFF2";//
////////////////////////

//INTERRUPCION EXTERNA DEL PIN B0, ESTA INTERRUPCION LA GENERA UN RELOJ ////////    
//EXTERNO QUE ENVIA UN PULSO EN ALTO CADA 2 HORAS                             //
#INT_EXT                                                                      //
void INT_B0()                                                                 //
{                                                                             //
DELAY_MS(50);                                                                 //
CONTADOR=0; //RESETEA EL CONTADOR PARA QUE REALIZE EL ENVIO DEL COMANDO       //
                                                                              //
                                                                              //
IF (input_state(PIN_B6)==0)/*PREGUNTA SI EN PIN B6 O SENSOR DE NIVEL BAJO     //
ESTA EN 0 ESO SIGNIFICA QUE EL NIVEL DEL AGUA ESTA BAJO AUN PASADAS           //
LAS 2 HORAS*/                                                                 //
{                                                                             //  
SetBomba=BOMBA2; /*SI ES CIERTO ESTO, SE SELECCIONA LA BOMBA2 PARA FUNCIONAR*///  
}                                                                             //
else                                                                          //
{                                                                             //
SetBomba=BOMBA1; /*CASO CONTRARIO, SE SELECCIONA LA BOMBA1 PARA FUNCIONAR*/   //
}                                                                             //
}                                                                             //  
////////////////////////////////////////////////////////////////////////////////

/*INTERRUPCIONES POR CAMBIO DE ESTADO RB 4-6-7 CUALES SON LOS SENSORES
DE NIVEL ALTO B7 Y DE NIVEL BAJO B6 COM TAMBIEN EL BOTON START*/
#INT_RB                                          
void INT_B4_6_7()              
{
DELAY_MS(50);  
START=1; /*SETEA LA VARIABLE GLOBAL START A 1 PARA EMPEZAR EL PROGRAMA
ESTO SE PUEDE HACER TANTO CON EL B6 Y B7 PERO CUANDO SE INSTALE EL SENSOR
DENTRO DEL TANQUE, PUEDEN ESTAR TANTO 0-0, 1-0, 0-1 POR ESO AGREGO EL SWHITCH
EN B4*/              
if ((input_state(PIN_B6)==0) && (input_state(PIN_B7)==0))/*PREGUNTA SI EL
SENSOR DE NIVEL ESTA EN 0-0 SIGNIFICA QUE EL LIQUIDO ESTA EN MUY BAJO NIVEL*/
{                                      
NIVEL=BAJO; /*En tal caso la variable nivel se carga con el balor de la
constante BAJO qe es igual a 0*/
CONTADOR=0;      
}                                  
                                                    
if ((input_state(PIN_B6)==1) && (input_state(PIN_B7)==1))/*PREGUNTA SI EL
SENSOR DE NIVEL ESTA EN 1-1 SIGNIFICA QUE EL LIQUIDO ESTA EN ALTO NIVEL*/
{                                                      
NIVEL=ALTO; /*En tal caso la variable nivel se carga con el valor de la
constante ALTO que es igual a 1*/  
CONTADOR=0;                
}                
}                                  
                                                  
void main ()        
{      
      
CONFING(); /*SE EJECUTA LA FUNCION DE CONFIGURACION DE PUERTOS*/      
CHAR COM_TO_SEND [];/*varable que contendra los comandos para ser enviados*/  
                      
IF (START==1)/*VERIFICA SI START ES 1 PARA ASI EMPEZAR EL PROGRAMA*/  
{
do {                                                        
/*VERIFICA QUE BOMBA ESTA SELECIONADA PARA ACTIVARLA O DESACTIVARLA*/                
switch (SetBomba)            
{                  
                                              
case 0: /*EN CASO DE QUE LA BOMBA SELECIONADA SEA LA BOMBA #1*/                                            
       if (NIVEL) /*VERIFICA SI EL NIVEL DEL LIQUIDO ESTA ALTO*/
       {
       /*CARGA EL COMANDO A ENVIAR PARA APAGAR LA BOMBA1*/
       COM_TO_SEND = COMB1OFF;
       /*APAGA EL LED INDICADOR DEL FUNCIONAMIENTO DE LA BOMBA1*/
       OUTPUT_LOW(PIN_A0);  
       }          
       else /*EN TAL CASO QUE EL NIVEL DEL LIQUIDO SEA BAJO*/                  
       {
       /*ENCIENDE EL LED PILOTO QUE INDICA EL FUNCIONAMIENTO DE LA BOMBA1*/
       OUTPUT_HIGH(PIN_A0);                      
       /*CARGA EL COMANDO A ENVIAR PARA ENCENDER LA BOMBA1*/
       COM_TO_SEND = COMB1ON;  
       }      
break;        
                      
case 1: /*EN CASO DE QUE LA BOMBA SELECIONADA SEA LA BOMBA #2*/  
       if (NIVEL) /*VERIFICA SI EL NIVEL DEL LIQUIDO ESTA ALTO*/      
       {
       /*CARGA EL COMANDO A ENVIAR PARA APAGAR LA BOMBA2*/
       COM_TO_SEND = COMB2OFF;
       /*APAGA EL LED INDICADOR DEL FUNCIONAMIENTO DE LA BOMBA2*/
       OUTPUT_LOW(PIN_A1);
       }                      
       else /*EN TAL CASO QUE EL NIVEL DEL LIQUIDO SEA BAJO*/
       {
       /*ENCIENDE EL LED PILOTO QUE INDICA EL FUNCIONAMIENTO DE LA BOMBA2*/
       COM_TO_SEND = COMB2ON;
       /*CARGA EL COMANDO A ENVIAR PARA ENCENDER LA BOMBA2*/
       OUTPUT_HIGH(PIN_A1);
       }
break;                  
}            
/*ENVIA POR EL PUERTO SERIAL B5 LA CADENA DE COMANDOS YA SEA PARA LA BOMBA1 O 2*/                          
printf("%s", &COM_TO_SEND);
delay_ms(500);

CONTADOR++; /*INCREMENTA EN 1 EL CONTADOR DE ENVIOS DE COMANDOS*/              
                        
}while (CONTADOR!=3); /*SE EJECUTA EL ENVIO DEL COMANDO 3 VECES COMO MEDIDA
DE SEGURIDAD*/
}                                                  
/*EJECUTA LA FUNCION DE SLEEP*/
DORMIR();                                  
}                                
                        
/*FUNCION DESTINADA A CONFIGURAR LOS PUERTOS*/
void CONFING()                        
{                                                        
SET_TRIS_B(0b11010101); //B7, B6, B4, B2, B0 ENTRADA
                        //B5, B3, B1 SALIDA
SET_TRIS_A(0X00);       //TODOS LOS PUERTOS A COMO SALIDA    
enable_interrupts(INT_RB); //ACTIVA LAS INTERRUPCIONES POR CAMBIO DE NIVEL LOGICO
enable_interrupts(INT_EXT);//ACTIVA LA INTERRUPCION EXTERNA DEL PUERTO B0
enable_interrupts(global);                    
}      
/*FUNCION ENCARGADA DE PONER EN ESTADO SLEEP AL uC PARA AHORRAR ENERGIA
ASTA QUE OCURRA UNA INTERRUPCION*/
void DORMIR()      
{
SLEEP();                      
}
« Última modificación: 27 de Abril de 2011, 18:52:42 por BURZUM »

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #1 en: 03 de Mayo de 2011, 21:22:25 »
Hee, ya pude solucionar mi problema con el sistema TX tanto con las interrupciones como con el envío de comandos por el puerto serial del uControlador el cual trabaja justo con las necesidades descritas anteriormente (rev. Codigo fuente "control de nivel TX"), que como verán envía 3 veces con intervalos de 3s el comando de tarea, relacionado con el estado del nivel del agua dentro del tanque.  

Ahora el problema surge con el código para el sistema RX puesto que utilizo la interrupción serial #INT_RDA la utilizo para ejecutar la función gets();  y guardar la cadena en el registro COMANDO[5] (el tamaño es para almacenar solo 4 caracteres y su fin de cadena o sea el numero 0), luego ejecuta las tareas correspondientes cuya duración no tarda mas de 1s (por seguridad la transmision del sistema TX tiene intervalos de 3s), la primera vez que recibe la cadena se ejecuta la interrupcion #INT_RDA y realiza lo que indica el codigo fuente, lo malo es cuando recive por segunda y tercera vez el comando pues agrega al principio en COMANDO[0] el valor 0x0A por lo cual e creado la funcion REV_CADENA:

Al recivir comando por 1 vez

By nephysto at 2011-05-03

Por segunda vez

By nephysto at 2011-05-03

Despues de la funcion REV_CADENA

By nephysto at 2011-05-03

Bueno asta acá todo bien si no fuera por estos casos

caso a): Elimino todos los delays lo cual no me conviene puesto que no creo que el sistema se active a esa velocidad de cambio 1-0, pero en la simulación paso a paso usando el programa PROTEUS con el código fuente del "control de nivel RX.cof" para evaluar paso a paso y paso saltado lo que hace el sistema; todo corre bien recive el comando lo evalúa y realiza la tarea a ejecutar lo malo es que se supone que quedaría dormido el uControlador pues no (aunque el piloto lo indique) se dirige de nuevo a la interrupción RDA y queda esperando por una nueva cadena. Y cuando lo ejecuto directamente con el archivo .hex para que corra libremente, pues no hace nada y no es por la velocidad puesto que el piloto busy debería por lo menos parpadear pero nada.

caso b):Activo los delays y la nueva instrucción #USE delay (CLOCK = 4000000) antes de la función main
aquí es mas directo el problema, pues realiza la tarea correspondiente al recivir el comando,
activa el pin A0 se va al retraso o función temporizadora del delay_ms y se pierde no retorna ni a la interrupción RDA ni a la instrucción siguiente del delay_ms.

Bueno estos son todos los problemas que tiene el programa RX, si pudieran ayudarme con algún error que este pasando por alto o si tienen algún método mejor para realizar las tareas a las cuales esta destinado el programa les rogaría darmelas a conocer.

Aca les dejo el codigo fuente del sistema RX y para descargar les dejo el programa TX, RX y el circuito simulado en proteus (abrir solo "simulacion proyecto TX").            

Código: [Seleccionar]
#include <16f88.h>  
#include <string.h>            
#fuses XT, NOWDT, PUT, NOPROTECT, NOWRT, NOLVP  
#USE delay (CLOCK = 4000000)                
#use rs232(baud=300, xmit=PIN_B5, rcv=pin_b2)
//#byte INTCON=0x8B      
                

//PROTOTIPO DE FUNCIONES////////////                                                            
void CONFING();                   //    
void DORMIR();                    //
void COMP_COM(char COM[]);        //
void WEAK();                      //
void REV_CADENA(char COM[]);      //
////////////////////////////////////          
                                        
//DECLARACIONES DE VARIABLES GLOBALES//                        
char COMANDO[5];                     //
                                     //
int8 START;                          //
///////////////////////////////////////                    
                    
///////CADENAS DE COMANDOS///
CHAR COMB1ON  []= "ONB1";  //    
CHAR COMB1OFF []= "OFF1";  //          
/////////////////////////////
                        
#INT_RDA              
void D_IN_RS()                                        
{
GETS(COMANDO);  ////captura la cadena de comando que envió el sistema TX

START=1;              ////setea la variable START que es la llave para entrar en la ejecucion de las funciones
                             ////para el tratado de cadenas comparacion, y ejecucion de tareas.
                             ////Esto indica que se recivio una cadena            
}                        
                                                  

///caso a) desactivo o dejo entre comentarios esta instrucción y los delays que aparecen en la función
///comp_com.

///caso b) dejo activo esta instrucción cuando dejo activados los delays entre la activación
///y desactivacion de los pines
 l
 l
 v
#USE delay (CLOCK = 4000000)
                    
void main()      
{          
CONFING();           ///llamo a la función de configuración para puertos, etc.
while(1)    
{    
if (START==1)       ///verifica la variable START si es así ejecuta las funciones y tareas en su interior
{              
WEAK();          
REV_CADENA(COMANDO);/// Como o indican las figuras 2 y 3 esta función realiza la tarea de arreglar el comando
COMP_COM(COMANDO);   ///Compara los comandos recibidos con los establecidos en el programa  
START=0;                        ///Recetea la variable START para salir al else y dejar en estado SLEEP
                                       ///al uControlador (es lo que se intenta  :sad:)                      
}                  
else                    
{          
DORMIR();                      ///De no ser 1 el valor de START se ejecuta esta funcion
}      
}
}      
                        

             /*FUNCION DESTINADA A CONFIGURAR LOS PUERTOS*/
void CONFING()                                
{                  
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);
}              
                          
             /*FUNCION ENCARGADA DEL ENVIO DE COMANDOS
            PARA EL CONTROL DE LAS BOMBAS HIDRAULICAS*/
          
                    
void COMP_COM(char COM[])            
{          
if(!(strcmp(COMANDO, COMB1ON)))    
{                              
output_high(PIN_A0);  ///pone en 1 la salida A0 para activar un relay cuyo contacto acciona el enclavamiento
                                  ///de la bomba Hidraulica #1 y encendiendola    
delay_ms(50);             ///Un pequeño retrazo antes de poner en 0 la salida A0 para confirmar la activacion  
output_low(PIN_A0);    
//DORMIR();               ///bueno aca intentaba directamente dejar al uC en sleep una vez realizada la tarea
                                 ///anterior pero ocurria el problema de volver dentro de la interrupción RDA y ademas que
                                 ///no retornaria a la funcion main
}                  
if(!(strcmp(COMANDO, COMB1OFF)))
{            
output_high(PIN_A1);  ///pone en 1 la salida A1 para activar un relay cuyo contacto corta el enclavamiento
                                  ///de la bomba Hidraulica #1 y apagandola
delay_ms(50);
output_low(PIN_A1);
//DORMIR();              
}
//DORMIR();
}                                
  
//esta funcion es de mucha ayuda a la hora de arreglar el comando con errores
//que se recive por segunda y tercera vez.                
void REV_CADENA(char COM[])
{
int8 i,sum=0;
if (COM[0]==0x0A)
{            
for(i=0;i<4;i++)
{          
sum++;  
COMANDO[i]=COM[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()
{                
output_high(pin_a3); //Pone en 1 elPiloto que indica que el uControlador esta trabajando                                        
output_low(pin_a2);   //Pone en 0 elPiloto que indica que el uControlador esta durmiendo
}        

                        
            /*FUNCION ENCARGADA DE PONER EN ESTADO
               SLEEP AL uC PARA AHORRAR ENERGIA
               ASTA QUE OCURRA UNA INTERRUPCION*/
void DORMIR()      
{          
output_low(pin_a3);  //Pone en 0 elPiloto que indica que el uControlador esta trabajando                          
output_high(pin_a2); //Pone en 1 elPiloto que indica que el uControlador esta durmiendo
//BIT_SET(INTCON, 7); //esta instrucción me servia anteriormente para poner en 1 el bit GIE del
                                   //registro INTCON, puesto que se desactivaban todas las interrupciones
SLEEP();                      
}
« Última modificación: 03 de Mayo de 2011, 21:29:30 por BURZUM »

Desconectado Alcaparrones

  • PIC10
  • *
  • Mensajes: 17
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #2 en: 04 de Mayo de 2011, 17:26:29 »
Buenas

Un par de cosillas que veo mal o dudoso: quita el segundo #USE delay (CLOCK = 4000000), creo que eso solo te puede dar fallos. Por otro lado, veo que tienes problemas mandando los comandos por rs232 y que los has solucionado de forma, digamos, expeditiva  8)  El comando que te da problemas 0x0a significa salto de linea. Supongo que usas "printf" para mandar los datos a este pic. Yo no suelo usar printf cuando comunico pic's, uso "putc" para enviar los caracteres de una tabla de uno en uno ( así deberás enviar manualmente /0 ), así me ahorro problemas.

Otra cosa, personalmente las interrupciones del puerto serie me han dado problemas, lo que no quiere decir que a tí te pase lo mismo. De todas formas, si el gets(comando); lo pones dentro de una estructura de selección con kbhit ( if(kbhit()){  } ) y te aseguras de que se lea el bufer solo si hay datos nuevos disponibles, mejor.

Y por último y más importante, el parón del pic. Dices que el problema lo tienes en el delay... ¿usas un cristal externo o el interno? si usas el interno ahí puede estar el problema. En vez de XT en los fuses pon INTRC_IO. Además, incluye la linea setup_oscillator(OSC_4MHZ|OSC_INTRC); al inicio de la función main()

Por cierto, cuando llamas a tus funciones les pasas el valor de una variable que después no usas, usas una global, solo usa la global y ahorrarás algo de memoria y tiempo al pic, que nunca viene mal.

Espero que te sirva de algo. Un saludo.
« Última modificación: 04 de Mayo de 2011, 17:44:39 por Alcaparrones »

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #3 en: 05 de Mayo de 2011, 05:28:54 »
Hola Alcaparrones, lo siento pero aqui me pierdo  ;-) ( incluye la linea setup_oscillator(OSC_4MHZ|OSC_INTRC); al inicio de la funcion main )
¿Porque de esta linea?

Saludos.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado Alcaparrones

  • PIC10
  • *
  • Mensajes: 17
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #4 en: 05 de Mayo de 2011, 18:08:41 »
Hola

Esa linea la pondrias solo si usas el oscilador interno. Realmente no es necesario ponerla, ya que al usar el #FUSE INTRC_IO y luego #USE delay(CLOCK=4000000) ya es suficente, pero como tenias problemas con los delay y estos están relacionados directamente con los osciladores, te lo sugerí por si acaso.

En fin, ¿sigues con los mismos porblemas?

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #5 en: 05 de Mayo de 2011, 18:16:14 »
Hola Alcaparrones, no soy yo quien tiene el problema  ;-) lo preguntaba porque no la he usado ninguna vez y no he tenido problemas con los delays ni con el funcionamiento del programa.

Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado BURZUM

  • PIC10
  • *
  • Mensajes: 7
Re: Problemas con codigo para Proyecto de Grado
« Respuesta #6 en: 06 de Mayo de 2011, 23:55:58 »
Muchas gracias Alcaparrones por tu respuesta puesto que mi post ya iba para las 100 vistas y ninguna respuesta je je :P. 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.

Código: [Seleccionar]
#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.   


 

anything