Comunicación serial PIC 16F1827 + Proteus

Estoy haciendo un código que es bastante sencillo, para probar la comunicación serial del PIC 16F1827 con interrupciones

Antes de explicar el problema, este es el esquema:

2uf4yyq.png


El código para el PIC de arriba:

Código:
#include <16f1827.h>
#fuses   XT,NOWDT,NOPROTECT,PUT,NOLVP  //ordenes para el programador
#use     delay (clock=32M)         // Fosc=32Mhz
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)

#define NO_INTERRUPCION        PIN_B3
#define SERIAL            PIN_B4
#define EXTERNO           PIN_B5 

int FLAG_EXT=0;
#INT_EXT
void ext_int(){
   disable_interrupts(GLOBAL);
   FLAG_EXT=1;
   enable_interrupts(GLOBAL);
}

int FLAG_SERIAL=0;
#int_RDA
void RDA_isr(void){
   disable_interrupts(GLOBAL);
   FLAG_SERIAL=1;
   enable_interrupts(GLOBAL);
}

void main(void){
   int ce;
   int cs;
   RESTART_WDT();
   enable_interrupts(int_ext);
   enable_interrupts(int_rda);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   
   while(TRUE){
      if(FLAG_SERIAL==1){
         output_low (NO_INTERRUPCION);
         output_low (EXTERNO);
         output_high (SERIAL);
         delay_ms(1000);
         output_low (SERIAL);
         FLAG_SERIAL=0;
         cs++;
      }
      else if(FLAG_EXT==1){
         output_low (NO_INTERRUPCION);
         output_low (SERIAL);
         FLAG_EXT=0;
         output_high (EXTERNO);
         delay_ms(1000);
         output_low (EXTERNO);
         ce++;
      }
      else if(FLAG_SERIAL==0 && FLAG_EXT==0){
         output_high (NO_INTERRUPCION);
         output_low (EXTERNO);
         output_low (SERIAL);
      }
   }
}

El código del PIC de abajo:

Código:
#include <16f1827.h>
#fuses   XT,NOWDT,NOPROTECT,PUT,NOLVP  //ordenes para el programador
#use     delay (clock=32M)         // Fosc=32Mhz
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)

#define NO_INTERRUPCION         PIN_B3
#define SERIAL            PIN_B4

int FLAG_EXT=0;
#INT_EXT
void intrb0()
{
   FLAG_EXT=1;
}

void main(void)
{
   int c;
   RESTART_WDT();
   enable_interrupts(int_ext);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   output_low (NO_INTERRUPCION);
   output_low (SERIAL);
   port_b_pullups(0b00000110);
   while(TRUE){
      if(FLAG_EXT==1){
         output_low (NO_INTERRUPCION);
         FLAG_EXT=0;
         char x="HOLA";
         putc(x,com);
         output_high (SERIAL);
         delay_ms(1000);
         output_low (SERIAL);
         c++;
      }
      do{
         output_high (NO_INTERRUPCION);
      }while(FLAG_EXT==0);
   }
}

Una explicación rápida del funcionamiento:

  • PIC 1:
    Si no está activa ninguna interrupción, el led ROJO está encendido. Si se activa la interrupción externa (por interruptor), se enciende el led VERDE. Si se activa la interrupción por comunicación serial (por el otro PIC) se enciende el led AZUL
  • PIC 2:
    Si no está activa la interrupción, el led ROJO está encendido. Si se activa la interrupción externa (por interruptor), se enciende el led AZUL y se envía un número por puerto serial al otro PIC

Para ambos PIC funciona bien tanto el led ROJO (sin interrupciones) y el led correspondiente a la activación de la interrupción externa. El problema es que o bien el PIC 2 no envía o el PIC 1 no recibe o ninguno de los dos hace nada
 

Adjuntos

  • Captura.PNG
    Captura.PNG
    51.6 KB · Visitas: 14
el proteus trae simulacion de terminal

