1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Simple AVR demonstration. Controls a LED that can be directly
* connected from OC1/OC1A to GND. The brightness of the LED is
* controlled with the PWM. After each period of the PWM, the PWM
* value is either incremented or decremented, that's all.
*
* $Id: demo.c,v 1.4 2004/07/21 21:03:07 joerg_wunsch Exp $
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#if defined(__AVR_AT90S2313__)
# 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__)
# 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
enum { UP, DOWN };
volatile uint16_t pwm; /* Note [1] */
volatile uint8_t direction;
SIGNAL (SIG_OVERFLOW1) /* Note [2] */
{
switch (direction) /* Note [3] */
{
case UP:
if (++pwm == 1023)
direction = DOWN;
break;
case DOWN:
if (--pwm == 0)
direction = UP;
break;
}
OCR = pwm; /* Note [4] */
}
void
ioinit (void) /* Note [5] */
{
/* tmr1 is 10-bit PWM */
TCCR1A = _BV (PWM10) | _BV (PWM11) | _BV (XCOM11);
/* tmr1 running on full MCU clock */
TCCR1B = _BV (CS10);
/* set PWM value to 0 */
OCR = 0;
/* enable OC1 and PB2 as output */
DDROC = _BV (OC1);
timer_enable_int (_BV (TOIE1));
/* enable interrupts */
sei ();
}
int
main (void)
{
ioinit ();
/* loop forever, the interrupts are doing the rest */
for (;;) /* Note [6] */
;
return (0);
}
|