/*----------------------------------------------------------------------------
* File: led_timer0.c
* Author: Lagruya
* Created on 4 de febrero de 2013, 20:38
*
* El objetivo de este programa es el de familiarizarce con el compilador XC8
* y ANSI C
*
* Este programa enciende y apaga un led cada 5 segundos utilizando la
* interrupcion por desborde de TMR0, con un algoritmo de cero error
* acumulativo (cortecia de http://www.romanblack.com/one_sec.htm)
*
*
*---------------------------------------------------------------------------*/
#include <xc.h>
/* configuracion de bits de configuracion para el pic 16f88 (fuses) */
#pragma config BOREN = OFF, CPD = OFF, CCPMX = RB0, DEBUG = OFF, WRT = OFF, \
FOSC = INTOSCIO, MCLRE = OFF, WDTE = OFF, CP = OFF, LVP = OFF, \
PWRTE = OFF, IESO = ON, FCMEN = ON
/* definicion para el correcto funcionamiento de la funcion delayms y us */
#define _XTAL_FREQ 8000000UL
#define LED RA0 // etiqueta para el pin usado para conectar un led
/*-------------------------VARIABLES GLOBALES--------------------------------*/
unsigned long bres; // variable de 32bits
unsigned int segundos; //variable para almacenar segundos
/*---------------------------------------------------------------------------*/
/* Funcion para la ISR (Rutina de Servicio de Interrupcion) El codigo
* generado por el compilador para esta funcion sera colocado en el vector
* de interrupcion del pic, es por eso que todas las interrupciones deben ser
* manejadas por esta funcion */
void interrupt interrupciones (void) {
if (TMR0IE && TMR0IF){ /* se verifica si la interrupcion es por TMR0
* sin prescaler TMR0 se desborda cada 256
* instrucciones con una Fosc = 8MHz cada
* desborde ocurre cada 128microsegundos */
bres += 256; // cantidad de instrucciones por interrupcion
if (bres >= 2000000){ /* 2000000 de instrucciones implican 1 segundo
* si Fosc = 8MHz */
bres -= 2000000; /* se reinicia bres reteniendo el error, cada
* vez la diferencia sera menor hasta que de
* cero. */
segundos++;
if (segundos == 5){
segundos = 0;
LED = !LED;
}
}
TMR0IF = 0; /* el flag de interrupcion de TMR0 se pone a
* cero por soft */
}
/* el resto de las interrupciones utilizadas se deben analizar a coninuacion*/
}
/*------------------------DECLARACION DE FUNCIONES---------------------------*/
void conf_oscilador (void); // Configuracion del oscilador
void conf_puertos (void); // Configuracion de puertos I/O
void conf_timer0 (void); // Configuracion registros TIMER0
/*---------------------CUERPO PRINCIPAL DEL PROGRAMA-------------------------*/
int main(void) {
conf_oscilador ();
conf_puertos ();
conf_timer0 ();
LED = 0; // se inicia con led apagado
while (1)
continue; // bucle infinito, se queda esperando por interrupciones
}
/*------------------------------FUNCIONES------------------------------------*/
/* Funcion para la configuracion del oscilador del pic16f88 */
void conf_oscilador (void) {
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1; // IRCF <2:0> = 111 setea Fosc 8MHz
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0; /* SCS <1:0> = 00 Modo del oscilador definido por
* FOSC <2:0> en #pragma config FOSC = INTOSCIO */
}
/* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
void conf_puertos (void) {
ANSEL = 0; // registro ANSEL = 0 no se usan puertos analogicos
TRISA = 0; /* todo el puerto A como salidas, salvo RA5 que es
* para el pic16F88 solo de entrada, el bit5 de TRISA
* no tiene efecto y RA5 siempre se leera como 1 */
TRISB = 0; // todo el puerto B como salidas
}
/* Funcion para la configuracion del modulo Timer0 como temporizador */
void conf_timer0 (void) {
OPTION_REG = 0b10001000; // configuracion para pic16F88 ver datasheet
INTCON = 0b10100000; // configuracion interrupciones ver datasheet
}