y se ve que NO SABES que el RS232 envia cadenas de caracteres es decir

no puedo hacer esto

char x="HOLA";

por que char X solo se carga con 1 sola letra
mientra que

char x[5]="hola";

si es valido por que es una cadena de caracteres

ahora char *x="HOLA";
tambien es valido pues es un apuntador cargado con la cadena de caracteres

NO es valido hacer esto
putc(x,com);

pues putc como lo dice su nombre escribe 1 sola letra es decir

no podemos escribir

char *x="foros de electronica";
putc(x);


para eso se usa la directiva printf que nos permite escribir una cadena entera

en el CCS encontramos una ayuda llamada INDEX que si la lees podrias aprender mucho si no la les estas perdido
 
Otros detalles aparte de lo que menciona TRILO-BYTE...
Si vas a simular, no uses frecuencias de trabajo tan elevadas, usa 1 MHz o 4 MHz, porque el simulador se sobrecarga.
Ya cuando realices el montaje en físico, cambia la palabra de configuración y la frecuencia que usarás normalmente.

Los problemas por los que no funciona tu programa son varios, sobre todo en el manejo de las interrupciones.

Aquí te lo dejo funcionando en simulación y posiblemente en físico también.
Compara los cambios realizados a los programas para que puedas ver en que partes tenías los problemas.

Como nota adicional, la frecuencia de trabajo la tienes en 32 MHz, pero usaste el fuse XT en vez de HS.
Al simulador eso no le afecta porque usa la frecuencia que se le establece al microcontrolador, pero en la programación eso si es importante.
 

Adjuntos

  • 16F1827 Int_Ext & Int_RDA.rar
    71 KB · Visitas: 38
Bueno, muchas gracias por las respuestas
La verdad solo hacía ese programa para probar que la recepción serial estuviera funcionando, porque tengo otro programa más grande en el cual debo implementarla

El programa lo que hace es recibir cierta información desde un XBee hasta otro XBee (puede ser PIC-PIC o PC-PIC) y hacer algo dependiendo de lo que recibe

Parte del programa original es el siguiente:

Código:
#include <16F1827.h>
#device WRITE_EEPROM = NOINT
#FUSES WDT, NOPUT, PROTECT, NOMCLR, NOCLKOUT, NOCPD, NOBROWNOUT, PLL, INTRC_IO,
#use delay(clock=32M)
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)

...

void main (void){
   int temp;
...
   ext_int_edge(L_TO_H);
   setup_timer_0(T0_INTERNAL|T0_DIV_4);
   enable_interrupts(global);
   enable_interrupts(int_ext);
   enable_interrupts(INT_TIMER0);
   while(true){      
      RESTART_WDT();
      if(kbhit(com)){
         RESTART_WDT();
         temp=recepcion_datos();  // -> -> Devuelve un entero
         ejecucion(temp);         // -> -> Actúa dependiendo del valor de la anterior función
      }
...
   }
}

En la función donde se reciben los datos se está haciendo siempre esto:

Código:
rx=getc(com);


Ahora, modificando el código para tener interrupción quedó de esta forma:

Código:
#include <16F1827.h>
#device WRITE_EEPROM = NOINT
#FUSES WDT, NOPUT, PROTECT, NOMCLR, NOCLKOUT, NOCPD, NOBROWNOUT, PLL, INTRC_IO,
#use delay(clock=32M)
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)

...

#int_RDA
void RDA_isr(void){
   RESTART_WDT();
   OUTPUT_BIT(LED2,LON);
   temp[br]=getc(com);
   br++;
   if(br==1){
      dato=temp[0];
      if(dato!=0x7E){
         temp[0]=0;
         br=0;
         recep=0;
      }
   }
   if(br==3){
      tam_tram=temp[2];
      tamano=tam_tram+3;
   }
   if(br<tamano){recep=0;}
   else if(br==tamano){recep=1;}
}
...

