Files
AVR_Learning/Make AVR Examples/Chapter09_Introduction-to-Timer-Counter-Hardware/amRadio/amRadio.c

82 lines
2.7 KiB
C

/*
Plays a simple tune, broadcasts it in the AM radio band.
*/
// ------- Preamble -------- //
#include <avr/io.h> /* Defines pins, ports, etc */
#include <util/delay.h> /* Functions to waste time */
#include <avr/power.h>
#include <avr/interrupt.h>
#include "pinDefines.h"
#include "scale16.h"
#define COUNTER_VALUE 3 /* determines carrier frequency */
// From f = f_cpu / ( 2* N* (1 + OCRnx) )
// Good values for the AM band from 2 to 6: pick one that's clear
// Divide by two b/c we're toggling on or off each loop;
// a full cycle of the carrier takes two loops.
// 8Mhz / (2 * 1 * (1+2)) = 1333 kHz
// 8Mhz / (2 * 1 * (1+3)) = 1000 kHz
// 8Mhz / (2 * 1 * (1+4)) = 800 kHz
// 8Mhz / (2 * 1 * (1+5)) = 670 kHz
// 8Mhz / (2 * 1 * (1+6)) = 570 kHz
// 8Mhz / (2 * 1 * (1+7)) = 500 kHz
static inline void initTimer0(void) {
TCCR0A |= (1 << WGM01); /* CTC mode */
TCCR0A |= (1 << COM0B0); /* Toggles pin each time through */
TCCR0B |= (1 << CS00); /* Clock at CPU frequency, ~8MHz */
OCR0A = COUNTER_VALUE; /* carrier frequency */
}
static inline void initTimer1(void) {
TCCR1B |= (1 << WGM12); /* CTC mode */
TCCR1B |= (1 << CS11); /* Clock at CPU/8 frequency, ~1MHz */
TIMSK1 |= (1 << OCIE1A); /* enable output compare interrupt */
}
ISR(TIMER1_COMPA_vect) { /* ISR for audio-rate Timer 1 */
ANTENNA_DDR ^= (1 << ANTENNA); /* toggle carrier on and off */
}
static inline void transmitBeep(uint16_t pitch, uint16_t duration) {
OCR1A = pitch; /* set pitch for timer1 */
sei(); /* turn on interrupts */
do {
_delay_ms(1); /* delay for pitch cycles */
duration--;
} while (duration > 0);
cli(); /* and disable ISR so that it stops toggling */
ANTENNA_DDR |= (1 << ANTENNA); /* back on full carrier */
}
int main(void) {
// -------- Inits --------- //
clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */
initTimer0();
initTimer1();
// ------ Event loop ------ //
while (1) {
transmitBeep(E3, 200);
_delay_ms(100);
transmitBeep(E3, 200);
_delay_ms(200);
transmitBeep(E3, 200);
_delay_ms(200);
transmitBeep(C3, 200);
transmitBeep(E3, 200);
_delay_ms(200);
transmitBeep(G3, 400);
_delay_ms(500);
transmitBeep(G2, 400);
_delay_ms(2500);
} /* End event loop */
return 0; /* This line is never reached */
}