Millisecond timer for state machine using Timer 1 interrupt

//
// Timer interrupt example for dsPIC30F4011
// Written by Ted Burke - 16-11-2016
//
// This is a simple state machine with four
// states. The current state is indicated
// using two LEDs. All state transitions are
// triggered by time elapsed since the
// previous state transition, as measured
// using a millisecond counter which is
// incremented every 30000 instruction cycles
// by a Timer 1 interrupt service routine.
//

#include <xc.h>
#include <libpic30.h>

_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Clock speed = 7.5MHz x 16, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

// These variables must be global because they
// are accessed by the main function and the ISR
int state = 1;        // state variable
int milliseconds = 0; // millisecond counter

// Timer 1 interrupt service routine (ISR)
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
{
    _T1IF = 0;      // Clear Timer 1 interrupt flag
    milliseconds++; // Increment the millisecond counter
}

// This function resets the millisecond counter and changes state
void change_state(int n)
{
    milliseconds = 0;
    state = n;
}

int main()
{
    // Configure digital I/O
    TRISD = 0b1100; // RD0 and RD1 are the two LEDs
    
    // Configure Timer 1
    PR1 = 30000;          // Set the Timer 1 period to 1 ms (30000 * Tcy)
    TMR1 = 0;             // Reset Timer 1 counter
    _T1IE = 1;            // Enable Timer 1 interrupt
    T1CONbits.TCKPS = 0;  // Prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256)
    T1CONbits.TON = 1;    // Turn on Timer 1
    
    while(1)
    {
        if (state == 1)
        {
            // Display state on LEDs
            _LATD0 = 0;
            _LATD1 = 0;
            
            // Change state?
            if (milliseconds >= 500) change_state(2);
        }
        else if (state == 2)
        {
            // Display state on LEDs
            _LATD0 = 1;
            _LATD1 = 0;
            
            // Change state?
            if (milliseconds >= 500) change_state(3);
        }
        else if (state == 3)
        {
            // Display state on LEDs
            _LATD0 = 0;
            _LATD1 = 1;
            
            // Change state?
            if (milliseconds >= 2000) change_state(4);
        }
        else if (state == 4)
        {
            // Display state on LEDs
            _LATD0 = 1;
            _LATD1 = 1;
            
            // Change state?
            if (milliseconds >= 3000) change_state(1);
        }
    }
        
    return 0;
}
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s