PIC10F322 -XC8 – Timer0 Module

The code (timer0_example.c) and headers can be found in my GitHub here – https://github.com/JamieStarling/MCU_FUN/tree/master/Microchip/PIC10F322/

The PIC10F322 has two Timer Modules – we are going to take a look at TMR0 (Timer 0).

Timer 0 – is an 8bit timer/counter – that can be incremented by either an external signal or internal instruction clock.  When the timer overflows – (reaches 0xFF and turns over to 0x00) it sets an interrupt flag that can be read and/or can be setup to trigger an interrupt if desired.

The example that you will find below – is a replacement for the LED Blinker.  In the previous examples – we use the __delay_ms macro – which basically to generate the delay, required executing NOPs (No Operation) commands on the MCU.  This can consume a lot of program memory space and leaves the CPU spinning its wheels.

Enter Timer 0 – It is what it is – a hardware counter.  It also has a prescaler that can be enabled to give longer overflow times.

Here is what the code does..

First we set the PIC10F322 to run at 31Khz.

Enable TMR0 – to use a prescaler of 16

Enable an output on PORTA.0 – this is where the LED is.

Next we check the overflow flag to see if TMR0 did overflow – if so, we toggle the LED on or off – the reset the overflow flag.

Resetting the overflow flag is important, as it can only be done in software.

With that code, a LED attached with Blink at a rate of around 500ms. around 508ms to be exact.

How did we figure that out…  here we go..  TMR0 is setup to use the internal clock as the source to increment – the clock is 31Khz, however we have to figure in FOSC/4 – to get the instruction cycle.  So the instruction speed is 7.75Khz.

That means the counter increments every – 0.000129032258 seconds.  That is a little bit faster than we want.  So, by place in a prescale value of 16, we increase the increment to every – .002064516128  seconds.  0.000129032258 x 16 = .002064516128 now we multiple that by 255 and come to – 526.45161264ms

We are a little off – but it not the math – Setting the Reference Clock to output – we can see where we are messing up. 

PIC10F322 -XC8 - Timer0 Module

So, instead of the 31Khz, that we expected the CPU to run at – it is really, around 32.268Khz. 

Working back though off that number.. we get to – 505.7642256ms

PIC10F322 -XC8 - Timer0 Module

The additional jitter, can be accounted for because of the how we are checking for the Over Flow Flag and time it takes to enter the function that changes the pin.  If you want to get it right on the money – you have to go with ASM.  We are close enough.. 

Which reminds me of a joke… a scientist and engineer see a person they are attracted to at the end of a hallway. The scientist takes half-steps and after a few steps, says.. I can never be close enough.  The engineer on the other hand, sees the same problem and says… I can get close enough for all practical purposes. 

Here is the code.. 

/*
 * File:   timer0_example.c
 * Author: Jamie Starling
 *
 * Created on August 14, 2020, 10:02 AM
 */


#include "includes/10F322_deviceconfig.h"
#include "includes/tmr0.h"
#include "includes/gpio.h"
#include "includes/osc.h"

void main(void) {
    
    cpuFreqSelect(KHZ31);
    enableTMR0(TRM0_MODE_TIMER,TRM0_PRESCALE_16,TRM0_EDGE_LOW_HIGH,TRM0_INTERRUPT_DISABLED);
    pinMode (0,OUTPUT);
    
    while(1)
    {
        if(tmr0_Check_Interrupt_Flag())
        {
            digitalToggle(0);
            tmr0_Clear_Interrupt_Flag();
        }
    }
    
}