Problem with MCU timing in C

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
I've been working on little projects to learn the C language using MPLAB IDE and High-Tech C lite compiler.

I have noticed that although my codes function as they're supposed to, my timing is always off and I'm not sure why. A flash of the LED for 1 second is coming out to be about 800mS or so, and I'm unsure as to the discrepancy.

I have heard that the High-Tech C compiler Lite version does not allow for precise timing operations, though I'm not sure if that's actually the case, but if anyone has heard this and it turns out it's not a problem with my code, that'd be nice to know. Here is my code snippet where I define clocks:

Rich (BB code):
// CONFIGURATION

#include <htc.h>
#define _XTAL_FREQ 4000000
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & BORDIS & LVPDIS & UNPROTECT & UNPROTECT);

/*************************************************/

//    GLOBAL VARIABLES

unsigned char dlycnt;    //DELAY COUNTER
unsigned char fpnum;    //FLASH PATTERN NUMBER
unsigned char set = 0;
unsigned char dbnce;    //SWITCH DEBOUNCE
/*************************************************/

void main()                //MAIN PROGRAM START
{
unsigned char address = 0;    //DEFINE ADDRESS FOR EEPROM
INTEDG = 1;                    //TRIGGER INTERRUPT ON RISING EDGE
INTE = 1;                    //RB0 EDGE INTERRUPT ENABLED
ei();                        //GLOBAL INTERRUPTS ENABLED

fpnum = eeprom_read(address); //DATA READ FROM EEPROM AND COPIED TO fpnum

 OSCF=1;            // INTERNAL OSCILLATOR 48KHz
 TRISA=0XFF;        // TRISA NOT USED, ALL SET AS INPUT
 TRISB=0XF7;        // TRISB 7-4 INPUT, 3 OUTPUT, 2-0 INPUT
Also, I'm calling delays using this routine:

Rich (BB code):
RB3=1;            //SET RB3 HIGH
     for (dlycnt=0; dlycnt<10; dlycnt++)    //CALL 1 SECOND DELAY
     {
        __delay_ms(100);
     }
Thanks for the help.
 

ErnieM

Joined Apr 24, 2011
8,377
20% off for 10 loops of a 100 mS delay does seem excessive. Is that "INTIO" config setting for the internal oscillator? Have you checked how fast that is actually running?
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
20% off for 10 loops of a 100 mS delay does seem excessive. Is that "INTIO" config setting for the internal oscillator? Have you checked how fast that is actually running?
INTIO is for internal oscillator with the clock pins set to I/O mode. I have not checked how fast it is actually running as I'm not entirely sure how to do this, I'll be honest.

Also, I'll clear something up right now that I just noticed about my code so that no one else does. I have _XTAL_FREQ set for 4MHz which is correct, but my comments under OSCF=1 say that it's set for 48KHz. 48KHz was the original setting, but I changed it to test if the 48KHz setting was what was messing up the timing, and I just never changed the comment. The timing is off regardless of whether the MCU is operating at 4MHz or 48KHz.

Perhaps I should test the timing using an external 4MHz crystal, which I have on hand, and see if the timing is still off.
 

ErnieM

Joined Apr 24, 2011
8,377
INTIO is for internal oscillator with the clock pins set to I/O mode. I have not checked how fast it is actually running as I'm not entirely sure how to do this, I'll be honest.
When using a new PIC device my first "reality check" is to see if I've set up things correctly so I am actually running at the frequency I think I am.

One way (simpler but...) is if your internal oscillator can drive a pin (and it's free!) you can drop a scope on it to read what Fosc / 4 is.

Other way is to write some code to toggle any free pin hi and low several times, a short delay, then rinse wash repeat. A scope should be able to capture the pulse at the first edge if you set the re-trigger delay correctly. Go back and look at the disassemble listing and count how many instructions it takes for each 1 and 0, and use that to compute the internal instruction clock.

I'd do that before I started changing hardware as you can introduce other problems doing that, though the crystal should run pretty dead nuts on 4MHz. Just that it may not run, and you are running now.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Thank you Ernie, appreciate the feedback. I do not own a scope, though I'm in the market for one, so the best way I have at the moment to test frequency accuracy (very rudimentary) is to flash a LED on/off once per second and compare it to the ticks on my wrist watch. Yea, I know... once you're done laughing...
 

ErnieM

Joined Apr 24, 2011
8,377
Thank you Ernie, appreciate the feedback. I do not own a scope, though I'm in the market for one, so the best way I have at the moment to test frequency accuracy (very rudimentary) is to flash a LED on/off once per second and compare it to the ticks on my wrist watch. Yea, I know... once you're done laughing...
Believe me, I'm not laughing. I'm lucky to have a scope I picked up as it was being tossed as "obsolete," but it is a classic Tektronics analog scope.

Can you run your code in a simulator? If it sims as 1.00 seconds then it's the PIC running fast and the code is OK.

Without a scope it may also be a good idea to use your crystal, it's probably either gonna run dead nuts accurate or not at all, so you learn something.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Still planning on testing things with an external crystal, just haven't had a chance to do it yet. I've been too busy between work and getting ready for the Fall school semester to start on Monday.
Should have time to test this later today.
 

THE_RB

Joined Feb 11, 2008
5,438
...
I do not own a scope, though I'm in the market for one, so the best way I have at the moment to test frequency accuracy (very rudimentary) is to flash a LED on/off once per second and compare it to the ticks on my wrist watch. Yea, I know... once you're done laughing...
There's nothing wrong with that! In the drawer on my compter desk I have a little cheap digital stopwatch. It's easy to generate (say) a 10second period in software and grab the stopwatch to check the timing is ok, that's also a great way to test simple things like PIC timer prescaler settings etc.

Re your timing issue it might be that you have cleared the PIC internal osc calibration value, with some PICs when the calibration value is cleared the timing will be 10% or 20% out, similar to what you are getting.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
There's nothing wrong with that! In the drawer on my compter desk I have a little cheap digital stopwatch. It's easy to generate (say) a 10second period in software and grab the stopwatch to check the timing is ok, that's also a great way to test simple things like PIC timer prescaler settings etc.

Re your timing issue it might be that you have cleared the PIC internal osc calibration value, with some PICs when the calibration value is cleared the timing will be 10% or 20% out, similar to what you are getting.
You know, that could actually be the case. I don't remember specifically clearing the MCU timing calibration, but I suppose being so new to programming yet that I could have inadvertently done so. If I remember correctly, the Datasheet of the PIC should tell me how to recalibrate the timing. I'll look into that... again, when I have time. I know I keep saying that I'm going to throw a crystal on the thing to see if that solves timing, but again, I haven't had time. School started and I'm working full time (as I always have) so time is short!

I'll check both, crystal first, then recalibrate the chip. Thanks for all the great feedback guys, always appreciated. :)
 

ErnieM

Joined Apr 24, 2011
8,377
My PicKit II could recalibrate some devices, it has an app for that. AFAIK it is a menu choice on the PicKit II stand-alone application.
 

t06afre

Joined May 11, 2009
5,934
Remember that _XTAL_FREQ is the system clock. So if your MCU is running at 48KHz clock speed. You should use 48KHz then defining the _XTAL_FREQ
It would also help if you told us which PIC you are using
 
Top