Low-Level PIC Microcontroller Assembly (MPASM) Library
Cycle-accurate MPASM assembly routines for Microchip PIC16F873 and PIC16F84A: hardware UART command reception, Timer 2 register control, and dynamic PWM duty cycle modulation.

Project Overview
A low-level bare-metal firmware library engineered in pure MPASM Assembly Language for the Microchip PIC16F873 and PIC16F84A 8-bit Harvard architecture microcontrollers, developed for advanced embedded systems coursework at the University of Brighton and awarded a First Class 79% (A).
The project focuses on register-level execution, cycle-accurate timing loops, interrupt servicing, and bus orchestration without relying on compiler abstractions or runtime overhead.
Core Circuit: PIC16F873 Reference Design
The flagship hardware system pairs two PIC16F873 microcontrollers over a full-duplex hardware UART serial bus. The master controller samples real-time analogue/digital inputs and streams command packets to the slave controller, which dynamically computes PWM waveforms and drives high-power peripheral loads.
Figure 1: PIC16F873 reference circuit showing the 16 MHz crystal oscillator with 20 pF load capacitors, ICSP programming pins (PGD/PGC), and a current-limited LED output on RB0.
System Specifications & Registers
| Feature | Hardware Implementation | Target Registers |
|---|---|---|
| Microcontroller | Microchip PIC16F873 (28-pin DIP, 20 MHz Crystal) | PORTA, PORTB, PORTC |
| Serial Bus | Hardware USART (Asynchronous 9600 Baud, 8-N-1) | RCSTA, TXSTA, SPBRG, RCREG |
| PWM Output | Hardware CCP1/CCP2 in PWM Mode with Timer 2 | CCP1CON, CCPR1L, T2CON, PR2 |
| Display Drivers | Multiplexed Common-Cathode 7-Segment Hex Displays | Direct bit latching on PORTB & PORTC |
| Interrupts | RX Serial Interrupt & Timer Overflow ISR | INTCON, PIE1, PIR1 |
PWM Modulation & Timer State Machine
The pulse-width modulation subsystem relies on hardware Timer 2 (TMR2) and period register PR2 to generate clean, jitter-free square waves without loading the CPU:
Figure 2: Execution flowchart for dynamic PWM duty cycle adjustment and UART packet decoding state transitions.
Register-Level MPASM Assembly Implementation
The assembly routines leverage direct bit manipulation, bank switching (STATUS, RP0), and cycle-accurate delay loops:
Figure 3: Carbon-style syntax-highlighted MPASM assembly showing USART configuration, bank selection, and CCP1 PWM duty cycle loading.
Assembly Firmware Modules
16F873_RX_to_PWM.asm: Hardware UART packet reception triggering dynamic PWM duty-cycle modulation.16F873_RX_to_LEDs_PORTC.ASM: Direct byte latching and parallel register bit driving for visual diagnostics on Port C.PWM.asm&PWM_Simple.asm: Hardware Timer 2 (TMR2) and PR2 period registers for high-efficiency pulse modulation.SimplePWMTest.asm: Automated bench verification loop for pulse width integrity checking.
Source Code & Academic Attribution
- GitHub Repository: HarryRogers073/pic-microcontroller-code
- Author: Harry Rogers (University of Brighton)
- Target Silicon: Microchip PIC16F873, PIC16F84A
- Compilers & IDEs: Microchip MPLAB X IDE, MPASM Assembler, MPLAB XC8
- Programmer: Microchip PICkit 3 / PICkit 4 In-Circuit Debugger
- Attribution & Provenance:
- MPASM Assembly Firmware (
firmware_asm/): All register-level assembly routines (16F873_RX_to_PWM.asm,16F873_RX_to_LEDs_PORTC.ASM,PWM.asm,SimplePWMTest.asm) were authored and verified by Harry Rogers. - Embedded C Drivers (
firmware_c/): Differential drive, ultrasonic ranging, and sensor routines developed for the mobile sensor buggy project by Harry Rogers & Albie Gullis. The I2C character LCD driver (lcd.c) was adapted from a tutorial by Khaled Magdy (DeepBlueEmbedded). - Microchip register include files (
p16f873.inc,<xc.h>) are copyright Microchip Technology Inc.
- MPASM Assembly Firmware (