Implemented Projects
This series of projects represents a journey from direct hardware control in assembly to the implementation of abstract drivers in C, establishing critical understanding of operation costs and hardware limitations.
1. Blink in Assembly – Direct GPIO Control
Basic LED control implementation through direct register manipulation in assembly, without high-level abstractions.
Source Code:
https://github.com/SimonAulet/portfolio/tree/main/PIC/blink.X
Expand code: Blink in Assembly (blink.s)
PROCESSOR 16F18875
LIST
#include
////////////////////////////////////////////////////////////////
; PIC16F18875 Configuration Bit Settings
; Assembly source line config statements
; CONFIG1
; CONFIG FEXTOSC = ECH ; External Oscillator mode selection bits (EC above 8MHz; PFM set to high power)
; CONFIG RSTOSC = LFINT ; Power-up default value for COSC bits (LFINTOSC)
; CONFIG CLKOUTEN = OFF ; Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
; CONFIG CSWEN = ON ; Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
; CONFIG FCMEN = ON ; Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)
CONFIG FEXTOSC = OFF ; Disable external oscillator
CONFIG RSTOSC = HFINT1 ; Use internal high-frequency oscillator (1 MHz)
CONFIG CLKOUTEN = OFF ; Disable clock output
CONFIG CSWEN = ON ; Allow frequency change at runtime
CONFIG FCMEN = OFF ; Disable Fail-Safe Clock Monitor (no longer needed)
; CONFIG2
CONFIG MCLRE = ON ; Master Clear Enable bit (MCLR pin is Master Clear function)
CONFIG PWRTE = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG LPBOREN = OFF ; Low-Power BOR enable bit (ULPBOR disabled)
CONFIG BOREN = ON ; Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)
CONFIG BORV = LO ; Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
CONFIG ZCD = OFF ; Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
CONFIG PPS1WAY = ON ; Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
CONFIG STVREN = ON ; Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
; CONFIG3
CONFIG WDTCPS = WDTCPS_31 ; WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
CONFIG WDTE = ON ; WDT operating mode (WDT enabled regardless of sleep; SWDTEN ignored)
CONFIG WDTCWS = WDTCWS_7 ; WDT Window Select bits (window always open (100%); software control; keyed access not required)
CONFIG WDTCCS = SC ; WDT input clock selector (Software Control)
; CONFIG4
CONFIG WRT = OFF ; UserNVM self-write protection bits (Write protection off)
CONFIG SCANE = available ; Scanner Enable bit (Scanner module is available for use)
CONFIG LVP = ON ; Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
; CONFIG5
CONFIG CP = OFF ; UserNVM Program memory code protection bit (Program Memory code protection disabled)
CONFIG CPD = OFF ; DataNVM code protection bit (Data EEPROM code protection disabled)
///////////////////////////////////////////////////////////////
PSECT resetVec,class=CODE,delta=2
resetVec:
PAGESEL main
goto main
PSECT code
main:
CLRF TRISA ; Configure PORTA as output
START:
MOVLW 00000000B ; Turn off LED on RA3
MOVWF PORTA
CALL Retardo ; Call delay
MOVLW 11111111B ; Turn on LED on RA3
MOVWF PORTA
CALL Retardo ; Call delay
GOTO START ; Repeat cycle
;-------------------
; Delay Subroutine
;-------------------
Retardo:
MOVLW 0xFF
MOVWF 0x20
MOVLW 0xFF
MOVWF 0x21
MOVLW 0x16
MOVWF 0x22
Loop1: ;decrement 20
DECFSZ 0x20, F
GOTO Loop1
Loop2: ;decrement 21
MOVLW 0xFF
MOVWF 0x20 ;reset reg 1
DECFSZ 0x21, F
GOTO Loop1
Loop3: ;decrement 22
MOVLW 0xFF
MOVWF 0x20 ;reset reg 1
MOVLW 0xFF
MOVWF 0x21 ;reset reg 2
DECFSZ 0x22, F
GOTO Loop1
RETURN
END main
Technical Features
- Timing: Through triple loop in assembly
- Configuration: Manual port setup without abstractions
- Oscillator: Internal HFINT1 at 1 MHz
- GPIO: Direct port A control
Educational Value: Understanding instruction cycle cost and precise timing.
2. Potentiometer Reading in Assembly
Analog acquisition system using 8-bit ADC with LED bar visualization.
Source Code:
https://github.com/SimonAulet/portfolio/tree/main/PIC/potenciometro.X
Expand code: ADC Reading in Assembly (potenciometro.s)
PROCESSOR 16F18875
LIST
#include
////////////////////////////////////////////////////////////////
; PIC16F18875 Configuration Bit Settings
; Assembly source line config statements
; CONFIG1
CONFIG FEXTOSC = OFF ; External Oscillator mode selection bits (EC above 8MHz; PFM set to high power)
CONFIG RSTOSC = HFINT1 ; Power-up default value for COSC bits (LFINTOSC)
CONFIG CLKOUTEN = OFF ; Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
CONFIG CSWEN = ON ; Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)
; CONFIG2
CONFIG MCLRE = ON ; Master Clear Enable bit (MCLR pin is Master Clear function)
CONFIG PWRTE = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG LPBOREN = OFF ; Low-Power BOR enable bit (ULPBOR disabled)
CONFIG BOREN = ON ; Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)
CONFIG BORV = LO ; Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
CONFIG ZCD = OFF ; Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
CONFIG PPS1WAY = ON ; Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
CONFIG STVREN = ON ; Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
; CONFIG3
CONFIG WDTCPS = WDTCPS_31 ; WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
CONFIG WDTE = OFF ; WDT operating mode (WDT enabled regardless of sleep; SWDTEN ignored)
CONFIG WDTCWS = WDTCWS_7 ; WDT Window Select bits (window always open (100%); software control; keyed access not required)
CONFIG WDTCCS = SC ; WDT input clock selector (Software Control)
; CONFIG4
CONFIG WRT = OFF ; UserNVM self-write protection bits (Write protection off)
CONFIG SCANE = available ; Scanner Enable bit (Scanner module is available for use)
CONFIG LVP = ON ; Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
; CONFIG5
CONFIG CP = OFF ; UserNVM Program memory code protection bit (Program Memory code protection disabled)
CONFIG CPD = OFF ; DataNVM code protection bit (Data EEPROM code protection disabled)
; CONFIG ADC
BSF ANSELA, 0 ; Configure RA0 as analog
BSF TRISA, 0 ; Configure RA0 as input
MOVLW 0x01 ; Select channel AN0 (RA0)
MOVWF ADPCH
MOVLW 0b00010101 ; ADC ON, Clock FRC, Left justified
MOVWF ADCON0
MOVLW 0b10000000 ; VDD and VSS reference, Left justified
MOVWF ADCON1
; CONFIG LEDS
MOVLW 0b00001111 ; RA4 to 7 as outputs, rest as they were
ANDWF TRISA, F
// config statements should precede project file includes.
///////////////////////////////////////////////////////////////
PSECT resetVec,class=CODE,delta=2
resetVec:
PAGESEL main ;Jump to Main
goto main
PSECT code
main:
START:
GOTO adc
MOVLW 0b01010101
MOVWF 0x20
;alternate 0x20 between ones and zeros
BTFSC 0x20, 7
MOVLW 0b00000000 ;00 L2
BTFSS 0x20, 7
MOVLW 0b11111111 ;10 L4
MOVWF 0x20
;check potentiometer result
BTFSC 0x20, 7 ;first bit
GOTO msb1
GOTO msb0
msb1:
BTFSC 0x20, 6 ;second bit
GOTO nivel4
GOTO nivel3
msb0:
BTFSC 0x20, 6 ;second bit
GOTO nivel2
GOTO nivel1
adc:
BSF ADCON0, 0 ; Start conversion
BTFSC ADCON0, 1 ; Wait for completion (while GO/DONE=1)
GOTO $-1
MOVF ADRESH, W ; I will only be interested in the 2 MSBs
MOVWF 0x20
RETURN
;LED bits are 4, 5, 6 and 7 of port A
nivel0: ;0000
MOVF LATA, W
ANDLW 0b00001111
MOVWF LATA
GOTO START
nivel1: ;0001
MOVF LATA, 0
ANDLW 0b00011111
IORLW 0b00010000
MOVWF LATA
GOTO START
nivel2: ;0011
MOVF LATA, 0
ANDLW 0b00111111
IORLW 0b00110000
MOVWF LATA
GOTO START
nivel3: ;0111
MOVF LATA, 0
ANDLW 0b01111111
IORLW 0b01110000
MOVWF LATA
GOTO START
nivel4: ;1111
MOVF LATA, 0
IORLW 0b11110000
MOVWF LATA
GOTO START
END main
Technical Features
- ADC: 8-bit on channel AN0 (RA0)
- Processing: The 2 most significant bits determine LED bar level
- Visualization: Visual representation on RA4–RA7
- Resolution: 4 discrete levels (2 bits)
Educational Value: Understanding the A/D conversion process and value mapping.
3. LCD Integration in C
Transition to structured programming in C using libraries and abstractions through Microchip Code Configurator.
Source Code:
https://github.com/SimonAulet/portfolio/tree/main/PIC/LCD_CON_I2C.X
Expand code: LCD Integration in C (main.c)
#include "mcc_generated_files/mcc.h"
#include "seri_lcd.h"
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
__delay_ms(500);
lcd_start();
int valor;
while (1)
{
char buffer[17];
__delay_ms(50);
lcd_delete();
valor = ADCC_GetSingleConversion(POT);
sprintf(buffer, "%d", valor);
lcd_writemessage(1, 1, buffer);
}
}
Technical Features
- Abstraction: Through
Microchip Code Configurator - Display: 16x2 character LCD with I2C interface
- Architecture: Maintenance of functional core with abstract drivers
- Libraries: Use of standardized APIs for peripherals
Educational Value: Transition from low-level to structured programming with abstractions.
Technical Specifications
Summary of components and configurations used in the projects.
| Component | Specification | Project | Language |
|---|---|---|---|
| Microcontroller | PIC16F18875 | All | ASM/C |
| Oscillator | HFINT1 @ 1MHz | Blink | Assembly |
| ADC | 8-bit, Channel AN0 | Potentiometer | Assembly |
| Display | 16x2 Character LCD | LCD Integration | C |
| Tool | Microchip MCC | LCD Integration | C |
| GPIO | Port A (RA0-RA7) | All | ASM/C |
| Communication | I2C for LCD | LCD Integration | C |
Value of Fundamentals
These projects establish critical understanding of operation costs and hardware limitations. The experience of writing delays in assembly and manually configuring registers illuminates the internal workings of microcontrollers.
Educational journey: The journey from bit-by-bit control in assembly to abstract drivers in C aids in complete understanding of the embedded software stack.
The progressive transition between abstraction levels enables:
- Cost understanding: Evaluation of each operation's impact on clock cycles
- Conscious optimization: Informed decision-making about resource usage
- Effective debugging: Ability to diagnose problems at multiple levels
- Tool selection: Criteria for choosing between direct control or abstractions