Hey guys..
Below are some of the code to read ADC on both AN0 and AN1 at 2Hz using PIC12F615.
The default FOSC is 4 MHz using internal oscillator.
There is a switch connect to GP2 and when the switch is pressed, GP2 -> HIGH.
What I'm trying to do is when the switch is pressed, I want to PIC to run at FOSC = 8MHz. When the switch is released, I want the PIC to run back at Fosc = 4MHz. As in, the PIC will just change its FOSC on the go.. Below is the rough code. As you can see, when GP2 -> HIGH, ANSEL and IOSCFS will change accordingly so that the PIC will sample at 4Hz instead of 2Hz.
Hmm.. will it work..? Is there any thing I missed..?
How long will it need for the internal oscillator to stabilize to its new Fosc..?
Code:
#include <pic.h>
/***** CONFIGURATION *****/
// Config: 4MHz int clock, no watchdog, ext reset disbled, no code protect
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS);
void adc_read(unsigned char channel)
{
ADON = 1;
ADCON0 = (channel << 2) + 0b00000001; //
GODONE = 1;
while(GODONE)
continue; // wait for conversion complete
ADON = 0;
}
void interrupt isr(void)
{
static int cntTMR0 = 0;
TMR0 += 256 - 250 + 3;
T0IF = 0;
if (++cntTMR0 == 2000) // loop 2000 times to make 0.5s (for 4 MHz)
{
cntTMR0 = 0; // interrupt occur every 250us. 2000 * 250us = 0.5s
ReadADC = 1;
}
}
void main()
{
// Initialisation
// ports
TRISIO = 0b00011111;
// Timer0
OPTION = (OPTION & 0xC0) + 0x08;
// Bit 3 - Prescaler assigned to WDT
// Bit 2:0 - WDT Rate = 1:1
// Interrupt
T0IE = 1; // Enable TMR0 interrupt
ei(); // Enable global interrupt
// configure ADC:
CMCON0 = 7; // Turn off Comparators
ANSEL = 0b00010011; // Set GP0 and GP1 as analog
// Select the Clock as Fosc/8
ADCON0 = 0b00000000; // Turn on the ADC
// Bit 7 - Left Justified Sample
// Bit 6 - Use VSS
// Bit 4:2 - Channel 0
// Bit 1 - Do not Start
// Bit 0 - Turn on ADC
while(1)
{
if (ReadADC == 1)
{
ReadADC = 0;
adc_read(0);
ADC1 = ADRESH;
adc_read(1);
ADC2 = ADRESH;
}
if (GP2 == 1)
{
// 8MHz
ANSEL = (ANSEL & 0x0F) + 0x50; // Change TAD for 8 MHz
IOSCFS = 1; //Internal Oscillator Frequency Select bit
}
else
{
// 4MHz
ANSEL = (ANSEL & 0x0F) + 0x10 // Change TAD for 4 MHz
IOSCFS = 0; //Internal Oscillator Frequency Select bit
}
}
}