Added code
This commit is contained in:
parent
80d55f25b0
commit
2d4a3fba3e
151
lab_2/main.c
Normal file
151
lab_2/main.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* GccApplication1.c
|
||||||
|
*
|
||||||
|
* Created: 10/8/2019 2:07:13 PM
|
||||||
|
* Author : lenfesty
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
uint8_t play_flag = 0;
|
||||||
|
uint8_t button_flag = 0;
|
||||||
|
|
||||||
|
ISR(INT0_vect) {
|
||||||
|
// Disable interrupts
|
||||||
|
cli();
|
||||||
|
|
||||||
|
// Notify of button press
|
||||||
|
button_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pin Definitions:
|
||||||
|
* PB2 -> OC0A output
|
||||||
|
* PB3 -> OC1A output
|
||||||
|
* PB0 -> Switch Input
|
||||||
|
*/
|
||||||
|
void gpio_init() {
|
||||||
|
// Piezo Out
|
||||||
|
DDRB |= (1 << DDB2) | (1 << DDB3);
|
||||||
|
|
||||||
|
// Switch Input Setup
|
||||||
|
DDRD &= ~(1 << DDD2);
|
||||||
|
PORTD |= (1 << PORTD2);
|
||||||
|
|
||||||
|
// Configure Interrupt Stuff
|
||||||
|
// Set falling edge for INT0
|
||||||
|
MCUCR |= (1 << ISC01) | (0 << ISC00);
|
||||||
|
|
||||||
|
// Enable INT0
|
||||||
|
GIMSK |= (1 << INT0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_init( ) {
|
||||||
|
/* --- Timer 0 (8 bit) --- */
|
||||||
|
// Set Compare mode A to toggle, and waveform generation mode to CTC
|
||||||
|
TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00);
|
||||||
|
// Nothing else relevant here, without setting notes
|
||||||
|
|
||||||
|
/* --- Timer 1 (16 bit) --- */
|
||||||
|
// Set compare mode A to toggle
|
||||||
|
TCCR1A = (0 << COM1A1) | (1 << COM1A0);
|
||||||
|
// Set waveform gen mode to CTC
|
||||||
|
TCCR1B = (1 << WGM12);
|
||||||
|
}
|
||||||
|
|
||||||
|
void play_beat() {
|
||||||
|
static uint8_t duration_left[2] = {0};
|
||||||
|
static uint16_t song_location[2] = {0};
|
||||||
|
|
||||||
|
// If at end of song, restart
|
||||||
|
if (song_location[0] == SPEAKER0_LEN) {
|
||||||
|
song_location[0] = 0;
|
||||||
|
song_location[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set note
|
||||||
|
for (uint8_t speaker = 0; speaker < 2; speaker++) {
|
||||||
|
if (duration_left[speaker] == 0) {
|
||||||
|
// Move to next note
|
||||||
|
// Read in next note from program memory
|
||||||
|
uint16_t beat;
|
||||||
|
beat_t* p_beat;
|
||||||
|
|
||||||
|
// Select from correct song
|
||||||
|
if (speaker == 0) {
|
||||||
|
beat = pgm_read_word((PGM_P*) &song_speaker0[song_location[speaker]]);
|
||||||
|
} else {
|
||||||
|
beat = pgm_read_word((PGM_P*) &song_speaker1[song_location[speaker]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_beat = (beat_t*) &beat;
|
||||||
|
|
||||||
|
|
||||||
|
// Set duration left after this beat
|
||||||
|
duration_left[speaker] = p_beat->duration - 1;
|
||||||
|
// Increment song location for next note
|
||||||
|
song_location[speaker]++;
|
||||||
|
|
||||||
|
// actually set note
|
||||||
|
play_note(*p_beat, speaker);
|
||||||
|
} else {
|
||||||
|
// Keep handling current note
|
||||||
|
// do nothing, it is set correctly
|
||||||
|
duration_left[speaker]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_delay_ms(BEAT_LENGTH * (1 - REST_FRACTION)); // Play note
|
||||||
|
|
||||||
|
// Rest note if at the end of the interval
|
||||||
|
for (uint8_t speaker = 0; speaker < 2; speaker++) {
|
||||||
|
if (duration_left[speaker] == 0) {
|
||||||
|
// End of note, pause here
|
||||||
|
beat_t beat = {
|
||||||
|
.note = rest,
|
||||||
|
.duration = 0,
|
||||||
|
.octave = 0, // octave doesn't matter, its a rest
|
||||||
|
};
|
||||||
|
play_note(beat, speaker);
|
||||||
|
} else {
|
||||||
|
// Note does not end, change nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_delay_ms(BEAT_LENGTH * REST_FRACTION);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
gpio_init();
|
||||||
|
timer_init();
|
||||||
|
|
||||||
|
sei();
|
||||||
|
|
||||||
|
/* Replace with your application code */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (play_flag) {
|
||||||
|
play_beat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button_flag) {
|
||||||
|
button_flag = 0;
|
||||||
|
|
||||||
|
beat_t beat = {
|
||||||
|
.note = rest,
|
||||||
|
};
|
||||||
|
play_note(beat, 0);
|
||||||
|
play_note(beat, 1);
|
||||||
|
_delay_ms(100);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bit_is_clear(PIND, PIND2) && (play_flag == 0)) {
|
||||||
|
cli();
|
||||||
|
play_flag = 1;
|
||||||
|
_delay_ms(100);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
lab_2/main.h
Normal file
42
lab_2/main.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef MAIN_H_
|
||||||
|
#define MAIN_H_
|
||||||
|
|
||||||
|
#define F_CPU 8000000UL
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include "notes.h"
|
||||||
|
|
||||||
|
#define TEMPO (120 * 4) // Tempo of song (bpm)
|
||||||
|
#define REST_FRACTION 0.3 // Fraction of the beat to stay silent between notes
|
||||||
|
#define BEAT_LENGTH 60000 / TEMPO // Length of each note (ms)
|
||||||
|
|
||||||
|
|
||||||
|
#define OCTAVES 2
|
||||||
|
#define NOTES_PER_OCTAVE 12
|
||||||
|
#define SPEAKER0_LEN 38
|
||||||
|
#define SPEAKER1_LEN 96
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
a = 0, b, c, d, e, f, g,
|
||||||
|
A, C, D, F, G,
|
||||||
|
rest
|
||||||
|
} note_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
note_t note;
|
||||||
|
uint8_t duration:7;
|
||||||
|
uint8_t octave:1;
|
||||||
|
} beat_t;
|
||||||
|
|
||||||
|
extern const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE];
|
||||||
|
|
||||||
|
extern const beat_t PROGMEM song_speaker0[SPEAKER0_LEN];
|
||||||
|
extern const beat_t PROGMEM song_speaker1[SPEAKER1_LEN];
|
||||||
|
|
||||||
|
void play_note(beat_t note, uint8_t speaker);
|
||||||
|
|
||||||
|
#endif
|
58
lab_2/notes.c
Normal file
58
lab_2/notes.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
|
||||||
|
{ 140, 62, 118, 106, 94, 88, 79, 64, 112, 98, , 37 }, // 1024 prescaler octave 2
|
||||||
|
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
|
||||||
|
{ 35, 31, 59, 53, 47, 44, 39, 32, 56, 49, 41, 37 }, // 1024 prescaler octave 2
|
||||||
|
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void play_note(beat_t note, uint8_t speaker) {
|
||||||
|
if (note.note == rest) { // Handle special rest case
|
||||||
|
if (speaker == 0) {
|
||||||
|
// Turn off timer clock source, disabling
|
||||||
|
TCCR0B &= ~( (1 << CS02) | (1 << CS01) | (1 << CS00));
|
||||||
|
// Turn off output pin
|
||||||
|
PORTB &= ~(1 << PORTB2);
|
||||||
|
} else {
|
||||||
|
// turn off timer clock source, disabling
|
||||||
|
TCCR1B &= ~( (1 << CS12) | (1 << CS11) | (1 << CS10));
|
||||||
|
// turn off output pin
|
||||||
|
PORTB &= ~(1 << PORTB3);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Set up so note changes always happen after rests,
|
||||||
|
// so we know CS[2:0] = 0
|
||||||
|
// See pages 86 and 114
|
||||||
|
uint8_t prescale = 0;
|
||||||
|
if (note.octave == 0) {
|
||||||
|
// set prescaler to 1024
|
||||||
|
prescale = 4;
|
||||||
|
} else {
|
||||||
|
// set prescaler to 64
|
||||||
|
prescale = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get value to write to output compare
|
||||||
|
uint8_t period = pgm_read_byte((PGM_P*) ¬es[note.octave][note.note]);
|
||||||
|
|
||||||
|
// Actually set clock source
|
||||||
|
if (speaker == 0) {
|
||||||
|
TCNT0 = 0; // reset counter
|
||||||
|
OCR0A = period; // set note period
|
||||||
|
TCCR0B |= prescale;
|
||||||
|
} else {
|
||||||
|
TCNT1H = 0; // reset counter
|
||||||
|
TCNT1L = 0;
|
||||||
|
OCR1AL = period; // set note period
|
||||||
|
OCR1AH = period >> 8;
|
||||||
|
TCCR1B |= prescale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
lab_2/song.c
Normal file
141
lab_2/song.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
const beat_t PROGMEM song_speaker0[SPEAKER0_LEN] = {
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 6, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = g, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = f, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = d, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
{.note = c, .duration = 4, .octave = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const beat_t PROGMEM song_speaker1[SPEAKER1_LEN] = {
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = A, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = A, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 3, .octave = 1 },
|
||||||
|
{.note = e, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = A, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = A, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = A, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 2, .octave = 1 },
|
||||||
|
{.note = g, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = d, .duration = 2, .octave = 1 },
|
||||||
|
{.note = d, .duration = 1, .octave = 1 },
|
||||||
|
{.note = a, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 2, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = c, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 2, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1 },
|
||||||
|
{.note = f, .duration = 1, .octave = 1 },
|
||||||
|
{.note = e, .duration = 1, .octave = 1},
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user