gbngfdbjn

This commit is contained in:
Lea 2023-11-24 10:08:01 +01:00
parent ec293656e2
commit 2ffe83f951
Signed by: Lea
GPG key ID: 1BAFFE8347019C42

109
main.c
View file

@ -6,43 +6,100 @@
#include <stdbool.h> #include <stdbool.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
volatile int debounce_int2 = 10; volatile uint16_t tick_timer_start = 0xffff - (F_CPU / 1024 / 1000);
volatile int debounce_int3 = 10; volatile bool speaker_disabled = true;
ISR(INT2_vect) { uint16_t notes[][3] = {
if (debounce_int2) return; { 1000, 200, 30 },
debounce_int2 = 100; { 1200, 200, 30 },
OCR0A++; { 1500, 200, 30 },
{ 1600, 200, 30 },
{ 1500, 200, 30 },
{ 1200, 100, 10 },
{ 1000, 300, 100 },
};
void ADC_Setup() {
// AVCC with external capacitor at AREF pin
ADMUX = _BV(REFS0);
// Enable ADC, set prescaler to 8tick_timer_start
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS1);
// Perform dummy readout
ADCSRA |= _BV(ADSC); // Start conversion
while (ADCSRA & _BV(ADSC)); // Await result
(void) ADCW; // Read out result
} }
ISR(INT3_vect) { uint16_t ADC_Read(uint8_t channel) {
if (debounce_int3) return; // Select chosen channel
debounce_int3 = 100; ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
OCR0A--; // Start conversion
ADCSRA |= _BV(ADSC);
// Await the result
while (ADCSRA & _BV(ADSC));
// Although it doesn't appear to be documented, ADCW holds the covnersion result
return ADCW;
} }
ISR(TIMER0_COMPA_vect) { uint16_t ADC_Read_Avg(uint8_t channel, uint8_t samples) {
PORTF ^= 0b00000001; uint32_t sum = 0;
for (int i = 0; i < samples; i++) {
sum += ADC_Read(channel);
}
return (uint16_t)(sum / samples);
}
void TIMER_Setup() {
TCCR1B |= _BV(CS10) | _BV(CS12); // clk/1024
// Set the TOIE (Timer Overflow Interrupt Enable) bit
// on TIMSK1 (Timer 1 Interrupt Mask Register).
TIMSK1 |= _BV(TOIE1);
// Sets the current timer value
TCNT1 = tick_timer_start;
// Enable interrupts
sei();
}
// ISR is used to handle interrupts. TIMER1_OVF_vect
// is triggered whenever timer 1 (16 bit) overflows.
ISR(TIMER1_OVF_vect) {
TCNT1 = tick_timer_start;
PORTB ^= 0b10000000;
if (speaker_disabled) PORTK &= 0b11111110;
else PORTK ^= 0b00000001;
}
void play_note(uint16_t freq, uint8_t delay, uint8_t delay_silence) {
speaker_disabled = false;
tick_timer_start = 0xffff - (F_CPU / freq / 1000);
for (int i = 0; i < delay; i++) _delay_ms(1);
speaker_disabled = true;
for (int i = 0; i < delay_silence; i++) _delay_ms(1);
} }
void main() { void main() {
DDRF = 0b00000001; DDRK = 0b00000001;
DDRD = 0b00000000; PORTB = 0b10000000; // Start with LED enabled
PORTD |= 0b00001100;
// EIMSK controls which ports can trigger interrupts ADC_Setup();
EIMSK |= _BV(INT2) | _BV(INT3); TIMER_Setup();
// Trigger on falling edge on INT2 and INT3
EICRA |= _BV(ISC21) | _BV(ISC31);
TCCR0B |= _BV(CS00) | _BV(CS02); // clk/1024 long rows = sizeof(notes) / sizeof(notes[0]);
TIMSK0 |= _BV(OCIE0A);
OCR0A = 0;
sei(); while (true) {
for (int i = 0; i < rows; i++) {
play_note(notes[i][0], notes[i][1], notes[i][2]);
}
while(1) { //uint16_t value = ADC_Read_Avg(0, 4);
_delay_ms(10); //speaker_disabled = value == 0;
OCR0A++; //if (value < 100) value = 100; // Anything lower than this causes issues
//tick_timer_start = 0xffff - (F_CPU / value / 1000);
} }
} }