1 /* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Joerg Wunsch 7 * ---------------------------------------------------------------------------- 8 * 9 * Simple AVR demonstration. Controls a LED that can be directly 10 * connected from OC1/OC1A to GND. The brightness of the LED is 11 * controlled with the PWM. After each period of the PWM, the PWM 12 * value is either incremented or decremented, that's all. 13 * 14 * $Id: demo.c 1637 2008-03-17 21:49:41Z joerg_wunsch $ 15 */ 16 17 #include <inttypes.h> 18 #include <avr/io.h> 19 #include <avr/interrupt.h> 20 #include <avr/sleep.h> 21 22 #include "iocompat.h" /* Note [1] */ 23 24 enum { UP, DOWN }; 25 ISR(TIMER1_OVF_vect)26ISR (TIMER1_OVF_vect) /* Note [2] */ 27 { 28 static uint16_t pwm; /* Note [3] */ 29 static uint8_t direction; 30 31 switch (direction) /* Note [4] */ 32 { 33 case UP: 34 if (++pwm == TIMER1_TOP) 35 direction = DOWN; 36 break; 37 38 case DOWN: 39 if (--pwm == 0) 40 direction = UP; 41 break; 42 } 43 44 OCR = pwm; /* Note [5] */ 45 } 46 47 void ioinit(void)48ioinit (void) /* Note [6] */ 49 { 50 /* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */ 51 TCCR1A = TIMER1_PWM_INIT; 52 /* 53 * Start timer 1. 54 * 55 * NB: TCCR1A and TCCR1B could actually be the same register, so 56 * take care to not clobber it. 57 */ 58 TCCR1B |= TIMER1_CLOCKSOURCE; 59 /* 60 * Run any device-dependent timer 1 setup hook if present. 61 */ 62 #if defined(TIMER1_SETUP_HOOK) 63 TIMER1_SETUP_HOOK(); 64 #endif 65 66 /* Set PWM value to 0. */ 67 OCR = 0; 68 69 /* Enable OC1 as output. */ 70 DDROC = _BV (OC1); 71 72 /* Enable timer 1 overflow interrupt. */ 73 TIMSK = _BV (TOIE1); 74 sei (); 75 } 76 77 int main(void)78main (void) 79 { 80 81 ioinit (); 82 83 /* loop forever, the interrupts are doing the rest */ 84 85 for (;;) /* Note [7] */ 86 sleep_mode(); 87 88 return (0); 89 } 90