Autor Tema: interrupcion por conteo  (Leído 7173 veces)

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

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
interrupcion por conteo
« en: 24 de Enero de 2010, 21:03:43 »
Muchachos necesito incorporar en un while(true) de una lectura del rtc lo siguiente:

el incremento de una variable hasta 60  ( seran segundos que recibira del rtc)y que produzca una interrupcion
para ello leo un pin del puerto b (B1) que es por donde van a ingresar los pulsos
 
int pulsos=0;            // inicio el contador   lo defino

if (input(pin_b1==1))    // leo el puerto
     {pulsos++              // incremento
      if(pulsos==60)  ///aca tendria que producirse una interrupcion 
      }


cuando se produzca la interrupcion atendera una funcion de grabado en memoria externa .
La pregunta es: como configuro la interrupcion en este if y en la funcion a la que llamo
gracias!!!
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: interrupcion por conteo
« Respuesta #1 en: 24 de Enero de 2010, 21:23:39 »
Generar una interrupción? Lo que tienes que hacer es al llegar a 60 llamar a una función que haga lo que tenga que hacer. Y debes agregar un while(pin_b1==1); para que espere a que ocurra el flanco descendente, sino contará de forma errónea.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #2 en: 24 de Enero de 2010, 21:51:22 »
Lo que sucede suky que se va a meter  en ese bucle hasta contar 60. y despues llama a la funcion. durante ese tiempo muerto no voy a ver los segundos del reloj en el lcd por eso queria ver lo de la interrupcion
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: interrupcion por conteo
« Respuesta #3 en: 24 de Enero de 2010, 22:11:45 »
Configura el Timer0 como contador de pulsos externos, precarga el timer0 con el valor (256-60) y conecta lo que esta ahora en RB1 al pin de entrada del Timer0(¿RA4?).

Habilita la interrupciones pertinentes, y deberia interrumir el timer0 cuando recibas 60 pulsos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: interrupcion por conteo
« Respuesta #4 en: 24 de Enero de 2010, 22:50:37 »
Lo que sucede suky que se va a meter  en ese bucle hasta contar 60. y despues llama a la funcion. durante ese tiempo muerto no voy a ver los segundos del reloj en el lcd por eso queria ver lo de la interrupcion

jejeje! Claro, tienes toda la razón, lo que queda es hacer lo que indica Bruno, pero dependiendo del timer tiene su pin especifico para recibir los pulsos. Cuando ocurra una interrupción al recibir los 60 pulsos, activa una bandera para tratarla en el bucle principal, no es recomendable hacer demasiadas tareas en una rutina de servicio de interrupción.


Saludos!
« Última modificación: 24 de Enero de 2010, 22:52:39 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #5 en: 25 de Enero de 2010, 12:17:45 »
Incorporo a mi programa pricipal estas lineas de configuracion del timer0 y una atencion de interrupcion:


El código del ejemplo será el siguiente:

#include <16F877A.h>
#fuses XT,NOWDT
#use delay(clock=4000000)
-------
------
-------


   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);  // configuro el timer como contador
   enable_interrupts(INT_TIMER0);              // habilito el int             
   enable_interrupts(GLOBAL);
   set_TIMER0(0xF1);                           //inicializa el timer0
                                               //el bucle infinito es necesario ya que si el micro entra en sleep
                                               //desactiva la interrupción del TMR0   
     
      //configuro puerto B PinB0 como salida
   
   bit_clear(option_reg,7);     // habilitacion de pull-up
   bit_clear(trisb,0);          // B0 como salida
   bit_clear(portb,0);          // apago señalizacion






void TIMER0_isr(void)                 //function interrupción TMR0
{
   
bit_set(portb,0);                   //enciendo led
delay_ms (100);                    // retardo
bit_clear(portb,0);               //apago led
set_TIMER0(0xF1);                 //inicializa el timer
   


Cuando compilo me da los siguientes errores

Executing: "C:\Archivos de programa\PICC\Ccsc.exe" +FM "final.c" +DF +LN +T +A +M +Z +Y=9 +EA
>>> Warning 203 "C:\ARCHIV~1\PICC\drivers\ds1307.c" Line 233(1,1): Condition always TRUE
*** Error 51 "final.c" Line 144(1,5): A numeric expression must appear here
*** Error 51 "final.c" Line 157(1,5): A numeric expression must appear here
*** Error 79 "final.c" Line 197(2,3): Expect }
      3 Errors,  1 Warnings.

estoy cometiendo algun error en las lineas agrgadas a mi programa???

Gracias!!!!
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: interrupcion por conteo
« Respuesta #6 en: 25 de Enero de 2010, 13:01:05 »
Saludos

