Объясните работу программы!
- Войдите на сайт для отправки комментариев
Пнд, 18/12/2017 - 00:28
Здравствуйте.Недавно начал осваивать ардуино и столкнулся с первыми трудностями.Есть код,который проигрывает wave файл все работает,но хотелось бы понять как это происходит.Вот собственно код:
#include <stdint.h> #include <avr/interrupt.h> #include <avr/io.h> #include <avr/pgmspace.h> #include "sounddata.h" #define SAMPLE_RATE 8000 int ledPin = 13; int speakerPin = 11; volatile uint16_t sample; byte lastSample; // This is called at 8000 Hz to load the next sample. ISR(TIMER1_COMPA_vect) { if (sample >= sounddata_length) { if (sample == sounddata_length + lastSample) { stopPlayback(); } else { // Ramp down to zero to reduce the click at the end of playback. OCR2A = sounddata_length + lastSample - sample; } } else { OCR2A = pgm_read_byte(&sounddata_data[sample]); } ++sample; } void startPlayback() { pinMode(speakerPin, OUTPUT); // Set up Timer 2 to do pulse width modulation on the speaker // pin. // Use internal clock (datasheet p.160) ASSR &= ~(_BV(EXCLK) | _BV(AS2)); // Set fast PWM mode (p.157) TCCR2A |= _BV(WGM21) | _BV(WGM20); TCCR2B &= ~_BV(WGM22); // Do non-inverting PWM on pin OC2A (p.155) // On the Arduino this is pin 11. TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0); TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0)); // No prescaler (p.158) TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // Set initial pulse width to the first sample. OCR2A = pgm_read_byte(&sounddata_data[0]); // Set up Timer 1 to send a sample every interrupt. cli(); // Set CTC mode (Clear Timer on Compare Match) (p.133) // Have to set OCR1A *after*, otherwise it gets reset to 0! TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12); TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10)); // No prescaler (p.134) TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10); // Set the compare register (OCR1A). // OCR1A is a 16-bit register, so we have to do this with // interrupts disabled to be safe. OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000 // Enable interrupt when TCNT1 == OCR1A (p.136) TIMSK1 |= _BV(OCIE1A); lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]); sample = 0; sei(); } void stopPlayback() { // Disable playback per-sample interrupt. TIMSK1 &= ~_BV(OCIE1A); // Disable the per-sample timer completely. TCCR1B &= ~_BV(CS10); // Disable the PWM timer. TCCR2B &= ~_BV(CS10); digitalWrite(speakerPin, LOW); } void setup() { pinMode(ledPin, OUTPUT); startPlayback(); } void loop() { //if (HIGH == digitalRead(12)) //{ // for (int i=0; i <= 255; i++) // { pinMode(ledPin, OUTPUT); // } // if (HIGH == digitalRead(12)) startPlayback(); //} }
Понятно,что используются прерывания по таймеру,но для чего - нет мыслей.Также интересно:почему динамик воспроизводит только на 11 пине,на остальных молчит(переменную speakerPin я естественно меняю ).
Также интересно:почему динамик воспроизводит только на 11 пине,на остальных молчит(переменную speakerPin я естественно меняю ).
А Вы сами-то код читали? Комментарий в строках 44-45 ни на какие мысли не навёл?
Не заметил.. Может есть литература или какая нибудь статья по этой теме?куда копать?
Забыл упомянуть,что wave файл хранится в файле sounddata.h в шестнадцатеричном виде