void main (void){
...
   ext_int_edge(L_TO_H);
   setup_timer_0(T0_INTERNAL|T0_DIV_4);
   enable_interrupts(global);
   enable_interrupts(int_ext);
   enable_interrupts(int_rda);         // Interrupción comunicación serial
   enable_interrupts(INT_TIMER0);
   while(true){
      RESTART_WDT();
// VALIDACIÓN DE RECEPCIÓN
      if(recep==1){
         RESTART_WDT();
         for(pos=0;pos<=br-1;pos++){decodificar_trama(pos,temp[pos]);}
         for(pos=0;pos<=32;pos++){temp[pos]=0;}
         temp2=recepcion_datos();
         ejecucion(temp2);
         br=0;
         temp2=0;
         tam_tram=0;
         recep=0;
      }
...
   }
}

Se creó una función para pasar la información del programa "principal" a la librería:

Código:
void decodificar_trama(int cn,int dato){
	brr[cn]=dato;
}

Y en la función de recepción ahora se hace lo siguiente:

Código:
rx=brr[0];

Esto con el fin de que se pueda estar ejecutando una acción sin esperar que todos los datos necesarios para una nueva instrucción lleguen al tiempo.

Anteriormente si llegaba un dato, se paraba lo que estuviera haciendo y solamente se dedicaba a recibir todo.
Ahora la idea es que mientras reciba todos los datos que está esperando, esté ejecutando algo y luego al acabar "revise" si tiene algo pendiente por hacer (llegaron todos los datos) o se quede esperando que lleguen los datos restantes.

El problema es que con el programa modificado jamás hace nada de lo que se le envía por XBee. No se dónde pueda ser el problema porque la recepción está funcionando correctamente (como se comprobó con el ejemplo que dio inicio a este post)

Espero que me puedan ayudar
 
sigo sin entender por que rayos #use delay(clock=32M)

que objetivo tiene si ese micro no puede manejar esa frecuencia y sobretodo por que que objetivo tiene
el programa no esta optimizado ni nada simplemente pienso que es un copy paste taringuero
 
El problema es que con el programa modificado jamás hace nada de lo que se le envía por XBee.
No sé dónde pueda ser el problema porque la recepción está funcionando correctamente (como se comprobó con el ejemplo que dio inicio a este post)
Siempre que tengo algún tipo de problema al cual no le encuentro solución lógica en el programa, entro al modo de depuración ICD y voy analizando la ejecución del programa paso por paso.

Veo el valor de las variables, los registros y cómo se va ejecutando el proceso.
De esa forma se visualiza fácilmente en que parte se produce el problema.
 
Siempre que tengo algún tipo de problema al cual no le encuentro solución lógica en el programa, entro al modo de depuración ICD y voy analizando la ejecución del programa paso por paso.

Veo el valor de las variables, los registros y cómo se va ejecutando el proceso.
De esa forma se visualiza fácilmente en que parte se produce el problema.

Primero que todo muchas gracias por la ayuda y por el tiempo que te tomaste leyendo el código

Esto no se puede hacer en el compilador (CCS) verdad ???
El código en sí es bastante extenso y la simulación no es algo fácil de hacer, pero creo que lo puedo hacer en físico prendiendo algún LED o algo así

Podrías orientarme un poco en qué partes del programa (el modificado) está mal o se podría optimizar ???
 
acabo de ver un error drastico!

#int_RDA
void RDA_isr(void){
RESTART_WDT();
OUTPUT_BIT(LED2,LON);
temp[br]=getc(com);
br++;

if(br==1){
dato=temp[0];
if(dato!=0x7E){
temp[0]=0;
br=0;
recep=0;
}
}
if(br==3){
tam_tram=temp[2];
tamano=tam_tram+3;
}
if(br<tamano){recep=0;}
else if(br==tamano){recep=1;}
}


aveces CCS no respeta esto aunque sea correcto

yo lo declarararia asi

para poder recibir una cadena de caracteres en RDA se uede hacer esto:

