Ivanoff-iv писал(а):когда ацп оцифрует следующий семпл, нулевой байт из массива уже будет на флешке.
не всё так просто))
а что мы делаем в обработчике прерывания ?
ISR(TIMER2_COMPA_vect) {
sbi(ADCSRA, ADSC); // start ADC sample
while (bit_is_set(ADCSRA, ADSC)); // wait until ADSC bit goes low = new sample ready
recByteCount++; // increment sample counter
bufByteCount++;
if (bufByteCount == 386 && bufWrite == 0) {
bufByteCount = 0;
bufWrite = 1;
} else if (bufByteCount == 386 & bufWrite == 1) {
bufByteCount = 0;
bufWrite = 0;
}
if (bufWrite == 0) {
buf00[bufByteCount] = ADCH;
}
if (bufWrite == 1) {
buf01[bufByteCount] = ADCH;
}
// запуск преобразования ADC
//ADCSRA
//1... .... ADEN - 1- вкл ADC. (0-ADC не потребляет мощности)
//.1.. .... ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
//..1. .... ADFR - 1- режим Непрерывного Преобразования.
//...1 .... ADIF - 1- флаг завершения преобразования
// -сброс программно.
// -для прерывания очищается аппаратно.
//.... 1... ADIE - 1- Разрешение прерывания
//.... .1.. ADPS2 - предделитель
//.... ..1. ADPS1 - предделитель
//.... ...1 ADPS0 - предделитель
sbi(ADCSRA, ADSC); // установить бит ADSC в регистре ADCSRA
это можно записать так (что одно и то же):
ADCSRA |= 0b01000000;
//.1.. .... ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
while (bit_is_set(ADCSRA, ADSC)); //
//ждём окончания преобразования ADC...
//.1.. .... ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
а интересно... сколько времени у нас занимает одно преобразование ?
для частоты преобразования ADC = 250.000 Hz время одного преобразования занимает ~57 микросекунды
при этом мы считали что обработчик прерывания работает с частотой 8000 Hz
Но в Ардуино настройки немного другие...
в Ардуино частота преобразования ADC = 2.000.000 Hz
соответственно время одного преобразования в Ардуине занимает ~6 микросекунды
в Ардуино частота прерывания таймера номер 2 = 22222,22222222222 Hz
соответственно время одного прерывания = 0,000045 секунд.
итого:
0,000006 секунды - одно преобразование ADC.
0,000039 секунды - пауза между преобразованиями ADC.
вот если мы уложимся в эти самые 0,000039 секунды между преобразованиями ADC... то тогда мы можем сделать такое:
Ivanoff-iv писал(а):когда ацп оцифрует следующий семпл, нулевой байт из массива уже будет на флешке.
всё дело в таймингах... мы должны в них уложиться))
Добавлено after 13 minutes 40 seconds:
далее...
recByteCount++; // increment sample counter - считаем семплы...
bufByteCount++; // считаем буфер...
if (bufByteCount == 386 && bufWrite == 0) {
bufByteCount = 0;
bufWrite = 1;
} else if (bufByteCount == 386 && bufWrite == 1) { // тут ОШИБКА !!! & вместо && !!! Исправлено))
bufByteCount = 0;
bufWrite = 0;
}
// тут мы выбираем буфер... в который мы будем писать данные ADC...
if (bufWrite == 0) {
buf00[bufByteCount] = ADCH; // будем писать данные ADC в буфер 00
}
if (bufWrite == 1) {
buf01[bufByteCount] = ADCH; // будем писать данные ADC в буфер 01
}
а вы уверены в правильности этого кода ?)))
if (bufByteCount == 386 && bufWrite == 0) {
bufByteCount = 0;
bufWrite = 1;
переменную обнулили ))) bufByteCount = 0;
if (bufWrite == 0) {
buf00[bufByteCount] = ADCH;
}
переменную передали в буфер buf00[bufByteCount] )))
а что мы передали в буфер buf00[0] ? Ноль ? ))
в оригинале вроде было так:
if (recByteCount % 1024 < 386) { // determine which buffer to store sample into
buf01[recByteCount % 386] = ADCH;
}
переменную recByteCount передали в буфер buf00[recByteCount] )))
или вам без разницы что передавать в буфер))
Добавлено after 23 minutes 48 seconds:
и ещё...
buf00[bufByteCount] = ADCH; // на флешку запишутся СТАРШИЕ 8 бит результат преобразования ADC...
птому что Ардуина использует сдвиг результат преобразования ADC влево...
//..1. .... ADLAR - Выравнивание результата
//ADLAR=1
// Выравнивание результата в левую сторону < (8-бит):
// ADCH // 1111 1111 - читать вторым (или первым, тогда последии 2 бит теряем)
// ADCL // 0000 0011 - читать первым
Это не совсем нормально))
При таком режиме мы потеряем качество звука ))
я использую сдвиг результат преобразования ADC вправо...
/ADLAR=0
// Выравнивание результата в правую сторону > (10-бит):
// ADCH // 0000 0011 - читать вторым
// ADCL // 1111 1111 - читать первым
у меня на флешку запишутся младшие 8 бит...
buf00[bufByteCount] = ADCL; // на флешку запишутся МЛАДШИЕ 8 бит результат преобразования ADC...
а в чём разница ? а разница в отсутствии искажения типа "ступенька" ))
или вам пофигу в каком качестве писать звук на флешку)))
а могу записать и все 10 бит...
buf00[bufByteCount] = ADCW; // на флешку запишутся ВСЕ 10 бит результат преобразования ADC...
тогда у меня будет самое высокое качество записи звука))
Добавлено after 16 minutes 37 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=4242470#p4242470"]sbi (TIMSK2, OCIE2A)
cbi (TIMSK2, OCIE2A)
это чё такое... типа ассемблерный вставки... ))
точно))[/uquote]
нет))
это обычные дефайны)))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
Ассемблера тут и близко нет))