Skip to content

About

PIC16F873 Voltmeter with LCD Display [Archive]

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

PIC16F873 Voltmeter with LCD Display

Project Overview

This is an embedded systems project written in PIC assembly language for the PIC16F873 microcontroller. The current implementation functions as a digital voltmeter with an LCD display, with the ultimate goal of evolving into a hygrometer with memory storage capabilities.

Author: David Robert (david@ombrepixel.com)
Microcontroller: PIC16F873
Language: Assembly (MPASM)


Hardware Configuration

Microcontroller Settings

  • Processor: PIC16F873
  • Clock Frequency: High-Speed Oscillator (HS_OSC) - 4 MHz to 20 MHz range
  • Power-up Timer: Enabled (PWRTE_ON)
  • Watchdog Timer: Disabled (WDT_OFF)
  • Brown-out Detect: Disabled (BODEN_OFF)
  • Low Voltage Programming: Disabled (LVP_OFF)
  • Code Protection: Disabled (CP_OFF)

Pin Configuration

PORT A (Analog Input)

  • RA0-RA5: Configured as analog inputs (bits 0-5 as inputs)
  • RA2: ADC input channel (configured in ADCON0)
  • Uses internal voltage reference

PORT B (LCD Interface)

  • RB4-RB7: LCD data lines (4-bit mode)
  • RB2 (bLCD_RS): LCD Register Select
  • RB3 (bLCD_E): LCD Enable signal
  • All configured as outputs

PORT C

  • All pins configured as inputs (TRISC = 0xFF)

LCD Display

  • Interface Type: 4-bit mode
  • Configuration: 2 lines, 5×7 dot matrix characters
  • Connection: PORT B (upper nibble for data, RB2/RB3 for control)

Analog-to-Digital Converter (ADC)

  • Resolution: 10-bit (0-1023)
  • Channel: RA2 (Channel 2)
  • Clock Source: Internal RC with predivider ÷8
  • Voltage Reference: VDD (5V typical)
  • Acquisition Time: ~80µs (4× 20µs delays)

Software Architecture

Main Program Flow

1. System Initialization
   ├── Configure I/O ports
   ├── Set up interrupts (prepared but not used)
   ├── Initialize ADC
   └── Clear RAM

2. LCD Initialization
   └── Configure 4-bit mode, 2-line display

3. Main Loop (infinite)
   ├── Acquire analog signal (ADC conversion)
   ├── Convert raw ADC value to voltage
   ├── Display voltage on LCD
   ├── Wait (temporal delay)
   └── Repeat

Key Modules

1. pic_voltmeter.asm (Main Program)

The core application logic containing:

  • System Configuration

    • Register definitions (OPTION_REG, INTCON, PIE1, PIE2)
    • Port direction setup
    • Interrupt handlers (framework present but unused)
  • Data Acquisition (acquire)

    • Configures ADC for channel 2 (RA2) with predivider ÷8
    • Waits for acquisition time (80µs)
    • Starts conversion and polls GO bit
    • Reads 10-bit result from ADRESH:ADRESL into auxreg1:auxreg2
  • Voltage Calculation (voltage)

    • Converts raw 10-bit ADC value to voltage representation
    • Uses bit-shifting and arithmetic operations
    • Formula approximates: Voltage = (ADC_Value × 5V) / 1024
    • Result stored in auxreg1:auxreg2 (scaled for display)
  • Display Formatting (LCD_ShowAcq)

    • Positions cursor at line 1
    • Displays "Ascii : " label
    • Converts voltage to ASCII decimal (XXX.XX format)
    • Appends "V" unit suffix
  • Timing (tempo)

    • Triple-nested loop delay routine
    • Provides ~262ms delay between readings

2. lcd.inc (LCD Driver)

