Autor Tema: problema con interrupcion rb0  (Leído 1737 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado lucaspascual

  • PIC10
  • *
  • Mensajes: 31
problema con interrupcion rb0
« en: 06 de Mayo de 2013, 10:07:12 »
Buenos dias. Tengo un problema con la interrupcion externa RB0, la es activada por unos pulsos de clock. La misma se activa solo una vez cuando arranca el micro pero una vez q se salta la interrupcion no vuelve a producirse. Quisiera saber si no hay que borrar algun flag o algo por el estilo porq ya probe haciendo muchas cosas y no encuentro solucion.
A continuacion adjunto el codigo en CCS. Dentro de la interrupcion lo que hago es guardar 8 bits que llegan por el puerto en un registro llamado dato y realizo un pulso para poder ver donde se realizo el muestreo.

Código: [Seleccionar]
#include <16f877.h>
#fuses hs,nowdt,put,nowrt,nolvp,noprotect
#use delay(clock=20000000)
#use fast_io(b)
#include <lcd.c>

int8 dato=0x00;


#int_ext
ext_isr()
{
delay_us(498);   
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,0);}
else{
bit_clear(dato,0);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,1);}
else{
bit_clear(dato,1);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,2);}
else{
bit_clear(dato,2);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,3);}
else{
bit_clear(dato,3);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,4);}
else{
bit_clear(dato,4);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,5);}
else{
bit_clear(dato,5);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,6);}
else{
bit_clear(dato,6);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,7);}
else{
bit_clear(dato,7);}
clear_interrupt(int_ext);

}

void main()
{
set_tris_b(0x03);
port_b_pullups(true);
output_low(PIN_B7);
output_low(PIN_B6);
lcd_init();
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(l_to_h);
while(1)
{

printf(lcd_putc,"\ndato= %u",dato);
delay_ms(50);

}
}


Desde ya muchas gracias y saludos

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: problema con interrupcion rb0
« Respuesta #1 en: 06 de Mayo de 2013, 11:23:13 »
Hola lucaspascual, de que velocidad es el clock externo? Te lo pregunto porque leyendo el código rápidamente veo que tienes muchos delays dentro de la interrupción, no sea que tengas un problema de tiempos.  También veo que tienes una instrucción clear_interrupt(int_ext); al final de la interrupción.  El CCS normalmente se encarga de setear o borrar los flags necesarios, de modo que creo que esa instrucción sobra en este caso. También veo que tienes una serie de instrucciones If - Else preguntando siempre por el estado del pin_b1 sin ninguna otra condición; lo que ocurre aquí es que estas instrucciones se ejecutan a mucha velocidad y solo vas a ver el resultado de la última.  Por la misma razón, (cambia inmediatamente de estado alto a bajo) también vas a ver siempre el pin_b7 en estado bajo. Si tu velocidad de reloj externo lo permite, lo mejor sería solo activar una variable bandera (int1) dentro de la interrupción y según el estado de esta, ejecutar el código que creas conveniente en el main().

Saludos!

Desconectado lucaspascual

  • PIC10
  • *
  • Mensajes: 31
Re: problema con interrupcion rb0
« Respuesta #2 en: 06 de Mayo de 2013, 11:48:03 »
Hola lucaspascual, de que velocidad es el clock externo? Te lo pregunto porque leyendo el código rápidamente veo que tienes muchos delays dentro de la interrupción, no sea que tengas un problema de tiempos.  También veo que tienes una instrucción clear_interrupt(int_ext); al final de la interrupción.  El CCS normalmente se encarga de setear o borrar los flags necesarios, de modo que creo que esa instrucción sobra en este caso. También veo que tienes una serie de instrucciones If - Else preguntando siempre por el estado del pin_b1 sin ninguna otra condición; lo que ocurre aquí es que estas instrucciones se ejecutan a mucha velocidad y solo vas a ver el resultado de la última.  Por la misma razón, (cambia inmediatamente de estado alto a bajo) también vas a ver siempre el pin_b7 en estado bajo. Si tu velocidad de reloj externo lo permite, lo mejor sería solo activar una variable bandera (int1) dentro de la interrupción y según el estado de esta, ejecutar el código que creas conveniente en el main().

