I have some code that I based, in part, on the interrupt code in Deans tutorial on timers. I noted recently that I mistakenly omitted the following header from the code:
#include
But the program still seems to work. I am glad that it does work (or at least seems to work), but should that be the case?
In case it is relevant, here is the code:
/* PWM_Servo_ver2 Using PWM to operate HiTec HS-311 Servo Author: R. P. Hintze Date: 16Jan10 Program to operate cause Servo to rotate to extreme positions and 0 degrees Version 2 Input on P5 thru push button (with debouncing amd interrupt) Pushing button toggles thru sero settings OFF->FCCW->Center->FCW->OFF Uses an Atmega8 MCU */ //Set includes #include#include // need "--std=c99" //Declare and initialize some variables typedef unsigned char u8; #define KEY_PIN PINC #define PC0 0 #define PC1 1 #define PC2 2 #define PC3 3 #define PC4 4 #define PC5 5 enum { OFF, FCCW, CENTER, FCW };//for servo_command; //OFF->0 //FCCW->1 //CENTER->2 //FCW->3 u8 key_state;//state of key 1->pressed (active low) u8 key_press;//detects key press 1->key pressed u8 key_press_mask;//mask to clear key_press u8 servo_command;//holds setting for action servo should take u8 ct0 = 0xFF; //holder to counter debounce states u8 ct1 = 0xFF; //holder to counter debounce states //Declare and define functions void init_timer1(void);//sets up timer parameters other than OCR1A and CS12:0 void init_timer2(void);//sets up timer parameters other than OCR1A and CS12:0 u8 need_action(u8 key_mask);//determine if key has been pressed //Start main function int main (void) { //Configure input and output pins DDRB |= (1 << 1); //pin PB1(OC1A) set to output PORTB &= ~(1 << 1); //initialize as low DDRC = 0; //pins PC3, PC4 and PC5 set as input PORTC = (1 << PC5) | (1 << PC4) | (1 << PC3); //enable internal pull-up resistors DDRC |= (1 << PC2); //pin PC2 set to output PORTC &= ~(1 << PC2); //initialize as low //Initialize timer1 (OCR1A and CS12:0 not set at this point) and timer2 init_timer1(); init_timer2(); //Set up interrupt on timer2 TIMSK |= (1 << OCIE2); // Enable CTC interrupt on timer2 sei(); // Enable global interrupts while (1) //loop to determine if button attached to PC5 pressed and if pressed advance servo_command and trake requisite action { if(need_action((1<<PC5))) //has PC5 been pressed? { servo_command++; //advance servo_command servo_command &= ~(0xFC);//if servo_command ->4, resets servo_command to 0 }//end if(need_action...) switch(servo_command) { case OFF: TCCR1B &= ~(1 << CS10);//servo is OFF; clear timer PORTC |= (1 << PC2); //turn on LED break; case FCCW: TCCR1B |= (1 << CS10);//servo is on; set up timer1 with no prescaler (Internal RC Oscillator at 1Mhz) PORTC &= ~(1 << PC2); //turn off LED OCR1A = 0x258; //600 equates into a duty cycle of approx 3% (rotate to -90 degress (left)) break; case CENTER: OCR1A = 0x5DC; //1500 equates into a duty cycle of approx 7.5% (rotate to 0 degress (center)) break; case FCW: OCR1A = 0x960; //2400 equates into a duty cycle of approx 7.5% (rotate to 0 degress (center)) break; } //end swtich } //end while } //end main /*********************************/ /*********************************/ //Declare and define functions /*********************************/ void init_timer1(void)//set all Timer parameters other than OCRA1 and CS12:0 (which are set in main based on input) { TCCR1A |= (1 << COM1A1);//set OC1A (PB1) to clear on Compare Match, and set at BOTTOM (non-iverting mode) TCCR1A |= (1 << WGM11);// Configure timer1 for Fast PWM mode (Mode 14) TCCR1B |= ((1 << WGM12) | (1 << WGM13)); ICR1 = 0x4E20; ////Set frequency of timer1 and PWM; 19,999 give a count of 20,000 (TOP +1) which equates into a frequency of 50hz }//end init_timer1() /*********************************/ void init_timer2(void)//set all Timer parameters other than OCRA1 and CS12:0 (which are set in main based on input) { TCCR2 |= (1 << WGM21);// Configure timer2 in CTC mode (non-PWM) TCCR2 |= ((1 << CS22) | (1 << CS21));//set up timer2 with 256 prescaler (Internal RC Oscillator at 1Mhz) OCR2 = 0x27; ////Set caomapre to 39, equates to slightly more than 10ms at prescale of 256 }//end init_timer2() /*********************************/ u8 need_action(u8 key_mask)//determine if key has been pressed { ATOMIC_BLOCK(ATOMIC_FORCEON) { key_press_mask = key_mask;//mask to clear key_press key_mask &= key_state & key_press; //read key; has key been pressed? key_press &= ~key_press_mask; //reset key_toggle }//end ATOMIC_BLOCK(ATOMIC_FORCEON) return key_mask; }//end need_action() /*********************************/ ISR( TIMER2_COMP_vect ) { u8 i; i = key_state ^ ~KEY_PIN; // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state key_press |= key_state & i; // 0->1: key press detect }//end ISR()