#include<bla bla.h>
//char *cadena debe ser variable global se declara abajo de las cabeceras
char *cadena; //no sabemos cuanto mide la cadena lo declaro como apuntador

#int_RDA
void RDA_isr(void)
{
gets(cadena); //con esto leemos toda la cadena que llega en una interrupcion
}
 
Última edición:
Con unas modificaciones, el código quedó ahora así:

Código:
#int_RDA
void RDA_isr(void){
   RESTART_WDT();
   temp[br]=getc(com);
   br++;
   if(br==1 && temp[0]!=0x7E){br=0;}
   if(br==3){tamano=tam_tram=temp[2]+3;}
   if(br==tamano){
      if(!recep){
         for(pos=0;pos<=br-1;pos++){decodificar_trama(pos,temp[pos]);}
      }
      recep=1;
      br=0;
   }
}

Código:
void main (void){
...
      //CONFIGURACION INTERRUPCIONES
      ext_int_edge(L_TO_H);
      setup_timer_0(T0_INTERNAL|T0_DIV_4);
      enable_interrupts(global);
      enable_interrupts(int_ext);
      enable_interrupts(int_rda);         // Interrupción comunicación serial
      enable_interrupts(INT_TIMER0);
      manualf=read_eeprom(3);
...
   while(true){
      RESTART_WDT();
      // VALIDACIÓN DE RECEPCIÓN
      if(recep==1){
         RESTART_WDT();
         temp2=trama_espera();
         recepcion(temp2);
         temp2=0;
         tam_tram=0;
         recep=0;
      }
...
}

Pero sigue teniendo el mismo problema

El problema es que con el programa modificado jamás hace nada de lo que se le envía por XBee.
No sé dónde pueda ser el problema porque la recepción está funcionando correctamente (como se comprobó con el ejemplo que dio inicio a este post)

------------------------------------------------------------------------------------

temp[br]=getc(com);
br++;


aveces CCS no respeta esto aunque sea correcto

No entiendo muy bien, por qué no lo hace siempre ???

Al hacerlo así con un "char" no tendría que esperar que llegue toda la información dentro de la misma vez que se activó la interrupción ???
 
Última edición:
Estuve haciendo algunas pruebas pero sigo teniendo problemas

El circuito que tengo montado es el siguiente:

313r9tg.png


  • PIC 1: Arriba
  • PIC 2: Abajo

Y tengo estos dos códigos:

Emisor
Código:
#include <16f1827.h>
#use     delay (internal = 32MHz)         // Fosc=32Mhz
// #use     delay (internal = 4MHz)          // Fosc=4Mhz, para simulación
#use     RS232(UART1)

#define NO_INTERRUPCION       PIN_B4
#define EXTERNO               PIN_B5

int FLAG_EXT=0;
#INT_EXT
void ext_int(){
   FLAG_EXT=1;
}

void main(){
   int c=0;
   int e=0;
   enable_interrupts(int_ext);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   output_high (EXTERNO);
   output_high (NO_INTERRUPCION);
   delay_ms(1000);
   output_low (EXTERNO);
   output_low (NO_INTERRUPCION);
   delay_ms(1000);
   output_high (EXTERNO);
   output_high (NO_INTERRUPCION);
   delay_ms(1000);
   output_low (EXTERNO);
   output_low (NO_INTERRUPCION);
   delay_ms(1000);
   output_high (EXTERNO);
   output_high (NO_INTERRUPCION);
   delay_ms(1000);
   output_low (EXTERNO);
   output_low (NO_INTERRUPCION);
   delay_ms(1000);
   while(TRUE){
      if(FLAG_EXT==1){
         output_low (NO_INTERRUPCION);
         FLAG_EXT=0;
         switch(c){
            case 0:
               e=0x7E;
            break;
            case 1:
               e=0x00;
            break;
            case 2:
               e=0x11;
            break;
            case 3:
               e=0x90;
            break;
            case 4:
               e=0x00;
            break;
            case 5:
               e=0x00;
            break;
            case 6:
               e=0x01;
            break;
            case 7:
               e=0x03;
            break;
            case 8:
               e=0x0A;
            break;
            case 9:
               e=0x02;
            break;
            case 10:
               e=0x00;
            break;
            case 11:
               e=0x00;
            break;
            case 12:
               e=0xFF;
            break;
            case 13:
               e=0xFE;
            break;
            case 14:
               e=0x01;
            break;
            case 15:
               e=0x01;
            break;
            case 16:
               e=0x20;
            break;
            case 17:
               e=0x83;
            break;
            case 18:
               e=0x0B;
            break;
            case 19:
               e=0x01;
            break;
            case 20:
               e=0xB1;
            break;
         }
         putc(e);
         output_high (EXTERNO);
         delay_ms(1000);
         output_low (EXTERNO);
         c++;
         if(c>20){c=0;}
      }
      else if(FLAG_EXT==0)
      {
         output_high (NO_INTERRUPCION);
         output_low (EXTERNO);
      }
   }
}

Receptor

Código:
#include <16f1827.h>
#use     delay (internal = 32MHz)         // Fosc=32Mhz
// #use     delay (internal = 4MHz)          // Fosc=4Mhz, para simulación
#use     RS232(UART1)

#define RECEPCION       PIN_B4
#define ERROR           PIN_B5
#define ESTADO          PIN_B6 

/*
ESTADO
-> CONSTANTE: DISPONIBILE
-> APAGADO: OCUPADO
-> 2 INT: TAM_TRAMA
-> 3 INT: COMPLETO
*/

int temp[32]={0};
int br=0;
int recep=0;
int pos;
int tamano=0;

#int_RDA
void RDA_isr(void){
   output_low (ERROR);
   output_low (ESTADO);
   output_high (RECEPCION);
   temp[br]=getc();
   br++;
   if(br==1 && temp[0]!=0x7E){
      output_low (RECEPCION);
      output_high (ERROR);
      delay_ms(1000);
      output_low (ERROR);
      delay_ms(1000);
      output_high (ERROR);
      delay_ms(1000);
      output_low (ERROR);
      delay_ms(1000);
      br=0;
   }
   if(br==3){
      output_high (ESTADO);
      delay_ms(1000);
      output_low (ESTADO);
      delay_ms(1000);
      output_high (ESTADO);
      delay_ms(1000);
      output_low (ESTADO);
      delay_ms(1000);
      tamano=temp[2]+3;
   }
   if(br==tamano){
      output_high (ESTADO);
      delay_ms(1000);
      output_low (ESTADO);
      delay_ms(1000);
      output_high (ESTADO);
      delay_ms(1000);
      output_low (ESTADO);
      delay_ms(1000);
      output_high (ESTADO);
      delay_ms(1000);
      output_low (ESTADO);
      delay_ms(1000);
      for(pos=0;pos<=32;pos++){temp[pos]=0;}
      br=0;
      recep=1;
   }
}

void main(){
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
   output_high (RECEPCION);
   output_high (ERROR);
   output_high (ESTADO);
   delay_ms(1000);
   output_low (RECEPCION);
   output_low (ERROR);
   output_low (ESTADO);
   delay_ms(1000);
   output_high (RECEPCION);
   output_high (ERROR);
   output_high (ESTADO);
   delay_ms(1000);
   output_low (RECEPCION);
   output_low (ERROR);
   output_low (ESTADO);
   delay_ms(1000);
   output_high (RECEPCION);
   output_high (ERROR);
   output_high (ESTADO);
   delay_ms(1000);
   output_low (RECEPCION);
   output_low (ERROR);
   output_low (ESTADO);
   delay_ms(1000);
   while(TRUE){
      if(recep==1){
         recep=0;
      }
      else if(recep==0){
         output_high (ESTADO);
         output_low (ERROR);
         output_low (RECEPCION);
      }
   }
}

Lo primero que hace es encender y apagar 3 veces todos los LEDs (solamente para saber que ya está listo para empezar :LOL:)
Luego, si no hay ninguna interrupción se encienden los LEDs ESTADO y NO_INTERRUPCIÓN

Todo comienza cuando hay una interrupción externa en el PIC 2, se enciende el LED SERIAL y se envía un dato al PIC 1 dependiendo de un valor que va aumentando desde 0 hasta 20 para volver a empezar en 0 y seguir
Esto lo hace perfectamente

En el PIC 1 se debería activar la interrupción por recepción serial y activar el LED RECEPCIÓN y dependiendo de lo que reciba hay unas secuencias de LED para finalmente volver a dejar encendido solamente el LED ESTADO, cuando todo el proceso acabe.

Ahora bien, en simulación y en físico el PIC 2 funciona correctamente, sin ningún problema
El PIC 1 tiene dos problemas:
Físico:
No enciende nunca ningún LED y al comienzo debería encender los tres LED en la misma secuencia que el PIC 2
* No es problema del PIC porque le cargué el programa emisor y funciona perfectamente, el problema es con el programa receptor
Simulación y Físico:
No se cumple correctamente la secuencia que debería en los LEDs correspondientes
 
Última edición:
estoy viendo otra marranada tuya

eso me pasa por no leer completamente el codigo

estas usando una interrupcion

en una interrupcion se usa la menor cantidad de codigo posible

10 instrucciones en una interrupcion es demaciado y una barbaridad al meterle DELAY eso no se hace en una iterrupcion

lo que yo recomiendo es que en la interrupcion del RDA leas lo que llega nada mas unicamente leer

y en el main metes tus IF

y de hecho un switch es mas rapido que un if

ejemplo

char *valor; //variable global valor uso char para ahorrar memoria y no usar int "en caso de usar otro compilador"

interrupcion ()
{
gets(valor); el apuntador lee toda la cadena que llega por RS232
}

void main()

while(1)
{
if( valor[1] == 21)
{
//secuencia
}

if( valor[2] == 45)
{
//secuencia2
}

if( valor[3] == 80)
{
//secuencia3
}

}

}
 
