Timer 1 Interrupt Example for the dsPIC30F4011

// This is a Timer 1 interrupt example for the dsPIC30F4011.
// Timer 1 is a 16-bit Type A timer.
// It toggles an LED on pin RD0 8 times a second.
// Written by Ted Burke - last updated 5-12-2010

#include <p30f4011.h>

// Clock speed = 7.5MHz x 16, i.e. 30 MIPS

// Watchdog timer off

// Function prototype for Timer 1 interrupt service routine
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void);

int main()
	// Configure RD0 (pin 23) as digital output for the LED
	LATD = 0;
	TRISD = 0b11111110;

	// Configure Timer 1
	// In this example, I'm setting PR1 and TCKPS for 8Hz
	T1CON = 0;            // Clear the Timer 1 configuration
	TMR1 = 0;             // Reset Timer 1 counter
	PR1 = 14648;          // Set the Timer 1 period (max 65535)
	T1CONbits.TCS = 0;    // Select internal clock (Fosc/4)
	T1CONbits.TCKPS = 3;  // Prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256)
	_T1IP = 1;            // Set the Timer 1 interrupt priority
	_T1IF = 0;            // Clear the Timer 1 interrupt flag
	_T1IE = 1;            // Enable Timer 1 interrupt
	T1CONbits.TON = 1;    // Turn on Timer 1

	// Lock the main function here in an empty loop and let
	// the Timer 1 interrupt service routine do all the work.

	return 0;

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

	// Toggle LED
	if (_LATD0) _LATD0 = 0; else _LATD0 = 1;
This entry was posted in PIC and tagged , , , , , , . Bookmark the permalink.

