Skip to content

Instantly share code, notes, and snippets.

@DavidEGrayson DavidEGrayson/fvrbor.c
Last active Oct 14, 2015

Embed
What would you like to do?
/* Code for the PIC18F25K50 that causes a brown-out reset by dumping a
* high voltage onto the FVR from the ADC's holding capacitor.
*
* Connections:
* RA0: Tie this pin to an LED that turns on when the pin is high.
* RA1/AN1: Don't connect anything to this pin.
* RA2/AN2: Don't connect anything to this pin.
* VDD: Connect a power source between 3 V and 5 V.
* GND: Connect to the GND of the power source.
*
* Expected behavior:
* On power up, LED blinks twice, pauses, then turns on.
*
* Actual behavior:
* On power up, LED blinks twice, pauses, blinks 4 times, pauses,
* blinks 4 times, pauses, blinks 4 times, pauses...
* This indicates that a brownout reset happens when the ADC
* is connected to the FVR.
*/
#pragma config FOSC = INTOSCIO
#pragma config CFGPLLEN = OFF
#pragma config CPUDIV = NOCLKDIV
#pragma config nPWRTEN = ON
#pragma config BOREN = ON
#pragma config BORV = 285
#pragma config nLPBOR = OFF
#define _XTAL_FREQ 1000000
#include <xc.h>
#define LED_ENABLE() (TRISA0 = 0)
#define LED(on) (on ? LATA0 = 1 : LATA0 = 0)
void delay_ms(unsigned int delay)
{
while(delay--) { __delay_ms(1); }
}
void blink()
{
LED(1);
delay_ms(100);
LED(0);
delay_ms(300);
}
void main(void)
{
LED_ENABLE();
/* Make RA1/AN1 be an analog input and drive it high. */
ANSELAbits.ANSA1 = 1;
TRISA1 = 0;
LATA1 = 1;
/* Make RA2/AN2 be an analog input and drive it low. */
ANSELAbits.ANSA2 = 1;
TRISA2 = 0;
LATA2 = 0;
/* Enable the FVR for 1.024 V operation. */
VREFCON0 = 0b10010000;
while(!VREFCON0bits.FVRST) { }
/* Check for a brown-out reset. */
RCONbits_t initialRCON = RCONbits;
RCONbits.POR = 1;
RCONbits.BOR = 1;
if (initialRCON.POR && !initialRCON.BOR)
{
/* A brown-out reset occurred. */
blink();
blink();
}
/* Charge up the ADC's holding capacitor by selecting AN1, which
* is driving high. */
ADCON0 = 0b00000101;
blink();
/* Uncommenting the line below fixes the problem, because it
* allows the ADC's holding capacitor to discharge by selecting
* AN2, which is driving low. */
// ADCON0 = 0b00001001;
blink();
delay_ms(400);
/* Select the FVR, connecting its output to the ADC's holding
* capacitor. This causes a brown-out reset if the capacitor is
* charged. */
ADCON0 = 0b01111101;
while(1)
{
LED(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.