#include <avr/io.h>
#include <avr/interrupt.h>
#define LEDOFF do { PORTB &= ~(1<<PB1); } while(0)
#define LEDON do { PORTB |= 1<<PB1; } while(0)
int
main(void)
{
/* Setup: ATtiny2313 with LED on PB1 and scope on PB3 */
DDRB |= 1<<DDB1 | 1<<DDB3; // debug LED and PWM output
/* pwm frequency (fixed at 50% duty cycle) */
OCR1A = 0x1000;
/* enable timer compare match interrupt for visible feedback */
TIMSK |= 1<<OCIE1A;
// Set phase-and-frequency-correct PWM on timer 1:
// Mode WGM13 WGM12(CTC1) WGM11(PWM11) WGM10(PWM10) Timer/Counter Mode of Operation TOP Update of OCR1x at TOV1 Flag Set on
// 9 1 0 0 1 PWM, Phase and Frequency Correct OCR1A BOTTOM BOTTOM
TCCR1A |= 1<<WGM10;
TCCR1B |= 1<<WGM13;
// Setup inverted PWM on OC1A (PB3)
// COM1A1/COM1B1 COM1A0/COM1B0 Description
// 0 0 Normal port operation, OC1A/OC1B disconnected.
// 0 1 WGM13=0: Normal port operation, OC1A/OC1B disconnected. WGM13=1: Toggle OC1A on Compare Match, OC1B reserved.
// 1 0 Clear OC1A/OC1B on Compare Match when up- counting. Set OC1A/OC1B on Compare Match when downcounting.
// 1 1 Set OC1A/OC1B on Compare Match when up- counting. Clear OC1A/OC1B on Compare Match when downcounting.
// bug? output stays low all the time, timer
// is running though (LED blinks):
TCCR1A |= 1<<COM1A1 | 1<<COM1A0;
// the following on the other hand does work, LED blinks
// and square wave on PB3
//TCCR1A |= 1<<COM1A0;
sei();
/* enable timer clock */
TCCR1B |= 1<<CS10;
for (;;);
}
ISR(TIMER1_COMPA_vect)
{
/* toggle the LED every 256 compare matches */
static unsigned char foo;
static unsigned char on;
if (!++foo) {
if (on) LEDON;
else LEDOFF;
on = !on;
}
}