PIC16C72/PIC16F72 based DC voltmeter
// Program : Calculates the input voltage of ADC and display the result in a
// 4-digit multiplexed 7-segment display
// Device : PIC16C72/PIC16F72
// Clock : 4MHz
#define digit1 PORTB.F0
#define digit2 PORTB.F1
#define digit3 PORTB.F2
#define digit4 PORTB.F3
#define decimal PORTC.F7
void delay() { // Function for 5mS delay
delay_ms(5);
}
unsigned char display(unsigned char no) { // Function for returning mask values
unsigned char pattern;
unsigned char segment[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66,
0x6D, 0x7D, 0x07, 0x7F, 0x6F};
pattern = segment[no]; // Patterns to be returned
return (pattern);
}
/* Main program starts here */
void main() { unsigned char units, tens, hundreds, thousands;
unsigned long adc_val;
TRISA = 0xFF; // PORTA as input
TRISB = 0x00; // PORTB as output
TRISC = 0x00; // PORTC as output
ADCON0 = 0x41; // Configuring ADC
ADCON1 = 0x00;
Start: // Endless loop
delay();
ADCON0.F2 = 1; // Start conversion
Wait: // Loops until conversion stops
delay();
if (ADCON0.F2 == 1) goto wait; // Checks conversion status
adc_val = ADRES; // Reads ADC register
adc_val = (adc_val*5000)>>8; // Converts adc value to volts
adc_val = adc_val/10; // Omits LSD
/* Converts adc_val to four individual digits */
thousands = adc_val / 1000; // digit_thousands
adc_val = adc_val % 1000;
hundreds = adc_val / 100; // digit_hundreds
adc_val = adc_val % 100;
tens = adc_val / 10; // digit_tens
units = adc_val % 10; // digit_units
/* Formats the digits to desired configuration */
if (units > 5) {
tens = tens + 1; // Add carry to ten's place
units = 0; // Clear Unit's place
}
if (tens > 9) {
hundreds = hundreds + 1; // Add carry to hundred's place
tens = 0; // Clear tens's place
}
if (hundreds > 9) {
thousands = thousands + 1; // Add carry to thousand's place
hundreds = 0; // Clear hundred's place
}
/* Loads mask values to digits */
PORTC = display(thousands); // Send to PORTC
digit1 = 0; // Enable digit 1
delay(); // Add delay
digit1 = 1; // Disable digit 1
PORTC = display(hundreds); // Send to PORTC
digit2 = 0; // Enable digit 2
decimal = 1; // Enable decimal point
delay(); // Add delay
digit2 = 1; // Disable digit 2
decimal = 0; // Disable decimal point
PORTC = display(tens); // Send to PORTC
digit3 = 0; // Enable digit 3
delay(); // Add delay
digit3 = 1; // Disable digit 3
PORTC = display(units); // Send to PORTC
digit4 = 0; // Enable digit 4
delay(); // Add delay
digit4 = 1; // Disable digit 4
goto Start // Repeat forever
}