RSS Daily tech news
  • Room-temperature quantum breakthrough freezes motion without cooling
    ETH Zurich scientists have levitated a tower of three nano glass spheres using optical tweezers, suppressing almost all classical motion to observe quantum zero-point fluctuations with unprecedented precision. Achieving 92% quantum purity at room temperature, a feat usually requiring near absolute zero, they have opened the door to advanced quantum sensors without costly cooling.
  • Tiny gold “super atoms” could spark a quantum revolution
    Scientists have found that microscopic gold clusters can act like the world’s most accurate quantum systems, while being far easier to scale up. With tunable spin properties and mass production potential, they could transform quantum computing and sensing.
  • Scientists unveil bioplastic that degrades at room temperature, and outperforms petroplastics
    Plastic pollution is a mounting global issue, but scientists at Washington University in St. Louis have taken a bold step forward by creating a new bioplastic inspired by the structure of leaves. Their innovation, LEAFF, enhances strength, functionality, and biodegradability by utilizing cellulose nanofibers, outperforming even traditional plastics. It degrades at room temperature, can be […]
  • Building electronics that don’t die: Columbia's breakthrough at CERN
    Deep beneath the Swiss-French border, the Large Hadron Collider unleashes staggering amounts of energy and radiation—enough to fry most electronics. Enter a team of Columbia engineers, who built ultra-rugged, radiation-resistant chips that now play a pivotal role in capturing data from subatomic particle collisions. These custom-designed ADCs not only survive the hostile environment inside CERN […]
  • Digital twins are reinventing clean energy — but there’s a catch
    Researchers are exploring AI-powered digital twins as a game-changing tool to accelerate the clean energy transition. These digital models simulate and optimize real-world energy systems like wind, solar, geothermal, hydro, and biomass. But while they hold immense promise for improving efficiency and sustainability, the technology is still riddled with challenges—from environmental variability and degraded equipment […]
  • Quantum tunneling mystery solved after 100 years—and it involves a surprise collision
    For the first time ever, scientists have watched electrons perform a bizarre quantum feat: tunneling through atomic barriers by not just slipping through, but doubling back and slamming into the nucleus mid-tunnel. This surprising finding, led by POSTECH and Max Planck physicists, redefines our understanding of quantum tunneling—a process that powers everything from the sun […]

PIC16F877A Timer1 Tutorial

by Florius
Educational slide introducing the Timer1 module of the PIC16F877A microcontroller. The left side shows a stopwatch icon and the question “Alarm, Timers, how does it work?”, while the right side features the microcontroller image and MPLAB X IDE logo. The tutorial focuses on Timer1's role in timing, delays, and interrupts.

The Timer1 module is a 16-bit timer/counter within most PIC MCU devices. Timer1 can increment up to a value of 65535 before it overflows back to zero. Because the timer is built into an 8-bit device, the 16-bit timer register is broken into two 8-bit registers (TMR1L and TMR1H) and increments in a similar way to an 8-bit timer with 8-bit prescaler. Timer1 has other built-in features that make it very useful for many different applications, such as the following:

  • 16-bit timer/counter register pair (TMR1H:TMR1L)
  • Programmable internal or external clock source
  • Prescaler
  • Interrupt on overflow
  • Wake-up on overflow (external clock, Asynchronous mode only)

The Timer1 module has 2 distinct modes in which it can operate:

  1. Timer Mode: In Timer mode, Timer1 functions as a timer. It increments its value at a specified rate based on the clock source it’s configured to use. In this mode, the input clock to the timer is Fosc/4 Once Timer1 reaches its maximum value (which depends on the number of bits it has), it overflows and generates an interrupt (or trigger an action, depending on the configuration). This overflow can be used to measure time intervals, generate periodic events, or trigger specific actions after a certain period.
  2. Counter Mode: In Counter mode, Timer1 functions as an external event counter. It counts the number of external pulses received on its input pin (usually RC1/T1OSI/CCP2 or RC0/T1OSO/T1CKI) and increments its value accordingly. This mode is often used for applications where you want to count external events such as pulses from an external sensor, encoder, or any other source that generates discrete events.

The microcontroller series also have other timers, which can be used differently and separately from Timer1. I refer to the Timers in general, Timer0 and Timer2 for their respective information.

1. Timer Mode

We will focus on the timer mode, even though the other mode might be just as interesting for certain applications. However, I will briefly mention how to configure the counter mode as well thruoghout the text. The other three important registers are:

RegistersDescription
T1CONThis register is used to configure Timer 1’s prescaler, clock source, etc.
TMR1LThis registers hold the lower 2 digits of the counter, from which the timer starts counting toward its maximum value.
TMR1HThis registers hold the higher 2 digits of the counter, from which the timer starts counting toward its maximum value.
Diagram of the T1CON register from the PIC16F877A microcontroller, displaying bit fields for configuring Timer1. Includes settings like TMR1ON (enable), TMR1CS (clock source select), T1CKPS (prescaler), and T1SYNC (synchronization). These control how Timer1 operates for accurate timing and delay generation.

T1CKPS1:T1CKPS0:Timer1 Input Clock Prescale Select bits
11 = 1:8 prescale value
10 = 1:4 prescale value
01 = 1:2 prescale value
00 = 1:1 prescale value

