Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Changing Fosc on the go.

Status
Not open for further replies.

MrNobody

New Member
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
		}
	}
}
 
You can't write to the config register in code and so this will not work.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top