реклама на сайте
подробности

 
 
> ADC3 в режиме сканирования и DMA2, Необъяснимые "лишние" данные и рассинхронизация
KnightIgor
сообщение Jul 21 2014, 12:04
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Здравствуйте, коллеги.

Не побеждается ADC3.

Имеем:
- STM32F103VC на 24MHz (не 72 для уменьшения потребления, т.к. есть back up на аккумуляторе),
- ADC3 в режиме сканирования трех каналов (11, 12 и 13), ADC тактируется 12MHz.
- естественно DMA2, канал 5, который складывает оцифрованное в буфер U16 длиной 32 триплета - всего 96 слов; таких буферов, конечно, два: один заполняем, из другого читаем.
- таймер 8, который с частотой 100Hz (замеряно) пихает ADC3 своим событием обновления (TRGO).
- прерывание от завершения передач DMA (по флагу TC), которое устанавливает флаг готовности буфера, переключает буферы и перегружает DMA канал.

В принципе, вся кухня работает. Но.
После рестарта может случиться, что данные оказываются смещенными в буфере: например, на месте канала 11 будут данные из канала 12, на месте 12 - из 13, ну а на месте 13 - из 11. Может случиться и сдвиг более дальнего порядка - в 11 - из 13, ну и так далее, по кругу. Причем этот сдвиг случается один раз при старте системы, а в процессе работы все остается фиксированно, без перескоков.

Я тщательно проанализировал последовательность инициализации и попытался в прерывании DMA сбрасывать бит STRT в ADC3->SR и "прочищать" ADC3->DR (чтением) перед тем как перегрузить DMA. Тем не менее в прерывании я мог всегда(!) поймать ситуацию при самом _первом_ вхождении, когда после перегрузки DMA его счетчик тут же уменьшался на единицу, словно ADC3 припрятал запрос к DMA несмотря на "прочистку".
Последнее, что я сделал, - поднял приоритет DMA до "kill 'em all", а в прерывании - выключал бит DMA в ADC3->CR2, делал прочистку ADC и перегрузку DMA и включал ADC3->CR2 снова. На моей плате это вроде привело к успеху (счетчик DMA не уменьшался сразу), а вот у коллеги - нет.

Идеи?
Заранее благодарен.

Сообщение отредактировал KnightIgor - Jul 21 2014, 12:44
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AlHakim
сообщение Jul 21 2014, 17:01
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 7-02-05
Из: Уфа
Пользователь №: 2 474



Цитата(KnightIgor @ Jul 21 2014, 21:41) *
Кстати, в Вашем коде нет собственно "взвода" ADC на следующую операцию. Опущено здесь для иллюстрации?


в принципе дальше в коде стоят
Код
  
ADC1->SQR1 |= (uint32_t)((6-1) << 20);
ADC1->CR2 |=  ADC_CR2_SWSTART | ADC_CR2_DMA;    //ADC_CR2_ADON| //первый старт, н нужен, потому что как только разрешил DMA оно сразу стартует

но вы не поверите. и без них работает, потому что ранее записано кол-во перобразований, осуществяемых через DMA и выставлено прерывание. А может быть это просто мистика, но оно работает sm.gif
Код
DMA1_Channel1->CNDTR = 18;
DMA1_Channel1->CCR |=  DMA_CCR_EN | DMA_CCR_TCIE


Сообщение отредактировал AlHakim - Jul 21 2014, 17:01
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 31st July 2025 - 11:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01361 секунд с 7
ELECTRONIX ©2004-2016