T1OSCEN: Timer1 Oscillator Enable Control bit
1-Oscillator is enabled
0-Oscillator is shut-off (the oscillator inverter is turned off to eliminate power drain)

T1SYNC: N/A for this timer in timer mode.de

TMR1CS: Timer1 Clock Source Select bit
1-External clock from pin RC0/T1OSO/T1CKI (on the rising edge) – Don’t confuse this with Crystal oscillator on CLKIN/CLKOUT pins
0-Internal clock (FOSC/4)

TMR1ON: Timer1 On bit
1-Enables Timer1
0-Stops Timer1

The prescaler is not as large as for Timer0 or Timer2, with 2 bits; it has a max value of 1:8. To enable and configure Timer 1, the remaining bits have to be set correctly. T1OSCEN = 1; Furthermore, to enable the internal clock (which could be the crystal oscillator/4), the follow bit has to be set: TMR1CS = 0; Finally, the timer1 has to be enabled through the TMR1ON = 0 bit.

1.1 TMR1H & TMR1L Registers

The other important part of the timer mode is to set the timer to the correct delay that you want it to be. This is best explained in my overview tutorial on Timers. Nonetheless, I will give a short recap here as well. Timer 1 requires you to make a Start number, from which it counts towards its maximum where it overflows. This start number can be calculated using the formula described below. In the case of Timer1, which is a 16-bit timer, the starting number will most likely be 2 bytes (or a 4-hexadecimal number), which needs to be split up in 2 separate registers, TMR1H (for the higher byte) and TMR1L (for the lower byte). Again, in my tutorial on timers, I provide a detailed example on exactly how to calculate it.

Annotated equation used to calculate the starting value for a timer register (TMRx) in microcontroller applications. It shows how to derive the value based on required delay time, prescaler setting, system clock frequency, and timer size (e.g., 8-bit or 16-bit). Each parameter is labeled with its role in the formula.

2. Timer Interrupt

To enable the interrupt, we need to enable the global and peripheral interrupts in the INTCON register. This is done by setting both GIE = 1 and PEIE = 1.

Diagram of the INTCON register from the PIC16F877A microcontroller, showing updated bit fields for managing interrupts. Includes global (GIE), peripheral (PEIE), timer (T0IE, T0IF), and external interrupt controls (INTE, INTF), providing fine-grained control over interrupt behavior in embedded applications.

Lastly, the TMR1 overflow flag enabler is situated in the PIE1 register and needs to be set to TMR1IE = 1; The TMR1 overflow flag itself is situated in the PIR1 register, and has to be cleared every time an interrupt happened. This can be done by setting TMR1IF = 0;

3. Programming code in MPLAB

Assume we have a PIC16F877A microcontroller with a 20 MHz crystal oscillator. We want to create a timer of 100 ms using Timer1. With the calculations from my tutorial, we can find that the prescaler is set to 8, and the TMR1 starts at 3036. In hexadecimals that is 0x0BDC. Hence, 0x0B goes into TMR1H, while 0xDC goes into TMR1L

				
					#include <pic16f877a.h>
#include <xc.h>
    
#define XTAL_FREQ 20000000  // 20MHz external crystal oscillator frequency

// Configuration bits 
#pragma config FOSC = HS    // High-Speed Crystal oscillator
#pragma config WDTE = OFF   // Watchdog Timer disabled
#pragma config PWRTE = OFF  // Power-up Timer disabled
#pragma config BOREN = OFF  // Brown-out Reset disabled
#pragma config LVP = OFF    // Low-Voltage Programming disabled
#pragma config CPD = OFF    // Data memory code protection off
#pragma config WRT = OFF    // Flash Program Memory Write protection off
#pragma config CP = OFF     // Flash Program Memory Code protection off

// Function prototype
void interrupt timer1_isr();

void main()
{
    TRISDbits.TRISD0 = 0; // Configure RD0 (LED) as output
    
    // Timer1 - T1CON Register Configuration
    T1CONbits.T1CKPS1 = 1; // Set prescaler to 1:8
    T1CONbits.T1CKPS0 = 1;
    T1CONbits.TMR1CS = 0; // Use internal clock (Fosc/4)
    T1CONbits.TMR1ON = 1; // Start Timer1
    
    // TimerCounter register
    TMR1H = 0x0B; // Load the time value (0x0BDC) for 100ms delay
    TMR1L = 0xDC;
    
    //INTCON Register & PIE1 Register configuration
    TMR1IE = 1; // Enable Timer1 overflow interrupt bit in PIE1 register
    GIE = 1; // Enable Global Interrupt
    PEIE = 1; // Enable the Peripheral Interrupt
    
    while (1)
    {
        // No need to toggle PORTD; only control RD1
    }
}


// Timer1 interrupt service routine
void interrupt timer_isr()
{
    if (TMR1IF == 1)
    {
        RD0 = !RD0; // Toggle RD0 (LED) state
        TMR1H = 0x0B; // Load the timer value for the next 100ms delay
        TMR1L = 0xDC;
        TMR1IF = 0; // Clear Timer1 interrupt flag in PIR1 register
    }
}
				
			
Florius

Hi, welcome to my website. I am writing about my previous studies, work & research related topics and other interests. I hope you enjoy reading it and that you learned something new.

More Posts

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.