TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Edwin_pe en 09 de Octubre de 2009, 22:23:07

Título: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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);
     }                             
  }
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: PalitroqueZ 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.

Título: Re: Ayuda interrupcion externa con CCS
Publicado por: jhozate 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
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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.
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe en 10 de Octubre de 2009, 00:07:46
Gracias amigo Jhozate, dejo el cambio para que me corrigan que esta mal.
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: jhozate 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
}
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: MLO__ 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)
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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;         
  }
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Suky 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!
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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.
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Suky 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?
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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.
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Suky 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!
Título: Re: Ayuda interrupcion externa con CCS
Publicado por: Edwin_pe 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.
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: jhosep_lol 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.....
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: jhosep_lol en 26 de Febrero de 2016, 17:11:20
hola me podrias ayudar con el armado en proteus?? saludos
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: KILLERJC en 26 de Febrero de 2016, 17:24:53
hola me podrias ayudar con el armado en proteus?? saludos

Este es un tema del año 2009 y el usuario Edwin_pe no se conecta desde el 2012. Lo cual no creo que vayas a obtener repuesta de el.
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: jhosep_lol en 26 de Febrero de 2016, 17:42:31
HOLA AYUDA USE TU CÓDIGO PERO NO ME MUESTRA EL CONTEO EN LA LCD ME PODRIAS AYUDAR SALUDOS ....
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: KILLERJC en 26 de Febrero de 2016, 17:47:36
Si vas a copiar un codigo no te va a funcionar nunca. Trata de empezar con codigos simples e ir aprendiendo.
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: jhosep_lol en 26 de Febrero de 2016, 17:59:25
HOLA GRACIAS POR RESPONDER LA DUDA ,....solo queria saber como se usa la interrupción externa (usando una lcd) soy nuevo en esto..
tambien quisiera saber si me podrias ayudar con comunicación I2C,SPI,USART,UART. lo que he encontrado en internet es muy complejo ya una aplicacion al protocolo necesito algo mas de principiantes,,,,saludos
Título: Re:Ayuda interrupcion externa con CCS
Publicado por: KILLERJC en 26 de Febrero de 2016, 18:23:31
Las interrupciones no tienen nada que ver con el LCD. Vos para hacer funcionar una interrupcion, tenes que activar la interrupcion y activar las interrupciones globales.
Luego definir una funcion que es la de interrupcion.

Lamentablemente en el foro no existen temas creados con ejemplos simples usando CCS, lo unico que hay es XC8. ( Lo cual si usas los codigos no te van a funcionar )

El problema que tenes es que me parece que no conoces el lenguaje C, ni tampoco el microcontrolador.
Deberias buscar por internet o el foro pequeños ejemplos basicos. Ademas leer el datasheet del microcontrolador que ahi explica bien como funciona el PIC y sus modulos.

No te puedo ser de mas ayuda.