Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

University of Portsmouth, Department of Electronic and Computer Engineering

ENG531 – Microcontrollers and Programmable Logic - Lecture 10

Branislav Vuksanovic

One more way to load Timer 0


EXAMPLE:

Calculate and load Timer 0 to achieve 20 ms delay assuming 20 MHz clock.

SOLUTION:

Using the standard approach explained in the previous lecture, we have:


4 4
Tic    0.2 106 s  0.2  s
f osc 20 10 6

Td 20 ms 20 103
Clock ticks needed for 20 ms delay: N     100 103  0x186 A
Tic 0.2  s 0.2 10 6

Timer 0 register value = 0xFFFF + 1 – 0x186A = -0x86A1 i.e. not achievable without prescaler.

Td 20 ms 20 103
For the prescaler set to 64: N    1562.5  1562  0x061A
64  Tic 64  0.2  s 64  0.2 106

Timer 0 register value = 0xFFFF + 1 – 0x061A = 0xF9E6

Appropriate Timer 0 loading is therefore: TMR0H = 0xF9;


TMR0L = 0xE6;
Providing prescaler is properly set to 1:64 using: T0CON = 0x05;

Same Timer 0 loading can be achieved with the following 2 lines:

TMR0H = ~(1562/256);
TMR0L = -(1562%256);

proof: 1562/256 = 6.101 rounded down to 6 so


~(1562/256) = ~(6) = ~(0000 0110) = 1111 1001 = 0xF9

1562%256 = 1562 – 6*256 = 26 so


-(1562%256) = -(26) = -(0001 1010) = 1110 0101 + 1 = 1110 0110 = 0xE6

Therefore
TMR0H = 0xF9; is identical to TMR0H = ~(1562/256);
TMR0L = 0xE6; is identical to TMR0L = -(1562%256);
University of Portsmouth, Department of Electronic and Computer Engineering
ENG531 – Microcontrollers and Programmable Logic - Lecture 10

Branislav Vuksanovic

EXAMPLE:

Use Timer 0 interrupt to generate pulse like signal from figure bellow. Your program should also make use
of external interrupt to stop and start generation of this signal.

20 us 20 ms 20 us

SOLUTION:

// Program to generate pulse width modulated signal on RB1 pin using Timer 0 interrupt.
// Short delay (20 us) is used for "pulse on" part, long delay (20 ms) for "pulse off" part.
// External interrupt (RB0 pin) is used to enable or disable pulse generation.

#include <p18f252.h>

#define pulse_pin PORTBbits.RB1

// high priority ISR - services Timer 2 interrupt


// if external interrupt occurs – disable PWM signal generation
void interrupt high_isr(void)
{
INTCONbits.INT0IF = 0;
if(INTCONbits.TMR0IE == 1)
INTCONbits.TMR0IE = 0; // dissable Timer 0 interrupt
else
INTCONbits.TMR0IE = 1; // enable Timer 0 interrupt
}

// low priority ISR - services Timer 0 interrupt


void low_priority interrupt low_isr(void)
{
if(pulse_pin == 0)
{
INTCONbits.TMR0IF = 0;
T0CON = 0x88; // prescaler OFF
TMR0H = ~(100/256);
TMR0L = -(100%256);
pulse_pin = 1;
}
else
{
INTCONbits.TMR0IF = 0;
T0CON = 0x85; // prescaler ON, set to 1:64
TMR0H = ~(1562/256);
TMR0L = -(1562%256);
pulse_pin = 0;
}
}
University of Portsmouth, Department of Electronic and Computer Engineering
ENG531 – Microcontrollers and Programmable Logic - Lecture 10

Branislav Vuksanovic

void main(void)
{
TRISB = 0x01; // RB1 is output, but RB0 is input
TRISC = 0; // port C is output

// Timer 0 interrupt configuration


INTCONbits.TMR0IE = 1; // enable Timer 0 interrupt
INTCON2bits.TMR0IP = 0; // configure TMR0 interrupt to low priority

// External interrupt 0 configuration


INTCONbits.INT0IE = 1; // enable INT0 interrupt
INTCON2bits.INTEDG2 = 1; // interrupt on rising edge
// note - INT0 is always high priority - no need to set it

// Global interrup enabling and configuration


RCONbits.IPEN = 1; // enable interrupt priority scheme
INTCONbits.GIEH = 1; // enable all high priority interrupts
INTCONbits.GIEL = 1; // enable all low priority interrupts

T0CON = 0x88; // initialise and start Timer 0


while(1)
{
PORTC++; // do other jobs while waiting
// for the interrupt
}
}

You might also like