Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Internal Oscillator configuration in PIC10F320

Status
Not open for further replies.

djc

Advanced Member level 1
Joined
Jan 27, 2013
Messages
402
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
India
Activity points
4,554
Hi,

I want to use internal oscillator of PIC10F320. I am using MikrocPro. As suggested in datasheet I configured OSCCON register for 16Mhz internal oscillator operation. Cleared 'FOSC' bit in configuration word in edit project setting. just toggled a port pin in timer interrupt. Checked it on scope and it is showing frequency of 14.674 Hz, though it should be 15Khz. Program is as follows,
Code:
#define channel_1 PORTA.B0
#define channel_2 PORTA.B1
char x=0;

PortNClock(){
 TRISA = 0b00000100;      // RA2 as as i/p,RA0 RA1 as o/p
 PORTA = 0x00;
 ANSELA = 0b00000100;     //RA2 as ADC i/p
 OSCCON = 0x01111001;     // 16 MHz internal clock

 CWG1CON0 = 0x00;         //complementry waveform generator off
 CWG1CON1 = 0x00;         //complementry waveform generator off
 CWG1CON2 = 0x00;         //complementry waveform generator off
}

Timer0(){
 INTCON = 0b11100000;     //Enable All interrupts and Timer0 interrupt
 T0CS_bit = 0;            //Internal clock /4
 PSA_bit = 1;             //Prescalar is inactive
 TMR0 = 0x00;
}

void interrupt(){
 if(INTCON.TMR0IF){
 TMR0IF_bit = 0;
 }
 channel_2=~channel_2;
 
TMR0 = 0x00;       //EC
}
void main() {
 PortNClock();
 
 Timer0();

        while(1){ 

        }

}
Can somebody plz tell me what are the other settings needs to be done to achieve desired frequency.
 

Hi,

This is just a deviation of 1.48 microseconds.
The problem might be that if the timeout is set up correctely, then it takes additional time to step into the ISR...process some code...then reset (restart) the timer.

Does the timer have some automatic restart feature?
If not, then work with the "compare feature"...don't restart the counter, just set new compare values.

Klaus
 

Thanks Klausst,
However unfortunately this IC does not have a capture compare mode. For comparing i may have to equalise the timer value with desired decimal value in main rather than checking for interrupt. Will that be right?
 

Hi,

@FvM:
I calculated again, but still see 1.48us.

@djc:
According datasheet figure 17.1 there is a comparator. But if you say so..

Klaus
 

14.674 Hz versus 15Khz. I presume decimal point, so factor 1000.
 

Hi,

Oh yes, now I see.

@OP: is it 14.7Hz or 14.7kHz?

Klaus
 

It is 14.7 Hz
 

Fig 17.1 comparator might be referring to PR2 register associated with Timer2 register.
 

Hi,

OK, then it looks like the factor 1024.

Klaus
 

A simple way to check that the oscillator is working at the frequency you think it is, is to set the CLKROE bit (in the CLKRCON register) and measure the signal on pin 3 (RA2).
Then just initialise the the oscillator and enter an empty 'while' loop.
(By the way, no point in setting the HFIOFS bit in OSCCON - it is read only.)
Probably not relevant for now but in your ISR, you toggle 'channel_2' and reset the TMR0 outside the test for TMR0IF. That means these instructions will execute on ANY interrupt, not just form the timer.
Also, according to the 'electrical specifications' for that device, parameter OSC8 shows the HFosc as having +/- 3% accuracy at best. Therefore it could be anything from 15.52MHz to 16.48MHz and still be within spec. Assuming the OP is actually measuring 14.674KHz, and ignoring the ISR overheads and instructions themselves, that would mean the oscillator was running at 15.03MHz - add in those overheads and you get fairly close to the bottom end of the acceptable Fosc range assuming a correct Vdd and the presence of the bypass capacitors etc..
Finally, that device has LAT capabilities and so you can apply the golden rule: read from the PORT and write to the LAT. To avoid RMW issues, 'channel_2' should be defined to reference LATA1.
Susan
 

"RMW" stands for "Read - Modify - Write" and refers to the low level operation that the hardware does to change a bit in a register.
Google "RMW" or "read modify write" and you will find (VERY) many references and explanations.
Overcoming RMW issues is one of the reason that the LATx registers were introduced into the Microchip MCUs.
Susan
 

Code:
#define channel_1 PORTA.B0
#define channel_2 PORTA.B1
char x=0;

