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..?
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
}
}
}