TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: MINDFIELD en 17 de Mayo de 2015, 09:10:14

Título: Como interpretar interrupcion
Publicado por: MINDFIELD en 17 de Mayo de 2015, 09:10:14
Buen dia tengo un par de lineas de codigo dentro del void main()

Código: [Seleccionar]
void main()
{
   enable_interrupts(global);
   enable_interrupts(int_ext | l_to_h);
   setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);  

   while...

quien me puede explicar como funcionan estas dos lineas

enable_interrupts(int_ext | l_to_h);

setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
Título: Re: Como interpretar interrupcion
Publicado por: KILLERJC en 17 de Mayo de 2015, 10:48:18
Para eso deberias de tener a mano el manual de CCS ( busca en google "CCS manual"), de todas formas un poco de ingles lo soluciona.


Código: [Seleccionar]
enable_interrupts(int_ext | l_to_h);
This function enables the interrupt at the given level. An interrupt procedure should have been defined for the indicated interrupt.
Enabling interrupts does not clear the interrupt flag if there was a pending interrupt prior to the call. Use the clear_interrupt( ) function to clear pending interrupts before the call to enable_interrupts( ) to discard the prior interrupts.

TL;DR; = hanilita las interrupciones, en ese caso imagino que habilita la interrupcion externa (ext ) que es el RB0 y setea la pendiente para cuando ocurra la interrupcion en un flanco ascendente (l_to_h = low to high = bajo a alto)

Código: [Seleccionar]
setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
Como el nombre de la funcion lo dice, es para configurar el timer 0. A veces llamado tambien RTCC.
Estaria seteandolo para que la entrada de clock sea del mismo oscilador y no de un pulso externo, con un preescaler de 128 y parece ser que tiene la opcion de ser de 16bits, pero lo configura como 8 bits.
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 17 de Mayo de 2015, 11:59:15
Esta interrupcion crearia un ciclo de un segundo?, como saco la cuenta?
Título: Re: Como interpretar interrupcion
Publicado por: KILLERJC en 17 de Mayo de 2015, 12:21:08
Utiliza el oscilador.. Asi que seria

4 / Fosc
Con un oscilador interno de 8Mhz

4 / 8Mhz = 500ns = 0.5us

Ahora tenemos el preescale de 128

0.5us * 128 = 64us

Cada 64 us cuenta 1. Suponiendo que se ponga a 0 el timer, es decir que tiene que contar 255 hasta el overflow:

64us * 255 = 0.0163s

Asi que deberias tener unas  61.35 interrupciones para llegar al segundo..

Asi que serian 61 interrupciones FULL y otra que tiene que durar:
0.35 * 0.0163s = 5.7ms

Deberia contar:
5.7ms / 64us  = 89

Como el timer es un contador ascendente, deberia rellenar con el complemento a 2.
Es decir deberias cargarlo con : (256-89) = 167
A la interrupcion numero 62
Todo esto suponiendo que son 8Mhz
Título: Re: Como interpretar interrupcion
Publicado por: RALF2 en 17 de Mayo de 2015, 13:13:44
Y te puedes ayudar tambien con esta (http://www.picbasic.co.uk/forum/showthread.php?t=4994) buena herramienta  :mrgreen:

Saludos
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 17 de Mayo de 2015, 19:42:56
Gracias por responder, estoy jugando con este codigo ahora

Código: [Seleccionar]
#include <16F877A.h>
//#FUSES NOWDT, HS, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#FUSES NOWDT, HS, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#use delay(clock=16000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1)
#use standard_io(d)

int flanco=0;
int dly0=0;
int8 dly1=0;

char valor_B;
char COM0;
char COM1

#int_EXT
void  EXT_isr(void)
   {
   output_d(0b00000000);      //configuro todo el puerto b como salida
    
   if (flanco==1)
   {set_timer0(255-dly0);
   while(get_timer0()>0);     //espera hasta que timer0 se desborde
   {
   ext_int_edge(h_to_l);
   flanco=0;
   output_high(pin_d0);
   }
   }
   else
   {set_timer0(255-dly0);
   while(get_timer0()>0);     //espera hasta que timer0 se desborde
   {
   ext_int_edge(l_to_h);
   flanco=1;
   output_high(pin_d0);
   }
   }
 if (flanco==1)
   {
   set_timer0(255-dly1);
   while(get_timer0()>0);     //espera hasta que timer0 se desborde
   {ext_int_edge(h_to_l);
   flanco=0;
   output_high(pin_d1);
   }
   }
   else
   {
   set_timer0(255-dly1);
   while(get_timer0()>0);     //espera hasta que timer0 se desborde
   {ext_int_edge(l_to_h);
   flanco=1;
   output_high(pin_d1);
   }
   }
}
void main()
{
   set_tris_b(0xff);
   enable_interrupts(global);
   enable_interrupts(int_ext | l_to_h);
   setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);  

   while (TRUE)  
{
        valor_B = getc();
        
        COM     = valor_B;
        COM1  = valor_B;
        
        if (COM == '0')
        {
          //dly0=1;
        }
        if (COM == '1')
        {
           dly0=25;
        }
        if (COM == '2')
        {
           dly0=50;
        }
        if (COM == '3')
        {
           dly0=75;
        }
        if (COM == '4')
        {
           dly0=100;
        }
        if (COM == '5')
        {
           dly0=125;
        }
        if (COM == '6')
        {
           dly0=150;
        }
        if (COM == '7')
        {
           dly0=200;
        }
        if (COM == '8')
        {
           dly0=225;
        }
        if (COM == '9')
        {
           dly0=254;
        }
        //****************************************************************
        if (COM1 == '0')
        {
          
        }
        if (COM1 == '1')
        {
          
        }
        if (COM1 == '2')
        {
          
        }
        if (COM1 == '3')
        {
          
        }
        if (COM1 == '4')
        {
          
        }
        if (COM1 == '5')
        {
          
        }
        
        if (dly0==255) dly0=254; //no pasa de 255
        if (dly1==255) dly1=254; //no pasa de 255
        
        if (dly0==0) dly0=1;      //no baja de 1
        if (dly1==0) dly1=1;      //no baja de 1
}

}

