1
\$\begingroup\$

I'm using a PIC16F1824 with an external 4MHz oscillator. I actually want to use the internal oscillator, but the timing seems incorrect.

For example, I tried to use delay_ms(1000), and it delayed 5 seconds instead of the expected 1 second.

What did I do wrong?

Data sheet: http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en546901

I'm clueless reading the OSCCON details: enter image description here

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Which clock are using? The 16MHz, 500KHz or 32KHz clock? It sounds like you may be using the 500KHz one? \$\endgroup\$
    – Majenko
    Jun 21, 2011 at 12:31
  • \$\begingroup\$ The default frequency is 500 kHz. Post your code. \$\endgroup\$ Jun 21, 2011 at 12:37
  • 1
    \$\begingroup\$ @mlam You don't. That PIC has 16MHz, 500KHz or 31KHz. There is no 4MHz option. Check the OSCCON register (under the Oscillators section of the data sheet) \$\endgroup\$
    – Majenko
    Jun 21, 2011 at 15:02
  • 2
    \$\begingroup\$ To get 4 MHz you set bit 6-3 of OSCCON to 1101 (page 71 of the data sheet). \$\endgroup\$ Jun 21, 2011 at 16:45
  • 1
    \$\begingroup\$ I just noticed that you originally said 18F1824, but the datasheet page later added to your post says 16F1824. Which is it? The code I gave in my answer was assuming the PIC 18 instruction set, since that's all you mentioned at the time. Is there even a 18F1824? Actually that sounds more like a enhanced PIC 16 part number. It now seems your original text was wrong, which is a bit strange considering the PIC model is a major point of the question. \$\endgroup\$ Jun 22, 2011 at 14:10

4 Answers 4

1
\$\begingroup\$

To get 4 MHz you set bit 6-3 of OSCCON to 1101 (page 71 of the data sheet).

I suggested that in a comment, and it apparently solved the problem.

The internal oscillator should be running when the device is reset, so you merely have to change those bits and you should be running from it at 4 MHz, instead of the 4 MHz crystal.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks to @Leon Heller. I managed to get my XTAL 4 Mhz works. I added OSCCON = 1101; And my USART works at the same time! Thanks guys. But I haven't find a way to use internal Oscillator. \$\endgroup\$
    – mlam
    Jun 22, 2011 at 11:31
  • \$\begingroup\$ I removed my XTAL and I tried to use the following codes to get internal 4Mhz. The delay_ms become much faster. Basically I just want a simple internal oscillator.: OSCCON.SCS1 = 1; OSCCON.SCS0 = 0; OSCCON.IRCF3 = 1101; \$\endgroup\$
    – mlam
    Jun 23, 2011 at 6:35
  • \$\begingroup\$ Ok. Solved. This oscillator is really difficult. I got the referrence from here: roughrecord.blogspot.com/2010/12/… \$\endgroup\$
    – mlam
    Jun 23, 2011 at 8:01
1
\$\begingroup\$

There are many things that could be wrong between the oscillator and however you measured the delay you got. First, do the same thing with the known good 4MHz oscillator and make sure you get the expected measurement. Then try with the suspect oscillator setup and see what you get.

I wouldn't be using C and some possibly suspect delay routine to measure the oscillator rate anyway. Occasionally I want to check that the oscillator is set up as expected, especially on PICs with complicated PLLs and dividers. What I usually do is write loop that toggles a port pin every iteration, something like:

loop
     btg   portb, 0
     bra   loop

That loop takes 3 instruction cycles per iteration, so 6 instruction cycles per output period, and 24 oscillator cycles per output period. Now look at the square wave with a scope or frequency meter and multiply by 24 to get the PIC oscillator frequency after whatever PLLs and dividers are applied.

\$\endgroup\$
0
0
\$\begingroup\$

delay_ms probably requires that the clock speed is defined in some .h file so that it knows the oscillator's speed and can calculate how long to loop for. If you're in MPLAB, you can right-click on the delay_ms function call and click "GoTo Locator"; it will take you to the definition. Look around that file to see if there's a define anywhere that asks for the clock speed or something similar.

\$\endgroup\$
1
  • \$\begingroup\$ Thankss ajs410. I found the answer. See comment from Leon \$\endgroup\$
    – mlam
    Jun 22, 2011 at 11:33
0
\$\begingroup\$

delay_ms() relies on you correctly defining XTAL in the code prior to it's use, it has no idea what you have set the clock to in hardware so you need to tell it by doing something like XTAL 4000000 (can't remember off the top of my head but take a look in the details of the delay_ms(); function in the compiler manual and it will say)

UPDATE:

Found my code and the line reads:

#define     _XTAL_FREQ 4000000  
\$\endgroup\$
1
  • \$\begingroup\$ Thanks @SimonBarker, I'm using MikroC, I will see how to use it. \$\endgroup\$
    – mlam
    Jun 22, 2011 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.