Saludos!
Hola bmb muchas gracias por tomarte el trabajo de ver mi programa.
Mira te paso a contar, la velocidad del clock es de 77 Khz, probe la interrupción en otro programa con este clock y funcionaba perfectamente y podía ver con los pulsos q le puse en cada if-else donde muestreaba la señal, funcionaba muy bien, solo que el dato que tomo por el portb1 no era leído, y guardado en dato, salvo cuando tenia ese puerto en 5 V o masa en el lcd, me mostraba el dato 255 o 0 (aparentemente funcionando bien), es como que el dato por el puerto pasaba demasiado rapido y no era leido. Otro problema q tengo es q cuando dejo el portb1 en 5V o 0V y enciendo el micro me toma el primer valor en el que esta, y si cambio a otro valor no vuelve a cambiar en el lcd (como si saltara una sola vez a la interrupción). Espero haberme hecho entender jjaja.

Desconectado lucaspascual

  • PIC10
  • *
  • Mensajes: 31
Re: problema con interrupcion rb0
« Respuesta #3 en: 06 de Mayo de 2013, 12:29:24 »
Código: [Seleccionar]
Algo asi seria con banderas,

[code#include <16f877.h>
#fuses hs,nowdt,put,nowrt,nolvp,noprotect
#use delay(clock=20000000)
#use fast_io(b)
#include <lcd.c>
int8 dato=0x00;
int1 bandera=0x00;
#int_ext
ext_isr()
{
bit_set(bandera,0);


}

void main()
{
set_tris_b(0x03);
output_low(PIN_B7);
output_low(PIN_B6);
port_b_pullups(TRUE);
lcd_init();
enable_interrupts(int_ext);
ext_int_edge(l_to_h);
enable_interrupts(global);

while(bandera==1)
{
delay_us(498);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,0);}
else{
bit_clear(dato,0);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,1);}
else{
bit_clear(dato,1);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,2);}
else{
bit_clear(dato,2);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,3);}
else{
bit_clear(dato,3);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,4);}
else{
bit_clear(dato,4);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,5);}
else{
bit_clear(dato,5);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,6);}
else{
bit_clear(dato,6);}
delay_us(12);
output_high(pin_b7);
output_low(pin_b7);
if (input(pin_b1)==1){
bit_set(dato,7);}
else{
bit_clear(dato,7);}
bit_clear(bandera,0);
printf(lcd_putc,"\ndato= %u",dato);
delay_ms(50);

}
}
]

 Tengo una duda, que hace el while si no se cumple la condicion q esta dentro?
Este programa no me funciona.

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: problema con interrupcion rb0
« Respuesta #4 en: 06 de Mayo de 2013, 13:18:33 »
Hola lucaspascual, aunque insisto en que no creo que tu programa funcione por las razones que te di en el post anterior, con una bandera sería así:

