Autor Tema: ayuda int_ext  (Leído 2475 veces)

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

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
ayuda int_ext
« en: 21 de Febrero de 2009, 04:09:55 »
hola a todos.
soy novato con la programacion en c para pics y estoy en un embrollo padre, mi intencion es la de escribir un codigo que mediante la interrupcion externa (rb0) cuando suceda un pulso (mejor dicho cuando detecte un flanco ascendente) vaya contando la duracion del estado en alto y si esta exede el segundo ponga en alto ra0 y cuando detecte un flanco descendente ponga ra0 en bajo.

para esto se que tengo que usar la directiva: INT_EXT, que ademas tengo que usar la deteccion de flanco: ext_int_edge(0,H_TO_L), y de alguna manera milagrosa usar el timer interno para contar la duracion del pulso.
la cuestion es que no doy pie con bola, me siento como bola sin manija para armar el codigo.
me he leido el post microcursillo de c y el post serie de tecnicas en c (de redpic), de esos post e llegado a las nociones que les digo, pero estoy trabadisimo. el post de red pic "midiendo un pulso" no me sirve, porque la medicion se concreta una vez finalizado el pulso, yo necesito hacerla durante el pulso.

no les pido que me tiren el codigo ya armado, sino alguna nocion, mientras tanto seguire intentando.
muchas gracias.

Desconectado QIQE

  • PIC18
  • ****
  • Mensajes: 335
Re: ayuda int_ext
« Respuesta #1 en: 21 de Febrero de 2009, 08:00:55 »
Pon el código que tienes hecho y así te podemos decir que e slo que no está funcionando.
Muchas gracias por vuestro tiempo.

Saludos desde valencia!!!

Desconectado chacruna

  • PIC10
  • *
  • Mensajes: 41
Re: ayuda int_ext
« Respuesta #2 en: 21 de Febrero de 2009, 11:58:45 »
Quizás ésto te sirve, fijate que cuando detecta la interrupción activa el timer que cuando desborda (cada 0.1mS) actualiza un contador (variable ticks).

Código: [Seleccionar]
#include <16F84A.h>

#fuses XT,NOWDT,NOPROTECT,PUT
#use delay (clock=4000000)
#use fast_io(b)

int ticks;

#INT_TIMER0
void int_timer() { //desborda cada 0.1mS
      set_timer0(156);
      ticks++; // 1 ticks = 0.1mS
}

#INT_EXT
void int_rb0() { //CUANDO PASA DE H_TO_L empieza a contar
ticks = 0;
set_timer0(0);
   enable_interrupts(INT_TIMER0);
}

void main() {
      set_tris_b(0x1); //RB0 COMO ENTRADA   

      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);
      ext_int_edge(H_TO_L);

     
      enable_interrupts(INT_EXT);
      enable_interrupts(GLOBAL);

      delay_ms(200); // tiempo de estabilizacion del pic

      while(1) {
       if(ticks==10000) {
               disable_interrupts(INT_TIMER0);
               disable_interrupts(INT_EXT);
               //lo que quieras cada un segundo por ejemplo
               enable_interrupts(INT_RB);
             }
      }
}

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
Re: ayuda int_ext
« Respuesta #3 en: 21 de Febrero de 2009, 15:05:20 »
muchas gracias chacruna, me diste el empujon que necesitaba.

agrego el codigo, todavia no estoy seguro de haberlo hecho bien.
criticas y comentarios, son mas que bienvenidos:

