Столкнулся с проблемой, есть плата Arduino Nano ATmega 328, Микрофонный усилитель MAX9814 подключенный к аналоговому пину, есть ЦАП MCP4921 12 битный подключенный к SPI портам.
Задача в том чтобы непрерывно производить АЦП сигнала с микрофона и передавать непрерывно на ЦАП через SPI. АЦП произвожу через analogRead() и передача по SPI через библиотеку для ардуино. Тк как цап 12 битный за один такт работы передаю по 2 байта информации. Проблема в том что между тактами передачи происходит очень большая пауза, как на фото сверху синхронизация, снизу данные. Пробовал менять все параметры тактовую частоту, дискретизацию SPI, однако пауза есть всегда, приведу пример кода, вариантов пробовал очень много, подскажите можно ли осуществить непрерывную передачу с несущественными паузами и как это сделать.
#define MicPin A0 //22
void setup() {
Serial.begin(9600);
/*DEFAULT: стандартное опорное напряжение 5 В (на платформах с напряжением питания 5 В) или 3.3 В (на платформах с напряжением питания 3.3 В)
EXTERNAL: внешний источник опорного напряжения, подключенный к выводу AREF*/
analogReference(DEFAULT);
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
pinMode(MicPin,INPUT);
//SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //20000000
SPI.begin();
send_data();
/*
digitalWrite(SS, LOW);
digitalWrite(SCK, LOW);
*/
}
void send_data() {
while(1){
unsigned int digital_signal = analogRead(MicPin); // Получаем цифровой сигнал от 0 до 1023
MCP4921_Send_data(digital_signal); //передаем сигнал в mcp4921
}
}
void MCP4921_Send_data(unsigned int value)
{
byte data;
PORTB &=~ (1 << 2);
data = highByte(value);
data = B00001111 & data;
data = B00110000 | data;
SPI.transfer (data);
data = lowByte(value);
SPI.transfer (data);
PORTB |= (1 << 2);
}
Можете пожалуйста какие-то референсы привести? Искал информацию по данной теме, но во всех местах все по-разному:) Просто чтобы было понятно куда копать
@artem_alish, присоединюсь к ранее озвученному мнению, что Вы выбрали неподходящий контроллер.
Функция analogRead() занимает на AVR около 112 мкс. Т.е. только АЦП (без дальнейшего ЦАП) уже будет иметь частоту порядка 8 кГц, так что по теореме Котельникова-Шеннона-Найквиста верхняя передаваемая частота не будет превышать 4 кГц, что для передачи голоса уже на пределе.
Необходимость ЦАП еще больше снизит эту частоту.
Можно, конечно, по совету rkit вместо analogRead() написать свой код на прерываниях, но вряд ли это серьезно улучшит ситуацию. Еще можно уменьшить время АЦП, снизив разрядность с 10 до 8 разрядов.
Но все это много работы с неочевидным результатом.
Лучше сразу ориентируйтесь на Arduino Due либо на stm32. Помимо прочего, они имеют DMA, что позволит производить обмен с АЦП и ЦАП параллельно, а не поочередно.
Если хочется именно на AVR, можно использовать внешний АЦП (внешний ЦАП ведь все равно нужен), например MCP3008. И запас по скорости будет и с точки зрения программирования явно проще.
Андриано! Ты же знаешь, что сев в лужу, Ркит замолкает.
Штатный gsm- кодек жмёт в 9600 бод. Какое отношение это имеет к выборке, знает только наша “затычка от каждой бочки”. Жмёт он (gsm) штатный PCM 64 Kbit. PCM штатный это как раз 8КГц выборки по 8 бит.
;))
Я точно уверен, что все это ты знаешь без меня. Я просто для истории и для иллюстрации… ;))
А, ну да.
У нас же теперь не “средства передачи” проектируют с учетом физики, а, наоборот, физику каждый день подстраивают под каждый телефон.
PS. Опять же, между “микрофоном” (диапазон частот 20-20000Гц) и “телефоном” (диапазон частот 300-4000Гц) есть некоторая разница. Поэтому и исходить нужно из физики для каждого конкретного процесса, а не из особенностей реализации аппаратуры для одного частного случая.