Lo de la interrupción lo sé, pero en ese programa que no hace nada más y en el cual uno tiene control sobre la interrupción no es algo muy relevante, o sí ???
 
No le veo sentido usar interrupciones, si dentro del servicio vas a entretener el programa con retardos.

Mejor usa polling y deja que las interrupciones puedan funcionar como lo que son.
 
Bueno, el ejemplo de la interrupción funcionó muy bien con estos dos códigos:

Emisor
Código:
#include <16f1827.h>
#use * * delay (internal = 32 MHz) * * * * // Fosc=32Mhz
#use * * RS232(UART1)

#define NO_INTERRUPCION * * * PIN_B4
#define EXTERNO * * * * * * * PIN_B5

void main(){
 * int c=0;
 * int e[21]={0x7E,0x00,0x11,0x90,0x00,0x00,0x01,0x03,0x0A,0x02,0x02,0x00,0xFF,0xFE,0x01,0x01,0x20,0x83,0x0B,0x01,0xB1};

 * enable_interrupts(int_ext);
 * ext_int_edge(L_TO_H);
 * enable_interrupts(GLOBAL);
 * 
 * output_high (EXTERNO);
 * output_high (NO_INTERRUPCION);
 * delay_ms(500);
 * output_low (EXTERNO);
 * output_low (NO_INTERRUPCION);
 * delay_ms(500);
 * output_high (EXTERNO);
 * output_high (NO_INTERRUPCION);
 * delay_ms(500);
 * output_low (EXTERNO);
 * output_low (NO_INTERRUPCION);
 * delay_ms(500);
 * output_high (EXTERNO);
 * output_high (NO_INTERRUPCION);
 * delay_ms(500);
 * output_low (EXTERNO);
 * output_low (NO_INTERRUPCION);
 * delay_ms(500);
 * 
 * while(TRUE){
 * * *output_high (NO_INTERRUPCION);
 * * *delay_ms(500);
 * * *output_low (NO_INTERRUPCION);
 * * *putc(e[c]);
 * * *output_high (EXTERNO);
 * * *delay_ms(1000);
 * * *output_low (EXTERNO);
 * * *c++;
 * * *if(c>20){
 * * * * c=0;
 * * * * output_high (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * * * output_low (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * * * output_high (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * * * output_low (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * * * output_high (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * * * output_low (NO_INTERRUPCION);
 * * * * delay_ms(500);
 * * *}
 * }
}

Receptor
Código:
#include <16f1827.h>
#use * * delay (internal = 32MHz) * * * * // Fosc=32Mhz
//#use * * delay (internal = 4MHz) * * * * *// Fosc=4Mhz, para simulación
#use * * RS232(UART1)

#define RECEPCION * * * PIN_B4
#define ERROR * * * * * PIN_B5
#define ESTADO * * * * *PIN_B6 

/*
ESTADO
-> CONSTANTE: DISPONIBILE
-> APAGADO: OCUPADO
-> 2 INT: TAM_TRAMA
-> 3 INT: COMPLETO
*/

int temp[32]={0};
int br=0;
int recep=0;
int pos;
int tamano=0;
int err=0;
int serial=0;
int tam=0;
int espera=0;
 
#int_RDA
void RDA_isr(void){
 * temp[br]=getc();
 * br=br+1;
 * if(br==1 && temp[0]!=0x7E){
 * * *br=0;
 * * *err=1;
 * }
 * if(br<3 || br>3){tam=0;}
 * if(br==3){
 * * *tam=1;
 * * *tamano=temp[2]+4;
 * }
 * if(br<tamano){espera=1;}
 * if(br==tamano){
 * * *for(pos=0;pos<=32;pos++){temp[pos]=0;}
 * * *br=0;
 * * *recep=1;
 * * *tamano=0;
 * }
 * serial=1;
}
 
void main(){
 * output_low (RECEPCION);
 * output_low (ERROR);
 * output_low (ESTADO);
 
 * enable_interrupts(int_rda);
 * enable_interrupts(GLOBAL);
 * 
 * output_high (RECEPCION);
 * output_high (ERROR);
 * output_high (ESTADO);
 * delay_ms(500);
 * output_low (RECEPCION);
 * output_low (ERROR);
 * output_low (ESTADO);
 * delay_ms(500);
 * output_high (RECEPCION);
 * output_high (ERROR);
 * output_high (ESTADO);
 * delay_ms(500);
 * output_low (RECEPCION);
 * output_low (ERROR);
 * output_low (ESTADO);
 * delay_ms(500);
 * output_high (RECEPCION);
 * output_high (ERROR);
 * output_high (ESTADO);
 * delay_ms(500);
 * output_low (RECEPCION);
 * output_low (ERROR);
 * output_low (ESTADO);
 * delay_ms(500);
 
 * while(TRUE){
 * * *if(err==1){
 * * * * err=0;
 * * * * output_low (ERROR);
 * * * * output_low (ESTADO);
 * * * * output_low (RECEPCION);
 * * * * output_high (ERROR);
 * * * * delay_ms(1000);
 * * * * output_low (ERROR);
 * * * * delay_ms(1000);
 * * * * output_high (ERROR);
 * * * * delay_ms(1000);
 * * * * output_low (ERROR);
 * * * * delay_ms(1000);
 * * *}
 * * *if(serial==1){
 * * * * output_low (ERROR);
 * * * * output_low (ESTADO);
 * * * * output_high (RECEPCION);
 * * * * if(tam==1){output_high (ESTADO);}
 * * * * if(espera==1){output_high (ERROR);}
 * * * * serial=0;
 * * * * delay_ms(1000);
 * * * * tam=0;
 * * * * espera=0;
 * * *}
 * * *if(recep==1){
 * * * * recep=0;
 * * * * output_low (ERROR);
 * * * * output_low (ESTADO);
 * * * * output_low (RECEPCION);
 * * * * output_high (ESTADO);
 * * * * delay_ms(500);
 * * * * output_low (ESTADO);
 * * * * delay_ms(500);
 * * * * output_high (ESTADO);
 * * * * delay_ms(500);
 * * * * output_low (ESTADO);
 * * * * delay_ms(500);
 * * * * output_high (ESTADO);
 * * * * delay_ms(500);
 * * * * output_low (ESTADO);
 * * * * delay_ms(500);
 * * *}
 * * *else if(recep==0){
 * * * * output_low (RECEPCION);
 * * * * output_low (ERROR);
 * * * * output_high (ESTADO);
 * * *}
 * }
}

View My Video






Ahora aún sigo teniendo problemas con el programa original

Así está en este momento:

Código:
#include <16F1827.h>
#device WRITE_EEPROM = NOINT
#FUSES WDT, NOPUT, PROTECT, NOMCLR, NOCLKOUT, NOCPD, NOBROWNOUT, PLL, INTRC_IO,
#use delay(clock=32M)
#use RS232(BAUD=9600, XMIT=PIN_B2, RCV=PIN_B1, stream=com,errors)

...

int temp[32]={0};
int br=0;
int recep=0;
int pos;
int tam_tram=0;
int temp2;
int tamano=0;

...

#int_RDA
void RDA_isr(void){
 * temp[br]=getc(com);
 * br=br+1;
 * if(br==1 && temp[0]!=0x7E){br=0;}
 * if(br==3){tamano=tam_tram=temp[2]+4;}
 * if(br==tamano){
 * * *recep=1;
 * * *br=0;
 * * *tamano=0;
 * }
}

...

void main (void){
 * //VARIABLES MAIN
 * //INICIO MODULOS GENERAL
...
 * //INICIO MODULO DIMMER
 * port_b_pullups(0b01010001);
 * setup_wdt(WDT_ON|WDT_2S);
...
 * RESTART_WDT();
 * if(...
 * * *//CONFIGURACION INTERRUPCIONES
 * * *ext_int_edge(L_TO_H);
 * * *setup_timer_0(T0_INTERNAL|T0_DIV_4);
 * * *enable_interrupts(global);
 * * *enable_interrupts(int_ext);
 * * *enable_interrupts(int_rda); * * * * // Interrupción comunicación serial
 * * *enable_interrupts(INT_TIMER0);
 * * *...
 * }

 * while(true){
 * * *RESTART_WDT();
 * * *// VALIDACIÓN DE RECEPCIÓN
 * * *if(recep==1){
 * * * * RESTART_WDT();
 * * * * for(pos=0;pos<=br-1;pos++){fun_1(pos,temp[pos]);}
 * * * * for(pos=0;pos<=32;pos++){temp[pos]=0;}
 * * * * temp2=fun_2();
 * * * * fun_3(temp2);
 * * * * temp2=0;
 * * * * recep=0;
 * * *}
...
 * }
}

Y en la librería está de esta forma:

Código:
...

void fun_1(int cn,int dato){
	brr[cn]=dato;
}

int fun_2(){
	int rx;
...
	rx=brr[0];
...
}
...

Ya está recibiendo datos, lo que sucede es que está haciendo algo que no debería

La función principal del código global es encender o apagar un bombillo de varias formas o a varios niveles (un dimmer)
La prueba la estoy haciendo con dos comandos básicos: encender o apagar
Cualquiera de los dos apaga el LED y lo enciende por algo menos de medio segundo
Solamente hace eso y no lo hace siempre, solo tras varios envíos del comando

No se si puede estar fallando a la hora de hacer la recepción o qué puede ser
 
Atrás
Arriba