Vous êtes sur la page 1sur 4

Simple Timer 1 interrupt example for the dsPIC30F4011

Posted on April 12, 2012by batchloaf


This is a minimal example of a Timer 1 interrupt in a dsPIC30F4011 program. I
compiled it with Microchips C30 compiler. The main loop of the program simply
flashes an LED on RD0 (pin23) at approximately 2 Hz. Meanwhile, Timer 1 triggers
an interrupt every 500 ms which toggles a second LED on RD1 (pin 18).
To change how often the Timer 1 interrrupt service routine (ISR) gets called, you
can either modify the value in the Timer 1 period register, PR1, or you can alter the
Timer 1 prescaler value , T1CONbits.TCKPS (the main clock can be divided by 1, 8,
64 or 256).
In this example, the following line specifies that the internal fast RC oscillator
should be used and that the PLL multiplier should be used to scale it up to 16 times
its normal value.
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16 x 7.5MHz = 120MHz
Since the dsPIC performs one instruction every four clock cycles, when Fosc is 120
Mhz, the chip is running at 30 MIPS (million instructions per second) and, most
importantly, the instruction cycle, Tcy = 33.33 ns.
In this example, the Timer 1 prescaler is set to 256, which means that the timebase
TMR1 increments (increases by 1) every 256 x Tcy seconds.
Timer 1 tick = 256 x 33.33ns = 8.533 us
PR1 then needs to be set to the number of ticks between interrupts.
Interrupt interval = PR1 x prescaler x Tcy = 58594 x 256 x 33.33 ns = 500 ms
Thats pretty much it, so heres the source code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Simple Timer 1 interrupt example for dsPIC30F4011
// Written by Ted Burke - Last updated 12-4-2012
//

#include <libpic30.h>
#include <p30f4011.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(MCLR_DIS); // Disable reset pin

// Function prototype for timer 1 ISR
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void);

int main()
{
// Configure RD0 and RD1 as outputs
TRISD = 0b1100;

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Configure Timer 1.
// PR1 and TCKPS are set to call interrupt every 500ms.
// Period = PR1 * prescaler * Tcy = 58594 * 256 * 33.33ns = 500ms
T1CON = 0; // Clear Timer 1 configuration
T1CONbits.TCKPS = 3; // Set timer 1 prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256)
PR1 = 58594; // Set Timer 1 period (max value is 65535)
_T1IP = 1; // Set Timer 1 interrupt priority
_T1IF = 0; // Clear Timer 1 interrupt flag
_T1IE = 1; // Enable Timer 1 interrupt
T1CONbits.TON = 1; // Turn on Timer 1

// Main loop just flashes LED on RD0 at approx 2Hz.
// Meanwhile, Timer 1 ISR flashes LED on RD1 at 1Hz.
while(1)
{
_LATD0 = 1;
__delay32(7500000);
_LATD0 = 0;
__delay32(7500000);
}

41
42
43
44
45
46
47
48
49
50
51
52
53
54
return 0;
}

// Timer 1 interrupt service routine toggles LED on RD1
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
{
// Clear Timer 1 interrupt flag
_T1IF = 0;

// Toggle LED on RD1
_LATD1 = 1 - _LATD1;

Vous aimerez peut-être aussi