Código: C
  1. #include <16f877.h>
  2. #fuses hs,nowdt,put,nowrt,nolvp,noprotect
  3. #use delay(clock=20000000)
  4. #use fast_io(b)
  5. #include <lcd.c>
  6.  
  7. int8 dato=0x00;
  8. int1 bandera=false;
  9.  
  10. #INT_ext
  11. void ext_isr()
  12. {
  13.    bandera = true;
  14. }
  15.  
  16. void main()
  17. {
  18.    set_tris_b(0x03);
  19.    output_low(PIN_B7);
  20.    output_low(PIN_B6);
  21.    port_b_pullups(TRUE);
  22.    lcd_init();
  23.    enable_interrupts(INT_ext);
  24.    ext_INT_edge(l_to_h);
  25.    enable_interrupts(global);
  26.  
  27.    WHILE(true)
  28.    {
  29.       if(bandera)
  30.       {
  31.          delay_us(498);
  32.          output_high(pin_b7);
  33.          output_low(pin_b7);
  34.  
  35.          IF (input (pin_b1) == 1)
  36.          {
  37.             bit_set (dato, 0) ;
  38.          }
  39.  
  40.          ELSE
  41.          {
  42.             bit_clear (dato, 0) ;
  43.          }
  44.  
  45.          delay_us(12);
  46.          output_high(pin_b7);
  47.          output_low(pin_b7);
  48.  
  49.          IF (input (pin_b1) == 1)
  50.          {
  51.             bit_set (dato, 1) ;
  52.          }
  53.  
  54.          ELSE
  55.          {
  56.             bit_clear (dato, 1) ;
  57.          }
  58.  
  59.          delay_us(12);
  60.          output_high(pin_b7);
  61.          output_low(pin_b7);
  62.  
  63.          IF (input (pin_b1) == 1)
  64.          {
  65.             bit_set (dato, 2) ;
  66.          }
  67.  
  68.          ELSE
  69.          {
  70.             bit_clear (dato, 2) ;
  71.          }
  72.  
  73.          delay_us(12);
  74.          output_high(pin_b7);
  75.          output_low(pin_b7);
  76.  
  77.          IF (input (pin_b1) == 1)
  78.          {
  79.             bit_set (dato, 3) ;
  80.          }
  81.  
  82.          ELSE
  83.          {
  84.             bit_clear (dato, 3) ;
  85.          }
  86.  
  87.          delay_us(12);
  88.          output_high(pin_b7);
  89.          output_low(pin_b7);
  90.  
  91.          IF (input (pin_b1) == 1)
  92.          {
  93.             bit_set (dato, 4) ;
  94.          }
  95.  
  96.          ELSE
  97.          {
  98.             bit_clear (dato, 4) ;
  99.          }
  100.  
  101.          delay_us(12);
  102.          output_high(pin_b7);
  103.          output_low(pin_b7);
  104.  
  105.          IF (input (pin_b1) == 1)
  106.          {
  107.             bit_set (dato, 5) ;
  108.          }
  109.  
  110.          ELSE
  111.          {
  112.             bit_clear (dato, 5) ;
  113.          }
  114.  
  115.          delay_us(12);
  116.          output_high(pin_b7);
  117.          output_low(pin_b7);
  118.  
  119.          IF (input (pin_b1) == 1)
  120.          {
  121.             bit_set (dato, 6) ;
  122.          }
  123.  
  124.          ELSE
  125.          {
  126.             bit_clear (dato, 6) ;
  127.          }
  128.  
  129.          delay_us(12);
  130.          output_high(pin_b7);
  131.          output_low(pin_b7);
  132.  
  133.          IF (input (pin_b1) == 1)
  134.          {
  135.             bit_set (dato, 7) ;
  136.          }
  137.  
  138.          ELSE
  139.          {
  140.             bit_clear (dato, 7) ;
  141.          }
  142.  
  143.          bit_clear(bandera,0);
  144.          printf(lcd_putc,"\ndato= %u",dato);
  145.          delay_ms(50);
  146.          
  147.          bandera = false;
  148.       }
  149.    }
  150. }

Si por la tarde tengo algo de tiempo, voy a mirar com más detenimiento tu programa a ver que te puedo sugerir.  Mientras tanto, me puedes contar cual es la intención final del programa para tener una mejor idea.

Saludos!

Desconectado lucaspascual

  • PIC10
  • *
  • Mensajes: 31
Re: problema con interrupcion rb0
« Respuesta #5 en: 06 de Mayo de 2013, 13:26:06 »
Este proyecto es para leer los datos de un calibre digitial con salida de datos. Tiene dos pines uno es de clock y otro de dato. Voy adjuntar un archivo .rar q contiene informacion del protocolo q usa. Lo q yo hago con los if es guardar los 8 bits q me interesan, pro eso pregunto si esta en 0 o 1 el puerto y luego lo guardo en una variable dato.
Voy a probar ahora lo q me corregiste y te cuento q hace. Muchas gracias nuevamente

Desconectado lucaspascual

  • PIC10
  • *
  • Mensajes: 31
Re: problema con interrupcion rb0
« Respuesta #6 en: 06 de Mayo de 2013, 19:20:04 »
bmb sabes q monte todo para probar el programa q me pasaste y no funciona, me parece q no esta saltando la interrupcion RB0, (desactive el clock y le coloco un pulso en RB0 y taampoco salta). Tambien me paso varias veces q me toma el primer valor cuando enciendo el micro y despues no vuelve a realizar una lectura, como si no se volviera a producir la interrupcion


 

anything