Autor Tema: interrpciones pic18f4220 en mikroc  (Leído 5155 veces)

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

Desconectado fcomeba

  • PIC10
  • *
  • Mensajes: 13
interrpciones pic18f4220 en mikroc
« en: 22 de Junio de 2009, 19:05:51 »
Tengo un problema al hacer funcionar esta interrupcion en mikroc.
La verdad no encuentro el error.

void main()
{
TRISB = 0;
do{
   PORTB.B0 = 0;
   OSCCON = 0b00001110;
   TMR0L = 391;
   T0CON = 0b11000101;
   INTCON = 0b10100000;
   if(TMR0IF){
              PORTB.B0 = 1;
              }
    }while(1);
}

Solo quiero que prenda un led despues de un segundo, que es lo mas sencillo, pero no funciona.
No se si hay algun registro que pueda interferir en la funcion.
Ya intente distintas cosas pero no funciona.
Otra cosa que me pasa es que ademas del bit 0, el bit1 y bit3 del puerto b tambien esta en 1 cuando nisiquiera estan habilitados en el programa.

Cuando alimento el circuito el led prende desde el principio.

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Re: interrpciones pic18f4220 en mikroc
« Respuesta #1 en: 23 de Junio de 2009, 07:16:23 »
Estoy empezando ahora a usar el PIC18F2550, por lo que os registros apenas los controlo. Si fuera en el 16F876 si podría ayudarte con más seguridad. Te adjunto un programa en mikroc para que puedas echarle un vistazo.

 Project name:
     LED_Blinking2 (Simple 'Hello World' project)
 * Copyright:
     (c) MikroElektronika, 2005-2008
 * Description:
     This is a simple 'Hello World' project. It turns on/off diodes connected to
     PORTB. It demonstrates the usage of the SWITCH structure to access PORTB
     pins.
 * Test configuration:
     MCU:             P18F4520
     Dev.Board:       EasyPIC5
     Oscillator:      HS, 08.0000 MHz
     Ext. Modules:    -
     SW:              mikroC v8.0
 * NOTES:
     None.
*/



void main() {
  ADCON1 = 0x0F;                         // Set AN pins to Digital I/O
  PORTB = 0;                             // initialize PORTB
  TRISB = 0;                             // configure PORTB as output

  do {
    switch (PORTB) {                     // read PORTB and switch
      case 0x00: PORTB = 0xFF; break;
      case 0xFF: PORTB = 0x00;
    }
    Delay_ms(1000);
  } while (1);
}




Usas el oscilador interno? ¿te has asegurado que el tiempo que trancurre hasta que se desborda el  TMR0IF es de 1 seg. Porque creo que esta configurado a 8 bits con prescaler, pero no creo que llegue hasta 1 segundo. Son cosas que se me ocurren,no puedo ayudarte más.


Te dejo otro ejemplo:

/*
 * Project name:
     LED_Blinking (Simple 'Hello World' project)
 * Copyright:
     (c) MikroElektronika, 2005-2008
 * Description:
     This is a simple 'Hello World' project. It turns on/off diodes connected to
     PORTC. It uses bitwise negation to toggle PORTC pins.
 * Test configuration:
     MCU:             P18F4520
     Dev.Board:       EasyPIC5
     Oscillator:      HS, 08.0000 MHz
     Ext. Modules:    -
     SW:              mikroC v8.0
 * NOTES:
     None.
*/

void main() {
  PORTC = 0;                 // Initialize PORTC
  TRISC = 0;                 // Configure PORTC as output

  while(1) {
    PORTC =  ~PORTC;         // toggle PORTC
    Delay_ms(1000);          // one second delay
    }
}


Un saludo, ya comentarás que te pasa.


Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: interrpciones pic18f4220 en mikroc
« Respuesta #2 en: 23 de Junio de 2009, 12:34:23 »
Tengo un problema al hacer funcionar esta interrupcion en mikroc.
La verdad no encuentro el error.

void main()
{
TRISB = 0;
do{
   PORTB.B0 = 0;
   OSCCON = 0b00001110;
   TMR0L = 391;
   T0CON = 0b11000101;
   INTCON = 0b10100000;
   if(TMR0IF){
              PORTB.B0 = 1;
              }
    }while(1);
}


