| 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 |
} |
} |