Autor Tema: xc8_interrupciones_TMR0  (Leído 5062 veces)

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

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
xc8_interrupciones_TMR0
« en: 11 de Febrero de 2013, 02:38:56 »
Decidi mudarme al compilador XC8 de microchip. Hasta ahora con buenos resultados, se me ocurre que puede ser de interes compartir las primeras pruebas de codigo (configuracion del pic, interrupciones, etc)

Este es un codigo bien simple, el objetivo del mismo es familiarizarce con XC8:

  • Aprender a configurar los bits de configuracion mediante la directiva #pragma config
  • Conocer como se manejan las interrupciones
  • Configurar la interrupcion por desborde de TMR0

Recomiendo leer MPLAB® XC8 C Compiler User’s Guide y consultarlo frente a cualquier duda http://ww1.microchip.com/downloads/en/DeviceDoc/52053B.pdf

Una ventaja de xc8 es la libreria que introduce el archivo de cabecera xc.h (#include<xc.h>) ya que permite dirigirce a los registros del pic por el nombre que tienen en la hoja de datos, sin tener que definir etiquetas con las direcciones de memoria de los registros usados. Es decir si no se conoce que funcion cumple un registro visto en el programa, simplemente buscar en la hoja de datos del pic!

Tambien recomiendo frente a cualquier duda de C consultar textos sobre ANSI C (estandar de C) con el que el compilador es compatible.

Este codigo utiliza la interrupcion de timer0 para contar un segundo exacto de promedio sin error acumulativo, el algoritmo es gentileza de http://www.romanblack.com/one_sec.htm.

Bueno cualquier cosa que no se entienda se pregunta y cualquier error que se detecte se agradece la correccion, como cualquier otra sugerencia que venga al caso.


Código: C
  1. /*----------------------------------------------------------------------------
  2.  * File:   led_timer0.c
  3.  * Author: Lagruya
  4.  * Created on 4 de febrero de 2013, 20:38
  5.  *
  6.  * El objetivo de este programa es el de familiarizarce con el compilador XC8
  7.  * y ANSI C
  8.  *
  9.  * Este programa enciende y apaga un led cada 5 segundos utilizando la
  10.  * interrupcion por desborde de TMR0, con un algoritmo de cero error
  11.  * acumulativo (cortecia de http://www.romanblack.com/one_sec.htm)
  12.  *
  13.  *
  14.  *---------------------------------------------------------------------------*/
  15.  
  16. #include <xc.h>
  17.  
  18. /* configuracion de bits de configuracion para el pic 16f88 (fuses) */
  19. #pragma config BOREN = OFF, CPD = OFF, CCPMX = RB0, DEBUG = OFF, WRT = OFF, \
  20.                FOSC = INTOSCIO, MCLRE = OFF, WDTE = OFF, CP = OFF, LVP = OFF, \
  21.                PWRTE = OFF, IESO = ON, FCMEN = ON
  22.  
  23.  
  24. /* definicion para el correcto funcionamiento de la funcion delayms y us */
  25. #define _XTAL_FREQ              8000000UL
  26. #define LED             RA0  // etiqueta para el pin usado para conectar un led
  27.  
  28. /*-------------------------VARIABLES GLOBALES--------------------------------*/
  29.  
  30. unsigned long bres;    // variable de 32bits
  31. unsigned int segundos; //variable para almacenar segundos
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. /* Funcion para la ISR (Rutina de Servicio de Interrupcion) El codigo
  36.  * generado por el compilador para esta funcion sera colocado en el vector
  37.  * de interrupcion del pic, es por eso que todas las interrupciones deben ser
  38.  * manejadas por esta funcion */
  39. void interrupt interrupciones (void) {
  40.  
  41.     if (TMR0IE && TMR0IF){      /* se verifica si la interrupcion es por TMR0
  42.                                  * sin prescaler TMR0 se desborda cada 256
  43.                                  * instrucciones con una Fosc = 8MHz cada
  44.                                  * desborde ocurre cada 128microsegundos */
  45.         bres += 256;            // cantidad de instrucciones por interrupcion
  46.        
  47.         if (bres >= 2000000){   /* 2000000 de instrucciones implican 1 segundo
  48.                                  * si Fosc = 8MHz */
  49.             bres -= 2000000;    /* se reinicia bres reteniendo el error, cada
  50.                                  * vez la diferencia sera menor hasta que de
  51.                                  * cero. */
  52.             segundos++;
  53.             if (segundos == 5){
  54.  
  55.                 segundos = 0;
  56.                 LED = !LED;
  57.             }
  58.         }
  59.         TMR0IF = 0;             /* el flag de interrupcion de TMR0 se pone a
  60.                                  * cero por soft */
  61.     }
  62. /* el resto de las interrupciones utilizadas se deben analizar a coninuacion*/
  63. }
  64.  
  65. /*------------------------DECLARACION DE FUNCIONES---------------------------*/
  66.  
  67. void conf_oscilador (void); // Configuracion del oscilador
  68. void conf_puertos (void);   // Configuracion de puertos I/O
  69. void conf_timer0 (void);    // Configuracion registros TIMER0
  70.  
  71. /*---------------------CUERPO PRINCIPAL DEL PROGRAMA-------------------------*/
  72.  
  73. int main(void) {
  74.  
  75.     conf_oscilador ();
  76.     conf_puertos ();
  77.     conf_timer0 ();
  78.  
  79.     LED = 0;       // se inicia con led apagado
  80.    
  81.     while (1)
  82.         continue;  // bucle infinito, se queda esperando por interrupciones
  83.  
  84. }
  85.  
  86. /*------------------------------FUNCIONES------------------------------------*/
  87.  
  88. /* Funcion para la configuracion del oscilador del pic16f88 */
  89. void conf_oscilador (void) {
  90.    
  91.     OSCCONbits.IRCF2 = 1;
  92.     OSCCONbits.IRCF1 = 1;
  93.     OSCCONbits.IRCF0 = 1; // IRCF <2:0> = 111 setea Fosc 8MHz
  94.    
  95.     OSCCONbits.SCS1 = 0;
  96.     OSCCONbits.SCS0 = 0; /* SCS <1:0> = 00 Modo del oscilador definido por
  97.                           * FOSC <2:0> en #pragma config FOSC = INTOSCIO */
  98. }
  99. /* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
  100. void conf_puertos (void) {
  101.    
  102.     ANSEL = 0;          // registro ANSEL = 0 no se usan puertos analogicos
  103.     TRISA = 0;          /* todo el puerto A como salidas, salvo RA5 que es
  104.                          * para el pic16F88 solo de entrada, el bit5 de TRISA
  105.                          * no tiene efecto y RA5 siempre se leera como 1 */
  106.     TRISB = 0;          // todo el puerto B como salidas
  107. }
  108.  
  109. /* Funcion para la configuracion del modulo Timer0 como temporizador */
  110. void conf_timer0 (void) {
  111.  
  112.     OPTION_REG = 0b10001000;    // configuracion para pic16F88 ver datasheet
  113.     INTCON = 0b10100000;        // configuracion interrupciones ver datasheet
  114. }

