Тоже есть вопрос по ADC / DMA. Пока не могу понять, в чём дело.
Речь о проекте анализатора спектра. Используется два канала АЦП в режиме "MultiChannel single conversion".
Суть следующая. Раз в 50 мкс (или с частотой 20 кГц) от таймера приходит прерывание. В этом прерывании "дёргается" АЦП. Сначала АЦП снимает данные с левого канала, затем с правого, и на этом всё заканчивается, вплоть до следующего запроса от таймера через 50 мкс.
Данные, которые получает АЦП (два 16-битных числа), кладутся в "длинный" DMA буфер. Таким образом, через некоторое время в этом буфере появляются снятые с двух каналов значения (L-R-L-R-L...-L-R). Дальше уже эти данные подвергаются анализу Фурье, выводятся на экран и всё такое. Но это пока не важно.
На STM32F103CB всё работает отлично. В качестве входов АЦП выбраны PA0 и PA1, которые в этом случае являются простыми каналами АЦП 0 и 1.
Но аналогичный код для STM32F303CC работает некорректно. В его случае эти же входы уже являются другими каналами АЦП (1 и 2), причём там есть какие-то тонкости с дифферециальными и обычными входами. И я подозреваю, что проблема именно где-то здесь
А проблема в том, что данные с PA0 (левый канал) аккуратно ложатся в "свои" ячейки в DMA буфере. То есть, например, если подать синусоиду в левый канал, а в правом оставить тишину, то в DMA буфере будет что-то типа:
Код: Выделить всё
L R L R L R L R L R L R L R
0 2048 500 2048 2000 2048 3000 2048 2000 2048 500 2048 0 2048
То есть, данные в "левых" ячейках постоянно меняются, а данные в "правых" равны половине разрешения АЦП (половина питания).
Но вот если на левый канал ничего не подавать, а синусоиду завести в правый канал, то в DMA буфере получается уже другая картина:
Код: Выделить всё
L R L R L R L R L R
2048 0 1048 1000 48 2000 0 2048 1000 1048
. То есть, левый канал не "стоит" в половине питания 2048, а меняется в противофазе с правым. Так, что их сумма почти одинакова всё время.
То есть, данные со входа PA0 попадают в канал ADC_channel 1 правильно.
А вот данные со входа PA1 попадаются не только в ADC_channel 2, но, почему-то, и в ADC_channel1, но "в противофазе".
Такое ощущение, что где-то не отключена "дифференциальность" для входа PA2. Но не могу понять точно.
Код с инициализацие АЦП, если кто хочет взглянуть:
https://github.com/WiseLord/ampcontrol- ... trum.c#L90 Там же чуть выше настройка DMA.
P.S. Так... вопрос, похоже, снимается. Похоже, в библиотеке LL функция LL_ADC_SetChannelSingleDiff имеет баг, из-за которого какой бы режим канала ни устанавливался (single_ended или differential), он всегда устанавливается в differential. Канал 1 работает нормально (так как у него "пары" нет), а вот канал 2 работает не относительно земли, а относительно канала 1.
Вот
упоминание о баге с ответом недельной давности, что пофиксят в будущих версиях LL.
P.P.S. Для справки, обошёлся обычным CMSIS-овским
Код: Выделить всё
ADC1->DIFSEL &= ~ADC_DIFSEL_DIFSEL_1;
ADC1->DIFSEL &= ~ADC_DIFSEL_DIFSEL_2;