Tienes que tener en cuenta que la interrupción se ejecuta a penas ocurre la causa de interrupción y sale de void o de la función que se esta ejecutando para atender la interrupción "valaga la redudancia  :D :D" .

Además debes tener la directiva adecuada para desborde del timer 0 la directiva es la siguiente #int_rtcc por ejmplo ha ocurrido un desborde por el timer 0 entonces como debes hacer la rutina

Código: [Seleccionar]
#int_rtcc
void TIMER0_isr(void)                 //function interrupción TMR0
{
   
bit_set(portb,0);                   //enciendo led
delay_ms (100);                    // retardo
bit_clear(portb,0);               //apago led
set_TIMER0(0xF1);                 //inicializa el timer
   



Seria bueno que publicaras todo el código ;-).

Que es lo único diferente es la directiva de interrupción que indica que lo que sigue es la atención por desborde del timer0, debes tener en cuenta que el compilador limpia la banderas pero es obligación del programador configurar adecuadamente el micro.
Un saludo desde Pereira - Colombia

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #7 en: 25 de Enero de 2010, 13:38:52 »
incorporo esa directiva pero sigo con los errores: he aqui el codigo
coloco #int_rtcc ò #int_timer0

//////////////////////////////////////////////////////////////////////////////////
#include <16f887.h>            //pic a utilizar          
#device  *=16 ADC=10;
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT            //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz
#use fast_io(B)
#use rs232(baud=9600,parity=N, xmit=PIN_C6, rcv=PIN_C7,bits=8,)   //manejo del RS232         
#include <24256.c>                        //libreria eeprom 24LC256
#include <lcdflex.c>
#include <STDLIB.H>
#include <ds1307.c>
#byte trisb=0x86
#byte portb=0x06
#byte option_reg=0x81
////////////////////DECLARACION DE VARIABLES GLOBALES

long i;
int dir=0;
boolean menu;        //si menu=0 se muestra el menu de inicio...
//void rs232 (void);   
int temp=0;
int adress1=0;
float const resoluc=5.0/1024.0;
unsigned int16 rref=0;
long value=0;
float vref=0;
float tvolt=0;
int min,hr,sec,day,mth,year,dow;



//////////////////// FUNCION INTERRUPCION///////////////////////////////

#int_rda

void rs232()
{
    char digito;               //...variables
   
 
   digito=getc( );               //almaceno dato serial(rs232) en digito
   
   puts("****************************************************" );   
   
   switch(digito){
     
       case '0':     
                 menu=!menu;                  //muestra menu
                  break;
      //case '1':      puts("opcion 1 ");
        //             puts("Configurando Reloj" );   //llena memoria 0xff
          //           puts(" Configurado!" );
            //         break;
                     
         case '2': 
                  lcd_gotoxy(1,1);
                  printf(lcd_putc,"enviando datos ",);
                  adress1=0;
               
                    for(i=0; i<=0x7fff;i++)
                    {
                    printf("Byte %lu=%2u\n\r",i,read_ext_eeprom(adress1++));
                    }
                    puts ("fin de lectura");       
                     break;
         
         case '3':
                   setup_adc(ADC_CLOCK_INTERNAL); 
                   set_tris_a(0xff);
                   lcd_init();
                   delay_ms(6);   
    
          while(TRUE)
               {   
   
     
      //configuro puerto B PinB0 como salida
   
   bit_clear(option_reg,7);     // habilitacion de pull-up
   bit_clear(trisb,0);          // B0 como salida
   bit_clear(portb,0);          // apago señalizacion
   
        //configuro conversor para lectura analogica
       
       setup_adc_ports( 0x0000);  //configuro al conversor entre VSS y VDD   
       set_adc_channel(3);      //para leer el canal 3
       rref=read_adc();
       setup_adc_ports(0x1000);//configuro al conversor entre vss y vref
       set_adc_channel(4); //para leer el canal 4 del sensor
      
      // configuro rtc
  ds1307_init(DS1307_ALL_DISABLED);
  ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ);   
  ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
  ds1307_set_date_time(23,01,10,4,18,10,0); 
   while(TRUE)
      {
       value=read_adc();
      //calculos
        vref=rref*resoluc;
                 //tvolt=valor*resoluc;
       tvolt=value*vref/1024;
       temp=(tvolt*1000-500)/10;
         
   
       /////////////////se lee rtc
 delay_ms(10);

 ds1307_get_date(day,mth,year,dow);        /// se obtiene la fecha 
 ds1307_get_time(hr,min,sec);             /// se obtiene la hora

       //////////////escribo las variables en la ext eprom
 write_ext_eeprom (dir++,value);
 write_ext_eeprom (dir++,(value>>8));
 write_ext_eeprom (dir++,hr);
 write_ext_eeprom (dir++,min);
 write_ext_eeprom (dir++,day);
 write_ext_eeprom (dir++,mth);   

     ///////////////////////////////visualizacion
      delay_ms(100); 
      lcd_gotoxy(1,1);
      printf(lcd_putc,"%02d/%02d/%02d ",day,mth,year);// por lcd fecha
      //printf(lcd_putc,"vref:%2.1f ",vref);
      lcd_gotoxy(11,1);
      printf(lcd_putc,"uv:");
      lcd_gotoxy(1,2);
      //printf(lcd_putc,"tvolt: %f ",tvolt);
      printf(lcd_putc,"%02d:%02d:%02d ",hr,min,sec); // por lcd hora
      lcd_gotoxy(11,2);
      printf(lcd_putc,"T: %2.0d  ",temp);
      printf("%2.0d \n\r",temp);//  A la pc hiperterminal
      //printf("%2.0lu\n\r",value);
      if(dir==0x7fff) dir=0;
       } 
       }       
          break;
       
//  funcion de la interrupcion       
#int_timer0 //la siguiente función tiene que ser la de interrupción del TMR0
void timer0_isr(void) //function interrupción TMR0
{
   bit_set(portb,0);   //enciendo led
delay_ms (100);        // retardo
bit_clear(portb,0); //apagp led
set_TIMER0(0xF1); //inicializa el timer



///////////////////////////////////PROGRAMA PRINCIPAL///////////////////////

void main(void)



{
   //configuro interrupcion por tmr0
                  
   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   set_TIMER0(0xF1); //inicializa el timer0
                     //el bucle infinito es necesario ya que si el micro entra en sleep
                     //desactiva la interrupción del TMR0   
 lcd_init();
 delay_ms(6);
 lcd_gotoxy(1,1);
 printf(lcd_putc,"select menu PC",);
 
   disable_interrupts (global);
   enable_interrupts(int_rda);      //activo interrupcion serial rs-232
   enable_interrupts(global);      //habilito la interrupcion
   //   init_ext_eeprom( );
   
   do{            //bucle...
   
     puts("                                   ");
      puts("Lectura/Escritura de EEPROM 24LC256");     
      puts("==============================================" );
      puts("Seleccione opcion:" );
      puts("-------------------------------------" );
      puts("   0->Ver opciones" );
      //puts("   1->Configurar reloj" );
      puts("   2->Lectura EEPROM" );
      puts("   3->Sensado y Escritura de variable" );
      //puts("   4->Escritura en EEPROM" );  //...principal
   
      menu=1;                     //muestra menu solamente una vez
      while(menu==1){ }            //espera tecla pulsada por teclado(rs-232)

   } while(TRUE);   //...infinito
}   

Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: interrupcion por conteo
« Respuesta #8 en: 25 de Enero de 2010, 14:10:37 »
Saludos.

En la interrupción #int_rda veo un problema creo que te falta una o dos llave por cerrar que es la del inicio al final en el break y otra la del while(true) ya que tienes dos while(true) y uno lo cierras y el otro no.
Un saludo desde Pereira - Colombia

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #9 en: 25 de Enero de 2010, 18:59:48 »
Bien, ahora si. veremos como anda en el hard.
si hace lo que tiene hacer.
Gracias
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #10 en: 25 de Enero de 2010, 22:49:15 »
Cuando programo el timer0 como contador. va a recibir los pulsos por el RA4, lo tengo que programar como entrada a este PIn  o ya esta por defeto en la configuracion del timer0
Gracias
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: interrupcion por conteo
« Respuesta #11 en: 25 de Enero de 2010, 23:50:24 »
Configuralo como entrada
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: interrupcion por conteo
« Respuesta #12 en: 26 de Enero de 2010, 00:44:29 »

Saludos. Cual era el problema kidpic del código?
Un saludo desde Pereira - Colombia

Desconectado kidpic

  • PIC16
  • ***
  • Mensajes: 231
Re: interrupcion por conteo
« Respuesta #13 en: 26 de Enero de 2010, 12:37:19 »
faltaba cerrar las llaves. Ahora no rsponde a la interrucion. probarè de configurar al ra4 como entrada.
Gracias.
Si quieres trascender..., enseña humildemente  lo que sabes.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: interrupcion por conteo
« Respuesta #14 en: 26 de Enero de 2010, 13:21:22 »
Por ahi lo que te esta pasando, es que tenes RA4 configurada como analogica. Asegurate de configurar todos los pines que no necesites con analógicos como digitales para poder usarlos sin problemas.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.