Last active
October 14, 2015 23:38
-
-
Save DavidEGrayson/8dae6a2afeaffd44f1db to your computer and use it in GitHub Desktop.
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
/* 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