Solo quiero que prenda un led despues de un segundo, que es lo mas sencillo, pero no funciona.
No se si hay algun registro que pueda interferir en la funcion.
Ya intente distintas cosas pero no funciona.
Otra cosa que me pasa es que ademas del bit 0, el bit1 y bit3 del puerto b tambien esta en 1 cuando nisiquiera estan habilitados en el programa.

Cuando alimento el circuito el led prende desde el principio.

Configuras todo el puerto como salida, así que cualquier pin puede quedar en 1 y otros en 0. Para asegurarte de no ser así realiza un PORTB=0;

Después, las configuraciones van fuera del do{}. Ahora que velocidad estas usando en el oscilador? Porque, dudo que logres realizar una temporización de 1 segundo, como mucho un par de ms, analiza eso nuevamente. Seguramente tendrás que usar una variable adicional que se vaya incrementando para poder contar los overflow del timer y así lograr una temporización de 1s.
No contesto mensajes privados, las consultas en el foro

Desconectado fcomeba

  • PIC10
  • *
  • Mensajes: 13
Re: interrpciones pic18f4220 en mikroc
« Respuesta #3 en: 23 de Junio de 2009, 23:03:44 »
Hola, creo que si me equivoque en algo de mis cuentas, porque el con 8 bits pensaba en contar hasta 512...
lo voy a intentar de nuevo, con respecto al reloj, esta internamente configurado para darme 31kHz y ademas contando en los ciclos internos esto  bajja a 7.550 kHz. no es asi?
a menos que en este pic, los coclos de sean exactamente de 31kHz que dudo mucho porque por los ejemplos siempre se divide entre 4. ya con el preescaler, me queda mucho menor. adelante pondre la cuenta y un nuevo programa con correcciones y comentarios, les digo que paso.

Desconectado fcomeba

  • PIC10
  • *
  • Mensajes: 13
Re: interrpciones pic18f4220 en mikroc
« Respuesta #4 en: 24 de Junio de 2009, 00:49:59 »
Aqui esta el nuevo codigo:

void main() {
TRISA       = 0b11111110; //puerto a con salida en A0
OSCCON      = 0b00000010; //Oscilador interno a 31 Khz
T0CON       = 0b11000101; //Habilitar TMR0 de 8bits
                          //Preescaler de 1:64
TMR0L       = 135;
while(1){
         PORTA.B0 = 0;
         INTCON = 0b10100000; //habilitar interrupciones
                              //overflow en TMR0
                              //TMR0IF = 0
         if(TMR0IF){
                    PORTA.B0   = ~PORTA.B0; //cambiar el valor de PORTA.B0
                    TMR0L      = 135;
                    TMR0IF_bit = 0;         //resetear bandera
                    }
         }
}

El resultado es el mismo, el porta.b0 se prende desde el principio.

El reloj interno esta a 31KHz/4 = 7750 Hz
con preescaler en 64 => 7750 Hz/64 = 121.0938 Hz.
para la interrupcion con 8 bits esto seria 256 - 121 = 135
es lo que meto a TMR0L.
Aun no encuentro el error.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: interrpciones pic18f4220 en mikroc
« Respuesta #5 en: 24 de Junio de 2009, 01:06:15 »
Veo que ahora cambiaste al Puerto A, y en ese caso tienes un error, debe ser PORTA,RA0.

Quedaría así:
Código: C
  1. void main() {
  2.     // <<< configuración de pines analógicos y comparadores>>>
  3.     TRISA       = 0b11111110; //puerto a con salida en A0
  4.     OSCCON      = 0b00000010; //Oscilador interno a 31 Khz
  5.     T0CON       = 0b11000101; //Habilitar TMR0 de 8bits
  6.                           //Preescaler de 1:64
  7.     TMR0L       = 135;
  8.     PORTA=0;
  9.     INTCON = 0b10100000; //habilitar interrupciones
  10.                               //overflow en TMR0
  11.                               //TMR0IF = 0
  12. while(1){
  13.          if(TMR0IF){
  14.                     PORTA.A0   = ~PORTA.A0; //cambiar el valor de PORTA.B0
  15.                     TMR0L= 135;
  16.                     TMR0IF_bit = 0;         //resetear bandera
  17.                     }
  18.          }
  19. }

