17 |
#include <inttypes.h> |
#include <inttypes.h> |
18 |
#include <avr/io.h> |
#include <avr/io.h> |
19 |
#include <avr/interrupt.h> |
#include <avr/interrupt.h> |
20 |
|
#include <avr/sleep.h> |
21 |
|
|
22 |
#if defined(__AVR_AT90S2313__) |
#include "iocompat.h" /* Note [1] */ |
|
# define OC1 PB3 |
|
|
# define OCR OCR1 |
|
|
# define DDROC DDRB |
|
|
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) |
|
|
# define OC1 PB1 |
|
|
# define DDROC DDRB |
|
|
# define OCR OCR1 |
|
|
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \ |
|
|
defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \ |
|
|
defined(__AVR_ATmega163__) |
|
|
# define OC1 PD5 |
|
|
# define DDROC DDRD |
|
|
# define OCR OCR1A |
|
|
#elif defined(__AVR_ATmega8__) |
|
|
# define OC1 PB1 |
|
|
# define DDROC DDRB |
|
|
# define OCR OCR1A |
|
|
# define PWM10 WGM10 |
|
|
# define PWM11 WGM11 |
|
|
#elif defined(__AVR_ATmega32__) || defined(__AVR_ATmega16__) |
|
|
# define OC1 PD5 |
|
|
# define DDROC DDRD |
|
|
# define OCR OCR1A |
|
|
# define PWM10 WGM10 |
|
|
# define PWM11 WGM11 |
|
|
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) |
|
|
# define OC1 PB5 |
|
|
# define DDROC DDRB |
|
|
# define OCR OCR1A |
|
|
# define PWM10 WGM10 |
|
|
# define PWM11 WGM11 |
|
|
#else |
|
|
# error "Don't know what kind of MCU you are compiling for" |
|
|
#endif |
|
|
|
|
|
#if defined(COM11) |
|
|
# define XCOM11 COM11 |
|
|
#elif defined(COM1A1) |
|
|
# define XCOM11 COM1A1 |
|
|
#else |
|
|
# error "need either COM1A1 or COM11" |
|
|
#endif |
|
23 |
|
|
24 |
enum { UP, DOWN }; |
enum { UP, DOWN }; |
25 |
|
|
26 |
volatile uint16_t pwm; /* Note [1] */ |
volatile uint16_t pwm; /* Note [2] */ |
27 |
volatile uint8_t direction; |
volatile uint8_t direction; |
28 |
|
|
29 |
ISR (TIMER1_OVF_vect) /* Note [2] */ |
ISR (TIMER1_OVF_vect) /* Note [3] */ |
30 |
{ |
{ |
31 |
switch (direction) /* Note [3] */ |
switch (direction) /* Note [4] */ |
32 |
{ |
{ |
33 |
case UP: |
case UP: |
34 |
if (++pwm == 1023) |
if (++pwm == 1023) |
41 |
break; |
break; |
42 |
} |
} |
43 |
|
|
44 |
OCR = pwm; /* Note [4] */ |
OCR = pwm; /* Note [5] */ |
45 |
} |
} |
46 |
|
|
47 |
void |
void |
48 |
ioinit (void) /* Note [5] */ |
ioinit (void) /* Note [6] */ |
49 |
{ |
{ |
50 |
/* tmr1 is 10-bit PWM */ |
/* tmr1 is 10-bit PWM */ |
51 |
TCCR1A = _BV (PWM10) | _BV (PWM11) | _BV (XCOM11); |
TCCR1A = _BV (WGM10) | _BV (WGM11) | _BV (COM1A1); |
52 |
|
|
53 |
/* tmr1 running on full MCU clock */ |
/* tmr1 running on full MCU clock */ |
54 |
TCCR1B = _BV (CS10); |
TCCR1B = _BV (CS10); |
56 |
/* set PWM value to 0 */ |
/* set PWM value to 0 */ |
57 |
OCR = 0; |
OCR = 0; |
58 |
|
|
59 |
/* enable OC1 and PB2 as output */ |
/* enable OC1 as output */ |
60 |
DDROC = _BV (OC1); |
DDROC = _BV (OC1); |
61 |
|
|
62 |
/* enable interrupts */ |
/* enable timer 1 overflow interrupt */ |
63 |
TIMSK = _BV (TOIE1); |
TIMSK = _BV (TOIE1); |
64 |
sei (); |
sei (); |
65 |
} |
} |
67 |
int |
int |
68 |
main (void) |
main (void) |
69 |
{ |
{ |
70 |
|
|
71 |
ioinit (); |
ioinit (); |
72 |
|
|
73 |
/* loop forever, the interrupts are doing the rest */ |
/* loop forever, the interrupts are doing the rest */ |
74 |
|
|
75 |
for (;;) /* Note [6] */ |
for (;;) /* Note [7] */ |
76 |
; |
sleep_mode(); |
77 |
|
|
78 |
return (0); |
return (0); |
79 |
} |
} |