nerdegutta.no
PIC16F690 - Day 3: Output Multiplexing Basics
31.07.25
Embedded
Goal: Learn basic multiplexing by lighting multiple LEDs one at a time in quick succession to give the illusion of being all on.
Hardware: 4 LEDs connected to RB4–RB7 (with resistors to GND)
Common multiplexing setup (like scanning digits or rows)
Concepts: Multiplexing = activating outputs one at a time very fast
Human eye can’t perceive the flicker if it's fast enough (~60+ Hz)
Two methods:
Manual scan using __delay_ms()
Abstraction using array/loop + __delay_us() for smoother cycling
Code 1: Simple manual LED scan with delay
#define _XTAL_FREQ 4000000
#include < xc.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
void main(void) {
// Set RB4–RB7 as outputs
TRISB &= 0x0F; // 0b00001111: upper 4 bits as output
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
while(1) {
// Light each LED one at a time
PORTB = 0b00010000; // RB4 on
__delay_ms(100);
PORTB = 0b00100000; // RB5 on
__delay_ms(100);
PORTB = 0b01000000; // RB6 on
__delay_ms(100);
PORTB = 0b10000000; // RB7 on
__delay_ms(100);
}
}
Code 2: Multiplex using loop and array (more scalable)
#define _XTAL_FREQ 4000000
#include < xc.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
const unsigned char led_mask[] = {
0b00010000, // RB4
0b00100000, // RB5
0b01000000, // RB6
0b10000000 // RB7
};
void main(void) {
TRISB &= 0x0F; // RB4–RB7 outputs
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
while(1) {
for (char i = 0; i < 4; i++) {
PORTB = led_mask[i]; // Activate one LED
__delay_us(500); // Fast refresh for persistence of vision
}
}
}