Código: C
  1. /////////////////////////interrupcion puerto B pic16F84////////////////////
  2. // se detecta por interrupcion en RB0 un pulso por flanco ascendente     //
  3. // una vez detectado se le toma el tiempo, si el mismo exede 1segundo    //
  4. // RA0 se pone en 1                                                                                                              //
  5. // cuando se detecta un flanco negativo si RA0 estaba en 1 vuelve a 0    //
  6. ///////////////////////////////////////////////////////////////////////////
  7.  
  8. #include <16F84.h>                              //pic a utilizar
  9. #fuses XT,NOWDT,NOPROTECT               //fusibles
  10. #use delay(clock=4000000)               //velocidad del cristal
  11. #use fast_io(A)
  12. #use fast_io(B)
  13.  
  14. #byte port_a=5                                  //puerto A
  15.  
  16. /////////////////////////////variables/////////////////////////////////////
  17.  
  18. int1 flanco=0;                                  //flanco es una variable de un bit
  19. int16 ticks=0;                                  //ticks es una variable de 16 bits      
  20.  
  21. ///////////////////////////////////////////////////////////////////////////
  22.  
  23. #INT_EXT                                                                //interrupcion externa en RB0
  24. void interrupcionRB0() {
  25.         if (flanco==0){                                         //se detecto flanco ascendente
  26.                 set_timer0(156);                                //pongo el valor 156 en el timer, le quedan por contar
  27.                                                                                 //100 microsegundos
  28.                 enable_interrupts(INT_TIMER0);  //habilito la interrupcion por desborde del timer0
  29.                 ext_int_edge(0,H_TO_L);                 //configuro para que detecte flancos descendentes
  30.                 ticks=0;                                                //inicializo el contador en cero                       
  31.                 flanco=1;                                               //indico que el proximo flanco es descendente
  32.  
  33.         } else {                                                        //se detecto flanco descendente
  34.                 ext_int_edge(0,L_TO_H);                 //configuro para que detecte flancos ascendentes
  35.                 flanco=0;                                               //indico que el proximo flanco es ascendente
  36.                 disable_interrupts(INT_TIMER0); //desabilito la interrupcion por desborde de timer0
  37.                 ticks=0;                                                        //elimino el valor anterior (menor a 10000) vuelvo a inicializarlo
  38.                 port_a=0;                                               //pongo a cero el puerto A
  39.                 }
  40.         }
  41.  
  42. #INT_TIMER0                                                             //interrupcion por desborde de timer0
  43. void int_timer() {                                              //desborda cada 0.1mS
  44.       set_timer0(156);                                  //despues del desvorde le vuelvo a signar el vlaor 156
  45.       ticks++;                                                  // ticks se incrementa en 1 cada 0.1mS (100 microsegundos)
  46. }
  47.  
  48. void main () {
  49.  
  50.         delay_ms(333);                                  //pausa mientras se estabiliza el pic
  51.         disable_interrupts(global);             //desabilito todas las instrucciones que voy a usar
  52.         disable_interrupts(int_ext);
  53.         disable_interrupts(INT_TIMER0);
  54.         delay_ms(333);                                  //estabilizo y pongo a "cero" el pic
  55.  
  56. ///////////////inicializo las partes a usar del pic///////////////////////
  57.  
  58.         set_tris_a(0b00000);                                            //todo el puero a como salidas
  59.         port_a=0;                                                                       //pongo a cero todo el puerto A
  60.         set_tris_b(0b00000001);                                         //selecciono RB0 como entrada
  61.        
  62.         ext_int_edge(0,L_TO_H);                                         //configuro para que detecte flancos ascendentes
  63.         flanco=0;                                                                       //indico que el flanco detectado es ascendente
  64.         enable_interrupts(int_ext);                                     //habilito la interrupcion externa
  65.         enable_interrupts(global);                                      //habilito el uso de interrupciones
  66.         setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);        //habilito timer0 como contador interno,
  67.                                                                                                 //cada cuatro ciclos de reloj se incrementa en 1
  68.         do {
  69.        
  70.                 if (ticks==10000) {                     //si ticks = 10000 paso un segundo (0,1mseg * 10000)
  71.                         port_a=0b00001;                 //pongo a 1 RA0
  72.                 }                              
  73.  
  74.         } while (TRUE);
  75.         }
« Última modificación: 21 de Febrero de 2009, 18:52:33 por lagruya »

Desconectado chacruna

  • PIC10
  • *
  • Mensajes: 41
Re: ayuda int_ext
« Respuesta #4 en: 21 de Febrero de 2009, 16:39:25 »
Hola como andas,

me equivoque en el prescaler, lo tenés que setear en 1 para que desborde cada 100uS
Código: [Seleccionar]
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1)

..me hiciste entrar en duda con el set_timer0(155).

yo lo habia calculado como 156 con la formula ((4 x Preescaler x (256-156)) / 4000000) = 100uS


saludos

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
Re: ayuda int_ext
« Respuesta #5 en: 21 de Febrero de 2009, 18:45:26 »
tenes razon con respecto a lo de 156, porque el contador cuenta hasta 255, pero arranca del valor 0. por eso se le resta 256 y para que cunete 100 tenemos que usar 156 no 155.

haber si entiendo bien lo del timer y el prescaler:
si el prescaler lo pongo a 4 se incrementara en 1 cada 16 pulsos de reloj

el maximo valor que puedo medir con el timer0 a 4MHz seria:
(4/FOSC) * 256 (valor maximo del contador) * 256(prescaler rate)
4/4000000 * 256 * 256 = 0,065536 seg = 65,536ms

con el prescaler a 1 el maximo valor a medir seria:
4/4000000 * 256 * 1 = 0,000256 seg = 256µs

yo quiero contar 100µseg entonces:

4/4000000Hz * (256 - x) = 100µs
256 - x = 100µs / 1µs = 100
x = 256 - 100 = 156

de ahi el set_timer0(156)

muchas gracias chacruna , me has hecho compreder esto mucho mas de lo que creia!
el codigo como lo ven? lo simule en mplab y creo que funca, pero tambien soy muy novato con el mplab, ahora lo voy a proban en mi entrenadora (pero para eso tengo que fabricarme el modulo de pulsadores para el puerto B  :oops: que todavia no hice)

muchas gracias denuevo.





« Última modificación: 21 de Julio de 2009, 00:58:36 por lagruya »


 

anything