nerdegutta.no
PIC16F690 - Day 2: Input Handling (Button Input)
29.07.25
Embedded
#define _XTAL_FREQ 4000000
#include < xc.h > // Remove extra spaces
// CONFIG
#pragma config FOSC = INTRCIO // Internal oscillator
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
void main(void) {
TRISA3 = 1; // RA3 as input
TRISB0 = 0; // RB0 as output
ANSEL = 0; // Disable analog on PORTA
ANSELH = 0;
PORTB = 0;
while(1) {
if (RA3 == 1) { // Button pressed (active high)
RB0 = 1; // Turn on LED
} else {
RB0 = 0; // Turn off LED
}
__delay_ms(20); // Simple debounce
}
}
Code 2: Interrupt-on-Change (IOC) on RB4 (simulate same logic)
#define _XTAL_FREQ 4000000
#include < xc.h > // Remove extra spaces
#include < stdint.h > // Remove extra spaces
// CONFIG
#pragma config FOSC = INTRCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
volatile uint8_t led_state = 0;
void __interrupt() isr(void) {
if (RBIF) {
// Simple debounce wait
__delay_ms(20);
if (RB4 == 1) {
led_state ^= 1; // Toggle state
RB0 = led_state; // Apply to LED
}
// Clear interrupt flag
RBIF = 0;
}
}
void main(void) {
TRISB4 = 1; // RB4 input (button)
TRISB0 = 0; // RB0 output (LED)
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
// Enable IOC on PORTB
IOCB4 = 1; // Enable interrupt on change for RB4
// Enable interrupts
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.RBIE = 1;
INTCONbits.RBIF = 0;
while(1) {
// Main loop does nothing; ISR handles the toggle
}
}