El problema que tengo es que cuando COM1 llegan hasta dly0=75 o dly0=100 se "bloquea" el programa en el

while(get_timer0()>0);     //espera hasta que timer0 se desborde

no entiendo el porque... tambien puedo varear el valor de COM1 rapidamente en pocos segundos pero despues hace lo mismo, siempre se queda en ese while  :(
Título: Re: Como interpretar interrupcion
Publicado por: RALF2 en 17 de Mayo de 2015, 20:00:51
Una posible solucion seria, preguntar por la bandera del timer0 y no tomar el valor que tiene el timer0.
Para ello borras la bandera y luego preguntas por el estado de esta.
Prueba y nos comentas.   :mrgreen:
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 17 de Mayo de 2015, 21:01:57
Como me gustaria entender todo lo que me decis  :lol: voy a estudiarlo y en la proxima respuesta aviso que tal me fue...
Título: Re: Como interpretar interrupcion
Publicado por: RALF2 en 17 de Mayo de 2015, 21:52:11
Como me gustaria entender todo lo que me decis  :lol: voy a estudiarlo y en la proxima respuesta aviso que tal me fue...
  :shock:

ASi:
#bit Flag_TMR0= getenv("BIT:TMR0IF") 

void main()
{
   if(FLAG_TMR0)   // Si el flag_tmr0 es igual a 1, hago algo ...
     ...

}
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 17 de Mayo de 2015, 22:58:11
Gracias por tú interes, antes de hacer lo que tú dices me di cuenta que en esta linea

while(get_timer0()>0);     //espera hasta que timer0 se desborde
   {

está el punto y coma, de esa manera funciona pero despues queda en el bucle y si saco el punto y coma no hace nada...
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 18 de Mayo de 2015, 18:40:54
y de la manera que me digiste RALF2 no me funciona
Título: Re: Como interpretar interrupcion
Publicado por: thegame en 19 de Mayo de 2015, 13:14:50
Creo que no vendría mal un poco de reorganización del código..... talves sacar algo de lo que haces en la interrupcion.
Agrega ERRORS a la directiva del RS232
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 19 de Mayo de 2015, 18:06:58
Hola! no entiendo lo de que agrega errores a la directiva del rs232, ami no me genera ningun error ni avisos de peligro o warning, lo de organizacion si es verdad voy a tratar de hacerlo lo mejor posible! pasa que no entiendo mucho donde va cada cosa, cada directiva, sentencia o lo que sea; Estuve metiendo mano en el codigo y si al pre-escaler lo bajo a 4 obviamente no funciona igual pero no se queda en el bucle while(get_timer0()>0); porque no se queda en el bucle?
Título: Re: Como interpretar interrupcion
Publicado por: thegame en 19 de Mayo de 2015, 19:38:03
Me referia a lo siguiente:

Tu tienes
Código: [Seleccionar]
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1)

Yo digo que lo completes asi:

Código: [Seleccionar]
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1,ERRORS)
Al agregar el parametro ERRORS, si llegase a existir un error en la comunicacion se borrara y reseteara el modulo RS232 del PIC, continuando con la operacion normal, como dije en otros post, tambien es bueno revisar las banderas de error en el registro de estatus del modulo RS232, y de paso la ayuda de CCS
Título: Re: Como interpretar interrupcion
Publicado por: MINDFIELD en 19 de Mayo de 2015, 19:49:23
SOS UN MAESTRO!!!!  ((:-)) ((:-)) ((:-)) ahora si fubciona!!! cuando crezca quiero ser como ustedes  :mrgreen: espero poder avanzar con el codigo sin problemas!
Gracias a todos!!