LED on RB0 and RC0 with a Push Button in PICSimLab Spare Parts
“LED on RB0, LED on RC0, push button to control them” is one of the most searched PICSimLab exercises — and a perfect spare-parts workout. This tutorial wires an LED to RB0, a second LED to RC0 and a push button that drives them, using PICSimLab’s LEDs and Push Buttons spare parts with a PIC16F877A. If you can do this, you understand digital outputs, digital inputs and part wiring — the three skills every other tutorial here builds on.
What you need
- PICSimLab 0.9.3 — see the download page.
- MPLAB X IDE and the XC8 compiler.
- Board: McLab2 or PICGenios, microcontroller PIC16F877A (the Breadboard also works for this exercise).
- Two spare parts: LEDs (Outputs) and Push Buttons (Inputs).
Wiring: LED RB0, LED RC0, push button on RD0
- LEDs part, LED 1 → RB0
- LEDs part, LED 2 → RC0
- Push Buttons part, button 1 → RD0 (the input the code polls)
Add both parts from Modules → Spare parts, then right-click each part, open Properties and set these connections. The behaviour in the example: while the button is held, the RB0 LED follows the button and the RC0 LED lights too; a quick press-and-release toggles the RC0 LED state so you can also test edge detection. Adjust the button’s active level in Properties if your part defaults differ — the code comments mark where to invert the test.
Steps
1. Generate the project
Select the board and PIC16F877A, then generate the MPLAB X project with the Code Project Wizard.
2. Configure directions
RB0 and RC0 are outputs (TRISBbits.TRISB0 = 0, TRISCbits.TRISC0 = 0); RD0 is an input (TRISDbits.TRISD0 = 1). Ninety percent of “the LED does nothing” reports are a direction bit or a Properties connection — check those before suspecting the simulator.
3. Build, load and click
Build in MPLAB X, load the .hex and run. Click and hold the button in the spare-parts window: RB0 follows the button live. Release and click again to see RC0 change state per press.
Example code (XC8)
// Example: LED on RB0 + LED on RC0 + push button - PIC16F877A, XC8
// Button on RD0 (example: pressed = logic 1; invert the tests if
// your Push Buttons part is configured active-low)
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
#include <xc.h>
#define _XTAL_FREQ 20000000 // Example: match the board clock
#define BUTTON PORTDbits.RD0
void main(void) {
TRISBbits.TRISB0 = 0; // RB0 output -> LED 1
TRISCbits.TRISC0 = 0; // RC0 output -> LED 2
TRISDbits.TRISD0 = 1; // RD0 input -> push button
PORTBbits.RB0 = 0;
PORTCbits.RC0 = 0;
unsigned char rc0_state = 0;
unsigned char last_button = 0;
while (1) {
unsigned char pressed = BUTTON;
PORTBbits.RB0 = pressed; // RB0 LED follows the button
if (pressed && !last_button) { // rising edge: one toggle
rc0_state = !rc0_state;
PORTCbits.RC0 = rc0_state; // RC0 LED toggles per press
__delay_ms(30); // debounce
}
last_button = pressed;
}
}
Try next
- Matrix keypad — from one button to sixteen keys on eight pins.
- EEPROM counter — count the button presses and keep the count across resets.
- Timers and interrupts — react to the button in an interrupt instead of polling.
Troubleshooting
The RB0 LED is on when it should be off (or the reverse). The button part’s active level does not match the code’s assumption. Either flip the connection behaviour in the part’s Properties or invert the pressed test (pressed = !BUTTON) and rebuild.
RC0 flickers instead of toggling once per press. Contact bounce plus a held button: the edge-detect and debounce in the example handle the normal case — if it still flickers, increase the debounce delay and make sure you are not retriggering by holding the mouse button down.
