Last active
June 15, 2021 11:07
-
-
Save BDeliers/f27d02469b90f8718b33ef9049a053ee to your computer and use it in GitHub Desktop.
Self-measure supply voltage from PIC16F153xx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DIA addresses | |
#define TSLR2 0x8113 | |
#define FVRA1X 0x8118 | |
#define FVRA2X 0x8119 | |
// Read from Device Information Area | |
uint16_t DIARead(uint16_t addr) { | |
// Access DIA | |
NVMCON1 = 0b01000000; | |
// Set address | |
NVMADRH = (addr >> 8) & 0xFF; | |
NVMADRL = addr & 0xFF; | |
// Start reading | |
NVMCON1bits.RD = 1; | |
// Wait for reading end | |
while (NVMCON1bits.RD); | |
// Return data | |
return (NVMDATH << 8) | NVMDATL; | |
} | |
/* MEASURE VCC */ | |
// FVR enabled, Temperature sensor disabled, low range, comparator FVR disabled, ADC FVR buffer 1024mV | |
FVRCON = 0b10000001; | |
// Wait for FVR to be ready | |
while (!FVRCONbits.FVRRDY); | |
// ADC source is FVR buffer 1, conversion stopped, ADC enabled | |
ADCON0 = 0b11111001; | |
// Result right aligned, clock is ADCRC, ref is VCC | |
ADCON1 = 0b10110000; | |
// No auto conversion | |
ADACT = 0; | |
// Required for ADC value settling | |
__delay_us(200); | |
// Start conversion | |
ADCON0bits.GO = 1; | |
// Wait for conversion end | |
while (ADCON0bits.GO); | |
// Calculate | |
uint16_t adc = (ADRESH << 8) | ADRESL; | |
// FVR real value | |
uint16_t fvrCalib1 = DIARead(FVRA1X); | |
// Vcc = Vfvr * ADC dynamic / ADC value | |
float voltage = (fvrCalib1 * 1024.0) / adc; | |
//uint16_t voltage = ((8192 / adc) * 1024) / 8; | |
printf("\nSupply voltage %fmV\r", voltage); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment