/* timer_demo.c Use of timer0 to produce a regular event (in this example, the toggling of an output pin). This happens while we also do "something else". With a 16MHz clock, timer0 increments every 1024/16000000 seconds, which is 64 usec. The SIG_OVERFLOW0 interrupt occurs every (1024*256)/16000000 = 0.0164 seconds. On each interrupt, the routine increments an internal counter ("counter"). When this counter reaches 61, the interrupt routine toggles PB0 and resets "counter". 61 * 0.0164 sec = 1 sec (approximately). So - the LED attached to PB0 flashes at a frequency of 0.5 Hz. Note that this approach allows "something else" to take an arbitrary amount of time. */ #include #include #include #include #include "oulib.h" #include "oulib_serial_buffered.h" volatile unsigned char counter; // the only reason char is used is because it is an 8-bit value volatile unsigned char duty; // the duty cycle (out of 256) ISR(TIMER0_OVF_vect) { counter+=1; if(counter >= 255) { if(duty >= 0x24) { PORTB |= 1; } counter = 0; }; if(counter >= duty) { PORTB &= ~1; }; }; int main(void) { int c; // character // Initialize I/O DDRB = 0x01; PORTB = 0; FILE* fp0 = serial_init_buffered(0, 9600, 10, 10); // enable serial // Initialize counter/duty counter = 0; duty = 0; // Overflow Interrupt occurs every (256^2)/16000000 = .004 seconds (245 Hz) timer0_config(TIMER0_NOPRE); // Enable the timer interrupt timer0_enable(); // Enable global interrupts sei(); printf("READY FOR PWM!!!\n\r"); while(1) { if(serial_buffered_input_waiting(fp0)) { c = getchar(); switch(c) { case 'u' : duty = duty++; printf("%x\n\r",duty); break; case 'd' : duty = duty--; printf("%x\n\r",duty); break; }; }; }; return(0); }