PIC16F877A Timer0 calculation - Page 1
Forum section: electronics / general

author: djsb
author_rank: Super Contributor
timestamp: August 06, 2021, 04:01:57 pm
content: I have this code on a PIC16F877ACode:/** File: Main.c* Author: David J S Briscoe* PIC: 16F877A w/Ext OSC @ 8MHz, 5v* Program: 06_Timer_Delay* Compiler: XC8 (v2.31, MPLAX X v5.45)* Program Version: 1.0*** Program Description: This Program uses Timer 0 for the delay between an LED* turning on and off.*** Hardware Description: An LED is connected via a 220R resistor to pin RD1 and* a switch is connected to pin RB0 with a 10k pullup resistor.** Created Aug 6th, 2021* NOTE: To open the header file for this PIC hold down CTRL and left click on* a statement E.G CTRL + LEFT click on TRISDbits.TRISD1 = 0; will open the 16f877a.h header file.*//********************************************************************************Includes and defines******************************************************************************/#define _XTAL_FREQ 8000000#define BUTTON PORTBbits.RB0 // pushbutton#include "16F877A_Internal.h"/******************************************************************************** Function: void initMain()** Returns: Nothing** Description: Contains initializations for main** Usage: initMain()******************************************************************************/void initMain(){////////////////////////// Configure Ports//////////////////////// Set PIN D1 as outputTRISDbits.TRISD1 = 0;// Set PIN B0 as inputTRISBbits.TRISB0 = 1;//Flash LED to show alive.RD1 = 1;__delay_ms(1000);RD1 = 0;////////////////////////// Configure Timer0//////////////////////// Select counter mode//OPTION_REGbits.T0CS = 1;// Select timer modeOPTION_REGbits.T0CS = 0;// Assign Prescaler to TIMER0OPTION_REGbits.PSA = 1;OPTION_REGbits.PS = 0b111; // prescale = 256// -> increment TMR0 every ? us// Change as needed.// Zero TimerTMR0 = 0;// Enable timer0 interrupts and clear interrupt flagINTCONbits.TMR0IE = 1;INTCONbits.TMR0IF = 0;}/**************************************************************************//******************************************************************************** Function: Main** Returns: Nothing** Description: Program entry point******************************************************************************/void main(void) {initMain();// define and initialize variables// Flashing @ 7.6345 KHz// On for 123.5uS off for// 7.5us. Duty cycle 94.277% ON// 5.723% OFF, PERIOD 130.98uSfor(;;)// Delay 500 ms? for 500KHz clock yes. NOT for an 8MHz clock that i'm using.{TMR0 = 0;while( TMR0 < (int)(500/2.048)){RD1 = 1;}// Turn off LEDRD1 = 0;}}These are the measurements on my scope (as described in the code comments above).LED Flashing @ 7.6345 KHzOn for 123.5uSOff for 7.5us.Duty cycle 94.277% ON5.723% OFF,PERIOD 130.98uSThe clock frequency is 8MHz.i'm trying to understand how these values are arrived at. I've had a look for an explanation that I can understand, but every one I've tried has left me more confused. Can someone help me figure this out? Thanks.

author: jpanhalt
author_rank: Super Contributor
timestamp: August 06, 2021, 05:10:54 pm
content: The instruction clock is Fosc/4 = 500 ns (0.5 us). Your on and off times per calculation fit that limit for resolution.The sum of on and off = 131 us = 7.633.6 kHz (calculated).Your measurements are off a little. Sources of error are your scope and oscillator frequency. Neither is exact.

author: djsb
author_rank: Super Contributor
timestamp: August 06, 2021, 06:18:24 pm
content: So it's 0.5uS x 244 (0.000122s)? How is the off time calculated? Thanks.

author: jpanhalt
author_rank: Super Contributor
timestamp: August 06, 2021, 06:43:47 pm
content: With all mid-range PICs, it take 4 system clock oscillations for an instruction cycle. Thus, the time for an instruction cycle is 4 x 1/Fosc. Then, 1/(8x10^6) = 125 ns, and 4x125 ns = 0.5 us.Timer0 counts on every instruction cycle and rolls over to zero after 255 (i.e., 8-bit). If you want an interrupt for less than 256 x 0.5 us, just pre-load a number in the timer.Aside from that, its just multiplication, addition/subtraction , and sometimes counting (e.g., if you want 1 interrupt for every 5 rollovers).