LCD control and communication routines:

  • LCD_Init_Display: Initializes LCD in 4-bit mode

    • Sends initialization sequence
    • Configures 2-line, 5×7 character display
    • Enables display, disables cursor
  • LCD_SendCMD: Sends commands to LCD (RS=0)

    • Splits byte into two nibbles
    • Toggles enable pin for each nibble
  • LCD_SendCHAR: Sends characters to LCD (RS=1)

    • Similar to SendCMD but with RS=1 for data
  • LCD_Clear: Clears display content

  • LCD_ShowLogo: Displays "Hello!" welcome message

3. ascii.inc (Conversion Utilities)

Number formatting and conversion routines:

  • HEX16_2_ASCII: Converts 16-bit binary to 5-digit ASCII decimal

    • Input: auxreg1:auxreg2 (16-bit value)
    • Output: aBCD0:aBCD1:aBCD2:aBCD3:aBCD4 (ASCII characters)
    • Implements binary-to-BCD conversion via bit testing
    • Suppresses leading zeros
  • BCD_normalize: Handles decimal carry during conversion

  • Timing Functions:

    • __Delay_5uS: 5 microsecond delay
    • __Delay_20uS: 20 microsecond delay
    • __Delay_50uS: 50 microsecond delay
    • __Delay_Nx: Variable delay (N × 50µs)

4. macro.inc (Assembly Macros)

Utility macros for cleaner code:

  • Comparison Macros: JE, JNE, JL, JG, JLE, JGE, JZ, JNZ
  • Data Movement: MOVLF, MOVFF
  • LCD Macros: CHR_LCD (send character), INS_LCD (send instruction)
  • Bank Selection: F_BANK

Memory Organization

Bank 0 (0x20-0x6F)

User variables:

  • test, table[10]: General purpose
  • cmpt1, cmpt2, cmpt3: Counter variables for delays
  • asciibit: Binary-to-ASCII conversion helper
  • TEMP0, TEMP1: Voltage calculation temporaries
  • auxreg1, auxreg2: ADC result and intermediate calculations

Common RAM (0x70-0x7F)

Accessible from all banks:

  • w_temp, status_temp, FSR_temp, PCLATH_temp: Interrupt context saving
  • aBCD0-aBCD4: ASCII decimal representation (5 digits)
  • dlyLSD, dlyMSD: Delay loop counters
  • LCD_Char: LCD character buffer

Banks 1-3

Reserved for future expansion (currently unused).


Operational Details

Voltage Measurement Process

  1. ADC Configuration

    • Selects analog input channel 2 (RA2)
    • Configures clock source with predivider ÷8
    • Sets right-justified result format
  2. Conversion Sequence

    Acquisition Time → Start Conversion → Poll Status → Read Result
         (80µs)              (GO bit)         (GO=0)      (10 bits)
    
  3. Voltage Calculation Algorithm The voltage subroutine performs fixed-point arithmetic:

    V = ADC_Value / 1024 × 5V
    
    Implementation (optimized shifts and adds):
    - Right shift 2 bits (÷4)
    - Subtract from original
    - Right shift 5 bits (÷32)
    - Add back original
    - Right shift 1 bit (÷2)
    
    Net effect: V ≈ ADC × 0.0048828 (approximately ADC × 5/1024)
    
  4. Display Format

    • Converts to ASCII decimal: "XXX.XX V"
    • Leading zeros suppressed as spaces
    • Fixed 2 decimal places
    • Example: " 3.25 V" or " 4.98 V"

LCD Display Layout

Line 1: "Ascii :  XX.XX V"
Line 2: (unused)

Timing Characteristics

  • ADC Conversion Time: ~20µs (at Fosc/8 prescaler)
  • Display Update Rate: ~262ms (controlled by tempo routine)
  • Effective Sampling Rate: ~3.8 samples/second

Interrupt Framework

The code includes a comprehensive interrupt handling framework (currently unused):

Prepared Interrupt Sources

  • Timer 0 (TMR0): General purpose timer
  • RB0/INT: External interrupt
  • RB4-RB7: Port change interrupt
  • ADC: Conversion complete
  • USART: Serial communication (RX/TX)
  • SSP: Synchronous serial port
  • CCP1/CCP2: Capture/Compare/PWM modules
  • TMR1/TMR2: Additional timers
  • EEPROM: Write complete
  • Bus Collision: I²C collision detection

