Autor Tema: Ayuda interrupcion externa con CCS  (Leído 13225 veces)

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

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Ayuda interrupcion externa con CCS
« en: 09 de Octubre de 2009, 22:23:07 »
Saludos a todos en esta comunidad, soy nuevo en este foro espero que me enchen y una mano, es un programa pequeñito que lo voy a aplicar a uno mayor explico como funciona:
Cada vez que se produce una int_ext por RB0 el programa cuenta y lo muestra en el LCD dicha cuenta (en la segunda fila )cuando llega a 255 todo empieza de nuevo, en otras palabras cuenta las interrupciones.
No se que tiene a primera vista todo esta bien ahi les adjunto el codigo.

/*=====================================================*/
#include <16f877.h>
#include <lcd.c>
#define  LCD_ENABLE_PIN PIN_D0
#define  LCD_RS_PIN PIN_D1
#define  LCD_RW_PIN PIN_D2
#define  LCD_TYPE 2
#fuses   XT,NOWDT,NOPROTECT,PUT,NOLVP  //ordenes para el programador
#use     delay (clock=4000000)         // Fosc=4Mhz
#use     standard_io(d)

/******************************************************************************/
/*********************   RUTINA DE INTERRUPCION    ****************************/
 int i=0;
 
#INT_EXT

  void IntRB0(){
       i++;
       output_d(i);     
       lcd_gotoxy(1,2);                /* inicia en la segunda linea del LCD */               
       printf(lcd_putc,"%d",i);             
       if(i==0x00FF){
          i=0;
       }
  }

/******************************************************************************/
/***********************   PROGRAMA PRINCIPAL    ******************************/
  void main(void)
  {   
     SET_TRIS_B(0x01);              // PIN RB0 COMO ENTRADA, RB1..RB7 SALIDA
     SET_TRIS_D(0x00);              // PORTD COMO SALIDA
     enable_interrupts(int_ext);    //activar interrupcion externa
     ext_int_edge(L_TO_H);          //config. de int. por flando de bajada
     enable_interrupts(GLOBAL);     //todas las interrupciones desactivadas
 
     lcd_init();
     lcd_gotoxy(1,1);                   /* inicia en la primera linea del LCD */
     printf(lcd_putc,"Muestra el conteo ");         

     while(1){
         output_high (pin_b7);   // enciendo el pin RB7           
         delay_ms(100);
         output_low (pin_b7);    // apago el pin RB7           
         delay_ms(100);
     }                             
  }

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5490
    • Electrónica Didacta
Re: Ayuda interrupcion externa con CCS
« Respuesta #1 en: 09 de Octubre de 2009, 22:26:07 »
pero ¿que dices que hace mal? ¿la cuenta hasta 255? es porque estas declarando la variable i como int8 o 1 byte.

no es recomendable usar printf dentro de la interrupción, porque consume mucho tiempo y hace perder la precisión de las cuentas.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Ayuda interrupcion externa con CCS
« Respuesta #2 en: 09 de Octubre de 2009, 23:07:38 »
como lo dijo don PalitroqueZ, el printf consume mucho tiempo dentro de la interrupcion, lo q podrias hacer seria definir un Flag dentro de la interrupcion y comprobarla dentro del While
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #3 en: 10 de Octubre de 2009, 00:05:15 »
Amigo Palitroquez me has hecho una buena obs la verdad no sabia, ya corregi esa parte haber como que da ahora.
Dentro de la int puse solo el encendido del un led por un seg para ver si entra a la int.
Otra consulta, cuando regresa de la int. a donde va el programa al primer while a al segundo, tengo esa duda.

 cambio esta de aqui para adelante.
/*=====================================================*/

#INT_EXT

  void IntRB0(){
       output_high (pin_b7);   // enciendo el pin RB7          
       delay_ms(1000);
       output_low (pin_b7);    // apago el pin RB7        
  }

/******************************************************************************/
/***********************   PROGRAMA PRINCIPAL    ******************************/
  void main(void)
  {    
     int i=0;
     SET_TRIS_B(0x01);              // PIN RB0 COMO ENTRADA, RB1..RB7 SALIDA
     SET_TRIS_D(0x00);              // PORTD COMO SALIDA
     enable_interrupts(int_ext);    //activar interrupcion externa
     ext_int_edge(L_TO_H);          //config. de int. por flando de bajada
     enable_interrupts(GLOBAL);     //todas las interrupciones desactivadas
 
     lcd_init();
     lcd_gotoxy(1,1);                   /* inicia en la primera linea del LCD */
     printf(lcd_putc,"Muestra el conteo ");        

 
     while(1){    
          i++;
          output_d(i);      
          lcd_gotoxy(1,2);              /* inicia en la segunda linea del LCD */                
          printf(lcd_putc,"%d",i);            
          if(i==0x00FF){
          i=0;
          }    
          while(1){                                                              /*  mientras  espera la int. esterna   */
               output_high (pin_b7);   // enciendo el pin RB7     /* enciende y apaga el led              */      
               delay_ms(100);
               output_low (pin_b7);    // apago el pin RB7          
               delay_ms(100);
         }
     }
  }

Amigo ahi te muestro los mensajes de error.

*** Error 12 "C:\Archivos de programa\PICC\drivers\lcd.c" Line 100(7,15): Undefined identifier   delay_us
*** Error 12 "C:\Archivos de programa\PICC\drivers\lcd.c" Line 112(7,15): Undefined identifier   delay_us
*** Error 12 "C:\Archivos de programa\PICC\drivers\lcd.c" Line 137(5,13): Undefined identifier   delay_ms
*** Error 12 "C:\Archivos de programa\PICC\drivers\lcd.c" Line 140(8,16): Undefined identifier   delay_ms
*** Error 12 "C:\Archivos de programa\PICC\drivers\lcd.c" Line 162(20,28): Undefined identifier   delay_ms
      5 Errors,  0 Warnings.

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #4 en: 10 de Octubre de 2009, 00:07:46 »
Gracias amigo Jhozate, dejo el cambio para que me corrigan que esta mal.

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Ayuda interrupcion externa con CCS
« Respuesta #5 en: 10 de Octubre de 2009, 00:21:08 »
En el Programa solo se debe tener un ciclo infinito. Es conveniente no ocupar mucho al micro dentro de la interrupcion..si utilizas delays dentro de la interrupcion estas ocupan al micro durante el tiempo que le pones al delay y de esta forma se deshabilitan las interrupciones por lo cual te podrias estar perdiendo algo suceso importante.. hace mucho tiempo yo tampoco tenia muy claro este cuento de los flag pero dan solucion a muchas cosas..entonces lo q puedes hacer seria definir un flag, y verificarlo en el while
Código: [Seleccionar]
#INT_EXT
 void IntRB0(){
       FLAG_INT_EXT=1;      
  }

 y en el while asi:
Código: [Seleccionar]
while(1)
{
  if(FLAG_INT_EXT==1)
    {
    FLAG_INT_EXT=0; //actualizo el flag para una nueva interrupcion
    //aqui lo que quieres hacer si ocurrio la interrupcion, por ejemplo prender el led o mostrar en el lcd la cuenta de las interruciones
    }
//aqui puedes poner al micro a hacer otra cosa
}
« Última modificación: 10 de Octubre de 2009, 00:26:03 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Ayuda interrupcion externa con CCS
« Respuesta #6 en: 10 de Octubre de 2009, 11:22:10 »
Hola.

Esos errores son a causa de que no has puesto:

Código: C
  1. #use delay(clock=12M)
El papel lo aguanta todo

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #7 en: 12 de Octubre de 2009, 12:51:25 »
Hola amigos aun no he dado con la solucion haber si me ayudan pero si he avanzado algo ya muestra en el LCD el primer mensaje (linea 1) el problema es que ahora no me genera las int por el pin RB0 tengo puesto alli un pulsador (uso el PROTEUS Portable 7.1)

/*=====================================================*/

#include <16f877.h>
#use     delay (clock=4000000)         // Fosc=4Mhz
#fuses   XT,NOWDT,NOPROTECT,PUT,NOLVP  //ordenes para el programador
#include <lcd.c>
#define  LCD_ENABLE_PIN PIN_D0
#define  LCD_RS_PIN PIN_D1
#define  LCD_RW_PIN PIN_D2
#define  LCD_TYPE 2

   int FLAG_INT_EXT=0;
/******************************************************************************/
/*********************   RUTINA DE INTERRUPCION    ****************************/
#INT_EXT

  void intrb0(){
       FLAG_INT_EXT=1;         
  }

/******************************************************************************/
/***********************   PROGRAMA PRINCIPAL    ******************************/
  void main(void)
  {   
     int i=0;
     SET_TRIS_B(0x01);              // PIN RB0 COMO ENTRADA, RB1..RB7 SALIDA
     SET_TRIS_D(0x00);              // PORTD COMO SALIDA
     enable_interrupts(int_ext);    // activar interrupcion externa
     ext_int_edge(H_TO_L);          // config. de int. por flando de bajada
     enable_interrupts(GLOBAL);     // todas las interrupciones activadas
 
     lcd_init();                        /* icinializamos en LCD */
     lcd_gotoxy(1,1);                   /* inicia en la primera linea del LCD */
     printf(lcd_putc,"Muestra conteo");         

     while(TRUE){   
 
       // ******** Procesos que se hacen si ocurre una int. ******************
          if(FLAG_INT_EXT==1){
             FLAG_INT_EXT=0;             /* actualizo el flag para una nueva interrupcion */
             i++;
             output_d(i);                /*  */     
             lcd_gotoxy(1,2);            /* el conteo se vera en la segunda linea del LCD */               
             printf(lcd_putc,"%d",i);    /* envia numero al LCD */           
             if(i==0x00FF){
                i=0;
             }
          }
      // ******************** espera la int. **************************
          while(TRUE){
               output_high (pin_b7);     // enciendo el pin RB7           
               delay_ms(100);
               output_low (pin_b7);      // apago el pin RB7         
               delay_ms(100);
         }
     }
  }