Una cosa más, si este PIC tiene entradas analógicas debes configurar para que todos, o por lo menos los que vas a usar sean digitales, también debes desactivar los comparadores analógicos. Ambos multiplexados con el puerto A.

Acá te dejo un tutorial de MikroC en español, son ejemplos con el 16F877, pero siempre la info no esta demás.
No contesto mensajes privados, las consultas en el foro

Desconectado ivan braga

  • PIC12
  • **
  • Mensajes: 77
Re: interrpciones pic18f4220 en mikroc
« Respuesta #6 en: 24 de Junio de 2009, 22:26:20 »
Ola fcomeba,

Tenha na cabeça, algumas particularidades do MIKROC.

1º - Declare a interrupção fora de MAIN sempre.
2º - leia o datasheet para declarar corretamente os registros, pois muitos como eu, estão acustumados com CCS declarando os registros e ai a cabeça esquenta.
3º - se não for usar os comparadores e as portas AD sempre desabilite as mesmas.
4º - se não for usar os restantes das portas, declare como saida e ponha a zero para evitar surpresas.

Abaixo um exemplo de simulação no Proteus.

Código: C
  1. void interrupt() {
  2.          if(TMR0IF){
  3.                     PORTA.B0   = ~PORTA.B0; //troca o valor de PORTA.B0
  4.                     TMR0L      = 135;
  5.                     TMR0IF_bit = 0;         //reset flag
  6.                     }
  7. }
  8.  
  9. void main() {
  10.      TRISA  = 0b00000000; //defiine PORT-A como saida
  11.      PORTA  = 0b00000000; //coloca todos os pinos a zero
  12.      OSCCON      = 0b00000010; //Oscilador interno a 31 Khz
  13.      ADCON1 = 0x0F;  // Configura  pinos AD como digital
  14.      CMCON  = 0x07;  // Comparador off
  15.  
  16. T0CON.TMR0ON = 1;// Timer0 On/Off Control bit:1=Enables Timer0 / 0=Stops Timer0
  17. T0CON.T08BIT = 1;// Timer0 8-bit/16-bit Control bit: 1=8-bit timer/counter / 0=16-bit timer/counter
  18. T0CON.T0CS   = 0;// TMR0 Clock Source Select bit: 0=Internal Clock (CLKO) / 1=Transition on T0CKI pin
  19. T0CON.T0SE   = 0;// TMR0 Source Edge Select bit: 0=low/high / 1=high/low
  20. T0CON.PSA    = 0;// Prescaler Assignment bit: 0=Prescaler is assigned; 1=NOT assigned/bypassed
  21. T0CON.T0PS2  = 1;// bits 2-0  PS2:PS0: Prescaler Select bits
  22. T0CON.T0PS1  = 0;
  23. T0CON.T0PS0  = 1;
  24.  
  25. TMR0L = 135;      // preset for Timer0 LSB register(1 cycle adjusted)
  26.  
  27. INTCON.TMR0IE = 1; //TMR0 Overflow Interrupt Enable bit
  28. INTCON.GIE = 1; //Global Interrupt Enable bit
  29.  while(1);
  30. }

Espero que ajude a entender.

Abraços 

Ivan
« Última modificación: 25 de Junio de 2009, 03:34:50 por ivan braga »
"Mesmo o objeto mais inanimado tem movimento suficiente para ficar na sua frente e provocar um acidente."
"Incluso el objeto más inanimado tiene suficiente movimiento para interponerse en su camino y provocar un accidente."
"Even the most inanimate object has enough movement to stand in your way and cause an accident."

Desconectado fcomeba

  • PIC10
  • *
  • Mensajes: 13
Re: interrpciones pic18f4220 en mikroc
« Respuesta #7 en: 25 de Junio de 2009, 02:12:45 »
Hola que tal.

Gracias por sus respuestas, finalmente funcionan las interrupciones de 1 segundo.

ivan braga tenia razon.

Si declaro las interrupciones dentro del main, estas por alguna razon no funcionan. Pero su programa esta perfecto, no es muy diferente al mio en cuando a configuracion de los registros ni de los puertos, pero declara las interrpciones afuera.

Alguien me podria decir porque pasa eso?

Gracias.