All interrupt handlers are present as stubs but return immediately. This provides a foundation for future enhancements.


Future Development Goals

According to the project header comments, planned enhancements include:

  1. Hygrometer Functionality

    • Replace voltage measurement with humidity sensing
    • Integrate appropriate humidity sensor (capacitive/resistive)
  2. Data Logging

    • Utilize internal EEPROM (present macros: REEPROM, WEEPROM)
    • Store min/max readings or time-series data
    • Implement timestamp functionality
  3. Enhanced User Interface

    • Use second LCD line for additional information
    • Display min/max values, trends
    • Add menu system for configuration
  4. Real-Time Features

    • Enable timer interrupts for precise sampling
    • Implement interrupt-driven ADC conversion
    • Add alarm thresholds

Building and Programming

Required Tools

  • Assembler: MPASM (Microchip PIC Assembler)
  • IDE: MPLAB X IDE or compatible
  • Programmer: PICkit, ICD, or similar device

Project Files

  • pic_voltmeter.asm - Main program
  • pic_voltmeter.mcp - MPLAB Classic project
  • pic_voltmeter.mcw - MPLAB workspace
  • lcd.inc - LCD driver library
  • macro.inc - Macro definitions
  • ascii.inc - Conversion utilities
  • p16F873.inc - PIC16F873 register definitions (Microchip standard)

Build Process

# Using MPASM command line
mpasm pic_voltmeter.asm /p16F873

# Or use MPLAB X IDE:
# 1. Open pic_voltmeter.mcp
# 2. Build → Build Main Project
# 3. Program device with generated .hex file

Technical Specifications

Parameter Value
Microcontroller PIC16F873
Flash Memory 4K words (8KB)
RAM 192 bytes (4 banks × 48 bytes + 16 common)
EEPROM 128 bytes
ADC Resolution 10-bit (1024 levels)
Input Voltage Range 0V to VDD (typically 5V)
Voltage Measurement Resolution ~4.88 mV/step (5V / 1024)
Display Update Rate ~3.8 Hz
Operating Frequency 4-20 MHz (HS oscillator)

Code Style and Conventions

v

  • Language: Comments (original documentation)
  • Naming: Mixed case for variables, uppercase for macros
  • Indentation: Tab-based alignment
  • Bank Management: Explicit bank switching using BANK0/BANK1/BANK2/BANK3 macros
  • Page Management: Inter-page jump macros (GOTOX, CALLX) for programs >2K

Troubleshooting

Common Issues

  1. No LCD Display

    • Check PORT B connections (RB2=RS, RB3=E, RB4-7=Data)
    • Verify LCD contrast adjustment
    • Confirm 5V power supply
  2. Incorrect Voltage Readings

    • Verify RA2 input within 0-5V range
    • Check ADC reference voltage (VDD)
    • Calibrate using known voltage source
  3. Erratic Behavior

    • Ensure stable power supply
    • Add decoupling capacitors (0.1µF near VDD/VSS)
    • Check for proper grounding
  4. Build Errors

    • Verify all .inc files are in project directory
    • Ensure p16F873.inc is in MPASM include path
    • Check for MPASM version compatibility

License and Credits

This project was created by David ROBERT on February 29, 2004, as an educational/hobbyist embedded systems project. The code demonstrates fundamental PIC microcontroller programming techniques including:

  • ADC signal acquisition
  • LCD interfacing (4-bit mode)
  • Binary-to-ASCII conversion
  • Fixed-point arithmetic
  • Assembly language optimization

Related Documentation

For additional information, refer to:

  • PIC16F873 Datasheet (Microchip DS30292C)
  • MPASM User's Guide (Microchip DS33014)
  • LCD HD44780 Controller Datasheet (Hitachi/compatible)
  • MPLAB X IDE Documentation

Contact

Author: David ROBERT
Project Date: February 29, 2004
Last Updated: October 8, 2025 (Documentation)

About

PIC16F873 Voltmeter with LCD Display [Archive]

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages