/* * scheduler.c * * Description: * This is a demonstartion of a simple scheduler for CCS PICC compiler. * * Author: Martin Dubuc * http://members.rogers.com/martin.dubuc/Robotics/Tips.html * * Creation date: November 18, 2003 */ #include <16f877.h> /* Microcontroller configuration bits */ #fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP #ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */ #device *=16 /* Allow RAM to expand beyond 256 bytes */ /* Set the clock speed to 20 MHz. */ #use delay(clock=20000000) /* Directive for RS-232 interface */ #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) /* Pin definitions */ #define LED0 PIN_B4 #define LED1 PIN_B5 #define LED2 PIN_B6 #define LED3 PIN_B7 // Scheduler variables unsigned char t1mS = 0, t10mS = 0, t100mS = 0; unsigned char t1mS0 = 0, t10mS0 = 0, // Watchdog timer kicker t10mS1 = 0, // LED blinking (quarter second on/off) t100mS0 = 0, // LED blinking (half second on/off) tS0 = 0, // LED blinking (1 second on/off) tS1 = 0; // LED blinking (2 second on/off) /* Function prototypes */ /* Public interface */ void main(void); void init_pins(void); void init_timers(void); void init(void); void timer1_isr(void); /* Scheduler implementation */ /* Init hardware pins: Set up the TRIS and set the pins to their * default values. */ void init_pins(void) { /* Set up the various pins in/out */ set_tris_b(0b00000000); /* B4 to B7 are outputs. Rest are not used. */ /* Set initial condition for servos */ output_low(LED0); output_low(LED1); output_low(LED2); output_low(LED3); } /* init_pins */ /* Module initialization. Initialize pins, global variables, * interrupts and timers. */ void init(void) { init_pins(); init_timers(); // Enable Timer1 interrupts enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL); printf("Scheduler demo\r\n"); } /* init */ /* Initialize the Timer1 timer. */ void init_timers(void) { // Configure Timer1 // Timer1 used for fixed 1 ms clock interrupt // For 20 MHz, base/4, prescaler/8 here and ~/625 in ISR setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); } /* init_timers */ /* This is the main control loop. */ void main(void) { init(); for ( ; ; ) { if (t1mS0) { /* 1 ms have elapsed */ t1mS0 = 0; } if (t10mS0) { /* 10 ms have elapsed */ /* Kick the watchdog. */ RESTART_WDT(); } if (t10mS1 == 25) { /* 250 ms has elapsed. */ t10mS1 = 0; /* Toggle LED */ output_bit(LED0, !input(LED0)); } if (t100mS0 == 5) { /* 500 ms has elapsed. */ t100mS0 = 0; /* Toggle LED */ output_bit(LED1, !input(LED1)); } if (tS0) { /* 1 second has elapsed */ tS0 = 0; /* Toggle LED */ output_bit(LED2, !input(LED2)); } if (tS1 == 2) { /* 2 seconds have elapsed */ tS1 = 0; /* Toggle LED */ output_bit(LED3, !input(LED3)); } } } /* main */ #int_timer1 void timer1_isr(void) { // Clock interrupt service routine. Invoked on Timer1 interrupt. set_timer1(-625); // For 20 MHz/625 => 1 ms - latency t1mS0++; if (t1mS++ == 9) { // 10 ms t1mS = 0; t10mS0++; t10mS1++; if (t10mS++ == 9) { // 100 ms t10mS = 0; t100mS0++; if (t100mS++ == 9) { // 1 s t100mS = 0; tS0++; tS1++; } } } } /* timer1_isr */