PortNClock(){
 TRISA = 0b00000100;      // RA2 as as i/p,RA0 RA1 as o/p
 PORTA = 0x00;
 ANSELA = 0b00000100;     //RA2 as ADC i/p
 OSCCON = 0x01111001;     // 16 MHz internal clock

 CWG1CON0 = 0x00;         //complementry waveform generator off
 CWG1CON1 = 0x00;         //complementry waveform generator off
 CWG1CON2 = 0x00;         //complementry waveform generator off
 CLKROE_bit=1;
}


void main() {
 PortNClock();
 
         
}
Thanx Aussie. I configured CLKROE_bit =1 and checked the o/p on RA2 pin However there was no output. What did i do wrong. Right now i amusing SMD version of PIC10f320.

- - - Updated - - -

Code:
#define channel_1 PORTA.B0
#define channel_2 PORTA.B1
char x=0;

PortNClock(){
 TRISA = 0b00000000;      // RA2 as as i/p,RA0 RA1 as o/p
 PORTA = 0x00;
 ANSELA = 0b00000100;     //RA2 as ADC i/p
 OSCCON = 0x01111001;     // 16 MHz internal clock

 CWG1CON0 = 0x00;         //complementry waveform generator off
 CWG1CON1 = 0x00;         //complementry waveform generator off
 CWG1CON2 = 0x00;         //complementry waveform generator off
 CLKROE_bit=1;
}


void main() {
 PortNClock();
 
         
}
Sorry. I made a mistake. i didn't configure RA2 as o/p. Now it's showing 8Khz on RA2.

- - - Updated - - -

Code:
#define channel_1 PORTA.B0
#define channel_2 PORTA.B1
char x=0;

PortNClock(){
 TRISA = 0b00000000;      // RA2 as as i/p,RA0 RA1 as o/p
 PORTA = 0x00;
 ANSELA = 0b00000100;     //RA2 as ADC i/p
 OSCCON = 0x01111001;     // 16 MHz internal clock

 CWG1CON0 = 0x00;         //complementry waveform generator off
 CWG1CON1 = 0x00;         //complementry waveform generator off
 CWG1CON2 = 0x00;         //complementry waveform generator off
 CLKROE_bit=1;
}

Timer0(){
 INTCON = 0b11100000;     //Enable All interrupts and Timer0 interrupt
  T0CS_bit = 0;            //Internal clock /4
 PSA_bit = 1;             //1=Prescalar is inactive, 0=Prescalar is assigned
 TMR0 = 0x00;
}
void interrupt(){
 if(INTCON.TMR0IF){
 TMR0IF_bit = 0;
 LATA.B1=~LATA.B1;
 TMR0 = 0x00;       //EC
}
}


void main() {
 PortNClock();
 Timer0();

        while(1){
        
        }
         
}
Now what is happening in this code is, when empty "while{}" loop is written in main along with oscillator initialization no signal appears on RA2 pin and 14 Hz signal on RA1 pin . If no "while{}" loop is there signal appears on RA2 pin with frequency 8Khz and 14hz on RA1 pin. Can you please tell why this is happening?
 

I think internal oscillator frequency which is chosen be OSCCON register is not getting assigned to controller. Because i select 8Mhz internal oscillator but frequency shown on scope was still same as 14.7 Hz.
 

Don't bother trying to set the bottom 4 bits of the OSCCON register - they are read-only status bits.
Not a problem with this device but it is always a good habit to get in to to set output bits via the LAT register and not the PORT.
Does your compiler really allow bit references written as 'PORTA.B0'? It may well. However, if you are intending to *set* these bits, then you should be referring to the LAT register (as you do in the interrupt function).
Does your compiler treat a function named 'interrupt' as *special* and connect it to the interrupt vector? If not then triggering an interrupt will cause a device reset.
Also you definitely need the 'while' loop. Without it, what you are probably seeing is the device going through a sequence of: reset and call the 'main' function; the program sets things up as it should; the 'main' function exists and the device resets and starts the cycle again.
In none of your code examples do you show the include statement(s) that normally go at the start of the program. Can you please show us all of the code and also the config settings?
Finally, is it possible to not use the timer and interrupt but use the compilers 'delay' functions (if it has them) and simply toggle a bit?
Susan
 

Thanx Aussie
In none of your code examples do you show the include statement(s) that normally go at the start of the program. Can you please show us all of the code and also the config settings?
I am using Mikroc for PIC. It is not necessary to use "#include" statements in this compiler. In none of my codes i have used it. This is the complete code apart from few more lines in interrupt routine.
Finally, is it possible to not use the timer and interrupt but use the compilers 'delay' functions (if it has them) and simply toggle a bit?
I have to generate 100 KHz frequency to drive 2 channels of mosfet. That is of prime importance, so thought of putting it in interrupt routine.

Does your compiler treat a function named 'interrupt' as *special* and connect it to the interrupt vector?
I have been using interrupt routine like this. In that i have checked for timer interrupt only (TMR0IF flag). Similarly if serial interrupt is there, check for serial interrupt flag in the same interrupt routine.

Now even i configured internal oscillator for 8 MHz, still toggling port pin frequency is 14 Hz. With timer value starting from '0'. If i make it 125(nearly half of 256) frequency increases to 27 Hz. Thus internal oscillator which is configured through OSCCON is not getting assigned to controller. is there any other register to use internal oscillator?
 
Last edited:

Try the attached project on hardware. I think Proteus PIC10F320 model has some bug. My code is correct. 16 MHz Internal Oscillator is used. It should give 100 KHz Pulses.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//Timer0
//Prescaler 1:256; TMR0 Preload = 242; Actual Interrupt Time : 10 us
//Place/Copy this part in declaration section
void InitTimer0() {
    OPTION_REG = 0x87;
    TMR0 = 242;
    INTCON = 0xA0;
}
 
void Interrupt() {
    if(TMR0IF_bit) {
      LATA0_bit = ~LATA0_bit;
      //Enter your code here
      TMR0IF_bit = 0;
      TMR0 = 242;
    }
}
 
void main() {
 
    CLKRCON = 0x00;
    OSCCON = 0x79;
    
    ANSELA = 0x00;
    TRISA = 0x00;
    PORTA = 0x00;
    LATA = 0x00;
    
    InitTimer0();
    
    while(1) {
    
    }
}




Also try this code.

Code:
while(1) {
          LATA0_bit = ~LATA0_bit;
          Delay_us(10);
    }
 
Last edited:

Hey thanx Aussie and Okada.
It was really a silly mistake. I put 'OSCCON=0x01110000' that should be '0b01110000'. Maximum attainable frequency is 83KHz using this code.Here is the code.
Code:
#define channel_1 PORTA.B0
#define channel_2 PORTA.B1
char x=0;

PortNClock(){
 TRISA = 0b00000000;      // RA2 as as i/p,RA0 RA1 as o/p
 PORTA = 0x00;
 ANSELA = 0b00000100;     //RA2 as ADC i/p
 //OSCCON = 0b01110000;     // 16 MHz internal clock
 OSCCON = 0x79;
 
 CWG1CON0 = 0x00;         //complementry waveform generator off
 CWG1CON1 = 0x00;         //complementry waveform generator off
 CWG1CON2 = 0x00;         //complementry waveform generator off
 CLKROE_bit = 1;
}

Timer0(){
 INTCON = 0b11100000;     //Enable All interrupts and Timer0 interrupt
 //OPTION_REG = 0b00000100;
 T0CS_bit = 0;            //Internal clock /4
 PSA_bit = 1;             //1=Prescalar is inactive, 0=Prescalar is assigned
 TMR0 = 240;
}

void interrupt(){
 if(INTCON.TMR0IF){
 TMR0IF_bit = 0;
 //LATA.B1=~LATA.B1;
 x=x+1;
 if(x==1){
 channel_2=0;
 delay_us(2);
 channel_1=1;
 }
 else{
 channel_1=0;
 delay_us(2);
 channel_2=1;
 x=0;
 }
 TMR0 = 240;       //EC
}
}
void main() {
 PortNClock();
 Timer0();

        while(1){

        }
}

Now I have another issue. I have to drive to mosfets as written in interrupt routine. Dead time between firing of two channels is also necessary. So after giving delay of 2us maximum frequency appearing is 39 Khz that is also when timer value is 240. So very minimum time available for other work like reading ADC. SO how to achieve 100 Khz frequency while reserving sufficient time for other work.
 

Glad it is working.
I have to generate 100 KHz frequency to drive 2 channels of mosfet. That is of prime importance, so thought of putting it in interrupt routine.
You miss the point - this was to *test* that the oscillator was working correctly and really nothing else. As you have found out, if the oscillator is not correct, hen not much else will work the way you want. Once that is going, of course you can then build up the rest of the program , including all of the interrupts and other techniques that are needed.
Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top