/*
* File: main.c
* Author: Nolan
* Chip: PIC16F1829
* Created on April 14, 2016
* - Pressing a pull-down button on RB5 triggers an interrupt
* - TMR0 is setup in the interrupt service routine (ISR) to delay re-enabling the RB5 interrupt
* - When TMR0 overflows 0xFF, the TMR0IF is triggered
*/
#include <xc.h>
// Insert CONFIG code here
#define LED RA5
#define LED_TRIS TRISA5
#define BUTTON_RELEASED RB5
void led_on(){
LED_TRIS = 0;
LED = 1;
}
void led_off(){
LED_TRIS = 0;
LED = 0;
}
void toggle_led(){
if(LED){
led_off();
}
else {
led_on();
}
}
// interrupt service routine
// executed when an interrupt occurs
void interrupt ISR(void){
if(IOCIE && IOCIF && IOCBF5){
toggle_led();
while(!BUTTON_RELEASED);
TMR0 = 0x00;
OPTION_REG = 0b00000011;
TMR0IF = 0;
TMR0IE = 1;
IOCBF5 = 0;
IOCIF = 0;
IOCIE = 0;
}
if(TMR0IE && TMR0IF){
IOCBF5 = 0;
IOCIF = 0;
IOCIE = 1;
TMR0IF = 0;
TMR0IE = 0;
}
PEIE = 1;
GIE = 1;
return;
}
void reset_interrupts(void){
// disable all interrupts
GIE = 0;
PEIE = 0;
// clear all interrupt flags
INTCON = 0;
PIR1 = 0;
PIR2 = 0;
PIR3 = 0;
PIR4 = 0;
// disable all interrupts
PIE1 = 0;
PIE2 = 0;
PIE3 = 0;
PIE4 = 0;
// all interrupts are cleared and disabled
// setup needed interrupts in other functions
return;
}
void configure_tmr0(void){
TMR0 = 0x00;
TMR0IF = 0;
TMR0IE = 1;
PEIE = 1;
GIE = 1;
OPTION_REG = 0b00000111; //without Prescaler, LED will blink too fast
return;
}
void configure_button(){
// clear all IOC flags and disable all IOC
IOCAF = 0;
IOCAN = 0;
IOCAP = 0;
IOCBF = 0;
IOCBN = 0;
IOCBP = 0;
// set up RB5 IOC
ANSB5 = 0;
TRISB5 = 1;
WPUB5 = 1;
INLVLB5 = 1;
IOCBP5 = 0;
IOCBN5 = 1;
IOCBF5 = 0;
IOCIF = 0;
IOCIE = 1;
PEIE = 1;
GIE = 1;
return;
}
void main(void) {
reset_interrupts();
configure_tmr0();
configure_button();
while(1);
return;
}