Цитата(scifi @ Jan 31 2011, 14:42)

Разбираться времени нет. Прикладываю свой модуль АЦП, он сканирует каналы 0..9 по кругу, складывая в буфер. Может быть, пригодится.
Спасибо, пока остановился на чём-то похожем. Дальше я эти наборчики отсчётов в прерывании таймера (частота дискретизации) накапливаю в буфер порядка 1К и передаю по ethernet-у. При таком подходе этот буферочек для 10 каналов представляет своего рода ящик, куда можно в любой момент за ними обратиться - уже готовенькие.
Я сначала по другому пути пошёл:
1. АЦП запустил в SCAN-mode, CONT=0 (по идее, остановка после конверсии группы регулярных каналов), аппаратный запуск от таймера (запускает с частотой дискретизации), DMA (кол-во передач=кол-во каналов), начальный адрес DMA - начало моего накопительного буфера (т.е. хотелось бы сразу кидать отсчёты в нужное место).
2. В прерывании по окончании DMA-передачи (предполагается, что DMA-передача заканчивается раньше очередного запуска АЦП от таймера) DMA отключал, обновлял счётчик передач и перенацеливал DMA на следующую позицию (+10 слов) в накопительном буфере, включал DMA. Приоритет обработчика прерываний DMA выше других.
Вот при таком подходе у меня и начиналась каша внутри 10-байтовых отрезков со сменой порядка отсчётов, причём сдвиг по кругу на произвольное и непостоянное число. Первая мысль была, что перезапуск АЦП от таймера происходил раньше окончания DMA-передачи. Но увеличение периода таймера до заведомо намного превышающей общее время конверсии группы каналов величины ситуации не поменяло. Тут-то мысль и остановилась. В чём порочность подхода?
Вобщем, пошёл пока по предложенному Вами пути.
Цитата(akimych @ Jan 31 2011, 19:01)

Вот что мне не нравится в этом проекте, так это как организована работа с дма.
АЦП судя по настройкам непрерывно работает, а мы ему то включаем, то отключаем дма.
Я бы сделал иначе.
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
А в цикле надо ловить флаги DMA1_FLAG_HT1 и DMA1_FLAG_TC1 и обрабатывать буфер по половинке.
Да, Вы правы, примерчик неудачный, я его поправил - сделал так:
...
ADC_InitStructure.ADC_ContinuousConvMode =
DISABLE;
...
while(1)
{
/* Test on DMA1 channel1 transfer complete flag */
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
/* Clear DMA1 channel1 transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
/* Disable DMA channel1 */
DMA1_Channel1->CCR &= 0xFFFFFFFE;
/* Update the Number of DMA transfer */
DMA1_Channel1->CNDTR = 2;
DMA1_Channel1->CMAR = (u32)ADC_DualConvertedValueTab;
DMA1_Channel1->CCR |= 0x00000001;
ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
И стало как дОлжно. Всё равно у меня в тылу остался вопрос, предыдущий пост.
Сообщение отредактировал pr0m - Jan 31 2011, 20:10