Saludos.

Desconectado seba85

  • PIC10
  • *
  • Mensajes: 28
Re: xc8_interrupciones_TMR0
« Respuesta #1 en: 08 de Octubre de 2013, 18:33:43 »
Hola! el ejemplo me vino como anillo al dedo! jaja
estoy haciendo algo parecido con interrupciones del Timer23 en XC16 pero es lo mismo
pero tengo unas dudas si me podes aclarar:

1-La funcion "void interrupt interrupciones (void)" se ejecuta cuando hay una interrupción en general, cualquiera sea? nosotros tenemos que de ahí en más averiguar cual de todas las causas posibles es?
2- También se encarga de guardar el estado, registros de programa y contador de programa?
3- y si la interrupción sucede durante la ejecución de otra rutina, salta directamente a esta función?


Saludos!

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: xc8_interrupciones_TMR0
« Respuesta #2 en: 08 de Octubre de 2013, 21:24:03 »
Hola! el ejemplo me vino como anillo al dedo! jaja
estoy haciendo algo parecido con interrupciones del Timer23 en XC16 pero es lo mismo
pero tengo unas dudas si me podes aclarar:

1-La funcion "void interrupt interrupciones (void)" se ejecuta cuando hay una interrupción en general, cualquiera sea? nosotros tenemos que de ahí en más averiguar cual de todas las causas posibles es?
2- También se encarga de guardar el estado, registros de programa y contador de programa?
3- y si la interrupción sucede durante la ejecución de otra rutina, salta directamente a esta función?


Saludos!

Hola

1.- Si, nosotros determinamos cual es la interrupción activa al preguntar por los FLAGs(banderas) e Interrupciones activas.
2.- Si , lo guarda en automático.
3.- Si, si esta en una rutina o cualquier linea salta al vector de interrupcion.Si estas en una interrupcion de bajo nivel y salta una de alto nivel , pasas a atender la de alto nivel y luego regresa a lo anterior.

Saludos!

Desconectado javier687

  • PIC10
  • *
  • Mensajes: 5
Re: xc8_interrupciones_TMR0
« Respuesta #3 en: 10 de Octubre de 2013, 09:13:09 »
Podran ayudarme a visualizar donde esta el error, al ejecutarlo en proteus no entra en la interrupcion por ello tampoco enciende el led que esta en A0.

#include <12f675.h>
#use delay(clock=4m)
#fuses nowdt, nomclr, put
#use fast_io(a)

#int_ext
void ext_isr(void)
{
output_high(pin_a0);
delay_ms(500);
}

void main (void)
{
set_tris_a(0b000100);
enable_interrupts(pin_a2);
ext_int_edge(0x40);
enable_interrupts(global);
INTERRUPT_ACTIVE(pin_a2);
output_low(pin_a0);
while(1);
}

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: xc8_interrupciones_TMR0
« Respuesta #4 en: 10 de Octubre de 2013, 10:03:41 »
Que compilador y version estas usando??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.


 

anything