/*====================================================================*/
Otra cosa amigos cuando cambio el void (ver cambio) me genera errores no se porque sera pero creo que lo logico es que vaya asi.

#INT_EXT

  void int_ext(){
       FLAG_INT_EXT=1;         
  }

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Ayuda interrupcion externa con CCS
« Respuesta #8 en: 12 de Octubre de 2009, 13:25:30 »
Primero, las definiciones de los pines que van a utilizarse para el LCD deben estar antes de la inclusión del archivo:

Código: C
  1. #define  LCD_ENABLE_PIN PIN_D0
  2. #define  LCD_RS_PIN PIN_D1
  3. #define  LCD_RW_PIN PIN_D2
  4. #define  LCD_TYPE 2
  5.  
  6. #include <lcd.c>

Después, no vas a detectar la interrupción si entras en un bucle infinito donde no se testea su ocurrencia, colócalo así:

Código: C
  1. while(TRUE){  
  2.  
  3.        // ******** Procesos que se hacen si ocurre una int. ******************
  4.           if(FLAG_INT_EXT==1){
  5.              FLAG_INT_EXT=0;             /* actualizo el flag para una nueva interrupcion */
  6.              i++;
  7.              output_d(i);                /*  */    
  8.              lcd_gotoxy(1,2);            /* el conteo se vera en la segunda linea del LCD */              
  9.              printf(lcd_putc,"%d",i);    /* envia numero al LCD */          
  10.              if(i==0x00FF){
  11.                 i=0;
  12.              }
  13.           }
  14.       // ******************** espera la int. **************************
  15.           do{
  16.                output_high (pin_b7);     // enciendo el pin RB7          
  17.                delay_ms(100);
  18.                output_low (pin_b7);      // apago el pin RB7        
  19.                delay_ms(100);
  20.          }while(FLAG_INT_EXT==0);
  21.      }


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

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #9 en: 13 de Octubre de 2009, 01:44:36 »
Gracias amigo suky y a todos los que me ayudaron para resolver el problemita que era ordenar bien el codigo, bueno uds por experiencia tambien lo saben. Bueno el programita ya esta funcionando y en en proteus puedo ver el conteo de las int. pero ahi hay un detalle,  que cuando las int se generan a mayores frecuencias (100Hz, 1Khz) no cuenta bien segun lo que puedo ver en el proteus (hasta ahora solo lo he simulado) en mi esquematico solo estoy haciendo con pulsador en RB0, aun no le he implementado derrepente ahi la cosa es diferente pero ahi les dejo ese comentario.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Ayuda interrupcion externa con CCS
« Respuesta #10 en: 13 de Octubre de 2009, 09:19:35 »
Pasa que a mayor velocidad se está visualizando en el LCD cuando ya se actualizo unas 10 veces  :? Que necesitas implementar?
No contesto mensajes privados, las consultas en el foro

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #11 en: 13 de Octubre de 2009, 12:39:03 »
Lo que pasa es que estoy construyendo mi entrenador de pic lo estoy haciendo en ORCADv10.5 aun estoy en el esquematico. Derrepente ahi en el hardware real la cosa se vee diferente se vee todo como debe ser , quizas el proteus me esta engañando con en conteo; aqui  tengo una consulta yo recuerdo que en assembler luego de que se enviaba un caracter a LCd se ponia un retardo ¿como se hace en CCS?, el compliador lo hace todo?, si le pongo un generador de pulsos en RB0 a 1khz el lcd no me cuenta bien se como algunos pulsos que sera?
Gracias a todos por sus observaciones, por unos dias me dedicare a mi entrenador de pic haber como me sale.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Ayuda interrupcion externa con CCS
« Respuesta #12 en: 13 de Octubre de 2009, 13:06:25 »
El compilador no lo hace, eso esta realizado en la librería del LCD que estas utilizando. Y como te había comentado, a causa de la cantidad de pulsos que estas ingresando se pierden cuentas. Por ejemplo la visualización en el lcd puede llevar unos 8ms y dentro de ese tiempo pasaron 8 pulsos que no logro contar. Para realizar ese tipo de conteo deber de re diseñar el código.-

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

Desconectado Edwin_pe

  • PIC12
  • **
  • Mensajes: 82
Re: Ayuda interrupcion externa con CCS
« Respuesta #13 en: 14 de Octubre de 2009, 01:21:26 »
Gracias amigo suky, me has hecho buenas obs ahora voy a avanzar con mi entrenador de pics para probar el programa , estare atento al foro.

Desconectado jhosep_lol

  • PIC10
  • *
  • Mensajes: 4
Re:Ayuda interrupcion externa con CCS
« Respuesta #14 en: 26 de Febrero de 2016, 15:48:59 »
Edwin_pe ME GUSTARIA SABER SI ME PUDIERAS PROPORCIONAR TU CODIGO YA EN FUNCIONAMIENTO HE LEIDO TU POST Y HE VISTO QUE YA SE SOLUCIONARON TUS DUDAS OCUPO QUE CUANDO SE ACTIVE LA INT EXTERNA SE ENCIENDA LA LCD.....