5 Responses to Timer 1 Interrupt Example for the dsPIC30F4011

  1. Shyamal says:

    This is my program though I am not able to run it on MPLAB debugger. The interrupt service routine is never being called by the program in the debugging mode. Do you too have the same problem with the debugger or am I doing something wrong?


    /* Timer1 program 
    Note: Fosc = 20MHz   */
    // FOSC
    #pragma config FPR = HS                 // Primary Oscillator Mode (HS)
    #pragma config FOS = PRI                // Oscillator Source (Primary Oscillator)
    #pragma config FCKSMEN = CSW_FSCM_OFF   // Clock Switching and Monitor (Sw Disabled, Mon Disabled)
    // FWDT
    #pragma config FWPSB = WDTPSB_16        // WDT Prescaler B (1:16)
    #pragma config FWPSA = WDTPSA_512       // WDT Prescaler A (1:512)
    #pragma config WDT = WDT_OFF            // Watchdog Timer (Disabled)
    // FBORPOR
    #pragma config FPWRT = PWRT_OFF         // POR Timer Value (Timer Disabled)
    #pragma config BODENV = BORV27          // Brown Out Voltage (2.7V)
    #pragma config BOREN = PBOR_ON          // PBOR Enable (Enabled)
    #pragma config LPOL = PWMxL_ACT_HI      // Low-side PWM Output Polarity (Active High)
    #pragma config HPOL = PWMxH_ACT_HI      // High-side PWM Output Polarity (Active High)
    #pragma config PWMPIN = RST_IOPIN       // PWM Output Pin Reset (Control with PORT/TRIS regs)
    #pragma config MCLRE = MCLR_DIS         // Master Clear Enable (Disabled)
    // FGS
    #pragma config GWRP = GWRP_OFF          // General Code Segment Write Protect (Disabled)
    #pragma config GCP = CODE_PROT_OFF      // General Segment Code Protection (Disabled)
    // FICD
    #pragma config ICS = ICS_PGD            // Comm Channel Select (Use PGC/EMUC and PGD/EMUD)
    int t =0;
    extern void timer1_init();
    /* UART2 Receive Interrupt Service Routine */ /*
    void __attribute__((interrupt, no_auto_psv)) _U2RXInterrupt(void) 
       if(U2STAbits.OERR == 1) {
         U2STAbits.OERR = 0; // Clear Overrun Error to receive data
    void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
    	IFS0bits.T1IF = 0;
    int main()
    //OSCCON: Oscillator Control Register
    OSCCONbits.COSC = 0b11;		//11 = Primary oscillator ,oscillator status bit
    OSCCONbits.POST = 0b00;		//00 = Oscillator postscaler does not alter clock
    OSCCONbits.OSWEN = 0; 	//Does not initiate clock switch
    OSCCONbits.LPOSCEN = 0;		//0 = LP oscillator is disabled
    // Configure all 4 port D pins as digital outputs
        TRISD = 0;
    timer1_init(); //initializing timer registers
    TMR1 = 0x0000;
    T1CONbits.TON = 1; 		//Starts the timer
    			// Toggle LED on RD1
        		_LATD1 = 1 - _LATD1;
    return 0;
    void timer1_init()
    // T1CON initialization
    	T1CONbits.TSIDL = 0; 	//0 = Continue timer operation in Idle mode
    	T1CONbits.TGATE =0;		//0 = Gated time accumulation disabled
    	T1CONbits.TCKPS = 0b00;	//00 = 1:1 prescale value
    	T1CONbits.TCS = 0;		//0 = Internal clock (FOSC/4)
    // For more info visit Ch-12 of dsPIC30F family reference manual
    	PR1 = 0xFFFF; 
    	/* Timer interrupt frequency
         * f = _XTAL_FREQ / 4*prescaler*Timer1 resolution
         * f = 20000000 / 4*1*65536 = 76.29 Hz */
     	IEC0bits.T1IE = 1;    // Enable Timer 1 interrupt
    • batchloaf says:

      Hi Shyamal,

      I actually don’t use the debugger very often and I’ve never used it for interrupts, so I’m not sure whether it should be working or not. Have you tried running my example code in the debugger to see if that works. I’ve tried it on a real chip and it definitely works there, so if it doesn’t work on the debugger, I guess that might be a clue as to why your program’s not working.

      A few other ideas:

      1.) Are you using the XC16 compiler? If so, you usually don’t include “p30f4011.h” directly – you just include “xc.h” and the compiler pulls in the correct header file itself.

      2.) Could you try setting PR1 to a different value (i.e. not equal to 0xFFFF). I’m not sure if it will make any difference, but I just think it might be worth trying in case this is a special value which behaves differently to other values.

      3.) The way you’re setting the configuration bits is different than how I’m doing it (and you’re setting more of them than I did in my example), so I’m not sure whether those values will work right in the debugger. For example, are you using the right oscillator setting for the debugger? To confirm that the program is actually running (even if the interrupt isn’t working), could you add something into your while(1) loop in the main function to switch a pin on and off or something? That would let you see if the program is actually running or not.


  2. shyamal890 says:

    Thanks a lot Ted, tested it today on real hardware and it worked perfectly. The problem indeed was with MPLAB SIM , you were right. I wonder why they have given this simulator?!! They must do some work on it…

    By the way was working on UART code and wanted to stick to scanf for receiving data from hyperterminal| (RS232). Unfortunately found that XC16 compiler skips the command line altogether if there is no reply from hyperterminal within a given period of time.

    I found that one needs to modify the compiler’s read() command that is being called by scanf function. I was looking for proper documentation on the same, indeed am still googling the issue. Can you please point me to the link if you are aware of it?

    • batchloaf says:

      Hi Shyamal,

      That’s great that it’s working on the real chip. It’s a pity you couldn’t get it to work on the simulator, but as long as it’s working on the real chip, I suppose that’s ok.

      When I use the UART on the dsPIC, I use printf extensively, but I never use scanf. I can’t remember why I began avoiding it – perhaps it was the same problem you’re having. Anyway, what I’m in the habit of doing is reading the incoming bytes straight from the UART registers and parsing the incoming text with my own code. It’s long-winded, but it allows fine-grained control and avoids the dsPIC getting hung by scanf waiting for text that may never arrive.

      You can see an example of the type of code I use for receiving text here:


      It’s not pretty, but it should give you some idea of the way I receive text (in this case 4-digit decimal numbers transmitted as plain text by the PC). The basic mechanism is to build in somewhere in your main loop a check for the value of “U1STAbits.URXDA” (UART 1 Status register, the UART receive “data available” flag bit). This bit gets set to 1 whenever a new character has been received by the UART. Each byte (character of text) which arrives is stored in the U1RXREG register, where it waits to be collected. Whenever you read the character from U1RXREG, the U1STAbits.URXDA bit is automatically reset to 0.

      Here’s a really short example:

      char c;
          if (U1STAbits.URXDA == 1)
              c = U1RXREG;
              if (c == 'y') _LATD0 = 1;
              if (c == 'n') _LATD0 = 0;

      Whenever a ‘y’ character is received, RD0 will be set high. Whenever an ‘n’ character is received, RD0 will be set low.

      Hope that helps!


    • sanju says:

      hai syam,..
      iam having a problemin dspic interrupts..can u say why?..
      i writen a code for timer 1 and timer3, with an lcd display, if both timer starts with isr, dspic hangs, indipently i can run any of one, and counter increment is displayed in lcd, what is the priority?..i want a high prior for timer1 and lower to t3, i writen code like :

      void InitTMR3()
      T3CON = 0x0020;
      TMR3 = 0;
      PR3 = 0x7777;
      _T3IP = 1; ?????????????????????????????/
      _T3IF = 0;
      _T3IE = 1;
      T3CONbits.TON = 1;
      void ti_init()
      T1CON = 0; // Clear the Timer 1 configuration
      TMR1 = 0; // Reset Timer 1 counter
      PR1 = microhundred*2;
      T1CONbits.TCS = 0;
      T1CONbits.TCKPS = 0;
      _T1IP = 7; // interrupt priority????????????????????????????
      _T1IF = 0; // Clear the Timer 1 interrupt flag
      _T1IE = 1; // Enable Timer 1 interrupt
      T1CONbits.TON = 1; // Turn on Timer 1
      which is having high prior in this code?
      pls correct me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s