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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ADC+DMA в STM32F107, Глюк DMA??
pr0m
сообщение Jan 31 2011, 11:36
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Всем привет.

Играюсь со слегка модицицированным примером для STM32F10x "RegSimul_DualMode" для ADC (из стандартной STM32F10xFWLib).
Там используются 2 ADC в режиме DualMode, 2 группы по 2 канала, после окончания конверсии каждой пары 32-битный результат складывается посредством DMA1 в буфер в ОЗУ. Так вот, я его переделал в том смысле, что зациклил процесс опроса (а не однократный опрос, как в оригинальном примере), после чего обнаружил несколько шокирующую картину - положение данных опроса в ОЗУ меняется от опроса к опросу, т.е. в том месте, где я ожидаю увидеть результат от каналов 1,2 через раз оказываются данные каналов 3,4, и наоборот.
Что это??? Только бы не глюк контроллера.... Собираюсь использовать его именно в режиме циклического опроса регулярной группы каналов АЦП.
Прилагаю кейловский проект.
Прикрепленные файлы
Прикрепленный файл  Project.rar ( 25.63 килобайт ) Кол-во скачиваний: 29
 


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 31 2011, 11:42
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Разбираться времени нет. Прикладываю свой модуль АЦП, он сканирует каналы 0..9 по кругу, складывая в буфер. Может быть, пригодится.
Прикрепленные файлы
Прикрепленный файл  adc.txt ( 2.41 килобайт ) Кол-во скачиваний: 230
 
Go to the top of the page
 
+Quote Post
akimych
сообщение Jan 31 2011, 16:01
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Цитата
Прилагаю кейловский проект.

Вот что мне не нравится в этом проекте, так это как организована работа с дма.
АЦП судя по настройкам непрерывно работает, а мы ему то включаем, то отключаем дма.
Я бы сделал иначе.
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
А в цикле надо ловить флаги DMA1_FLAG_HT1 и DMA1_FLAG_TC1 и обрабатывать буфер по половинке.
Go to the top of the page
 
+Quote Post
pr0m
сообщение Jan 31 2011, 20:03
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(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


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
akimych
сообщение Feb 1 2011, 17:16
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Цитата
Всё равно у меня в тылу остался вопрос, предыдущий пост.

Этот?
Цитата
В чём порочность подхода?


Не может ли там быть каким-то образом, что перезапуск дма получился где-то в середине? По идее достаточно одно такого глюка, что бы началась каша.
АЦП выдает 2 значения подряд, а дма уже не в 0, на 1ом будет флаг ТС1, пересброс дма, по сути операция эта очень быстрая, ацп не успеет 2ое значение потерять, 2ое значение ляжет первым, после чего 1ое (новое) значение пойдет на 2ое место, опять готовность дма и всё повторяется. Если буфер не 2, а больше значений, то соотв. сдвижка будет другая. И никуда она не денется и период таймера не повлияет.
Как вариант, можно попробовать ловить флаг не от дма, а от ацп, он его выдаст после оцифровки всей группы каналов. Тут уже глюков быть не должно.
Заодно можно проверить, если от ацп флаг есть, а от дма нету (в течение некоторого адекватного времени, весьма короткого), значит имеет место косяк.
Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 1 2011, 20:19
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(akimych @ Feb 1 2011, 20:16) *
Не может ли там быть каким-то образом, что перезапуск дма получился где-то в середине? По идее достаточно одно такого глюка, что бы началась каша.

Очень на то похоже, другого объяснения не вижу.
Цитата(akimych @ Feb 1 2011, 20:16) *
АЦП выдает 2 значения подряд,

Разве такое возможно? Каналы перебираются последовательно, после каждого преобразования i-го канала запрос к DMA. В моём случае АЦП на максимальной скорости - 12МГц, 14 тактов - одна конверсия 1.17мкс. Период триггера запуска АЦП от таймера >50мкс. А пересылка посредством DMA одного 16-бит слова из АЦП со всякими там арбитражами-подтверждениями (тонкостей не знаю), думаю, займёт ну пусть 10 тактов системных (72МГц) - всё равно несоизмеримо с 1.17мкс.
Цитата(akimych @ Feb 1 2011, 20:16) *
а дма уже не в 0, на 1ом будет флаг ТС1, пересброс дма, по сути операция эта очень быстрая, ацп не успеет 2ое значение потерять, 2ое значение ляжет первым, после чего 1ое (новое) значение пойдет на 2ое место, опять готовность дма и всё повторяется. Если буфер не 2, а больше значений, то соотв. сдвижка будет другая. И никуда она не денется и период таймера не повлияет.

Характер сдвига несколько другой, в хаосе имеется закономерность - сдвиг циклический sm.gif - из моих 6 каналов возможны комбинации
012345-123450-234501 и т.д. И сдвиг гуляет, а не стоит на месте.
Вот такого нет: 102345,42501 и т.п.
Цитата(akimych @ Feb 1 2011, 20:16) *
Как вариант, можно попробовать ловить флаг не от дма, а от ацп, он его выдаст после оцифровки всей группы каналов. Тут уже глюков быть не должно.
Заодно можно проверить, если от ацп флаг есть, а от дма нету (в течение некоторого адекватного времени, весьма короткого), значит имеет место косяк.

Согласен полностью, выглядит самым надёжным вариантом. От АЦП конечно флаг будет, раз уж ввалились в прерывание от оного, и очень интересно поглядеть, чем в это момент занимается ДМА,все ли дела закончило. Думаю, проверка флага ТС1 обязательна, и вовсе не будет означать косяк. Важнее глянуть на счётчик передач, он должен быть не больше 1, т.е. может идти последняя передача. К сожалению, сегодня не добрался до железки, как только опробую, отрапортую.

Сообщение отредактировал pr0m - Feb 1 2011, 20:27


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
akimych
сообщение Feb 1 2011, 22:23
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Цитата
Разве такое возможно?

Сложно сказать. Я не думаю, что там что-то не успевает. Речь шла о другом. Может там что-то остается после калибровки, к примеру, дма ведь на тот момент уже работает.
Кстати говоря, дма у стм32 отнисительно тормозное. Если его направить в порт, то можно посмотреть частоту дрыгания ногами.
А я вообще столкнулся с тем, что при частоте SPI = 1/2 и 8 бит, дма иногда не успевает вычитывать данные.
Но для ацп должно хватать.

Цитата
Характер сдвига несколько другой, в хаосе имеется закономерность - сдвиг циклический

Это как раз подтверждает мое предположение (пишем буфер не с 0), либо означает, что ацп пишет в дма кол-во данных не кратное длине буфера.

Цитата
Важнее глянуть на счётчик передач, он должен быть не больше 1

Хм, а почему 1? В SCAN-mode там будет столько, сколько каналов оцифровывается. В этом режиме оцифр. все каналы друг за другом, после чего выставляется EOC.

Я кстати так и делал, ловил прерывание от ацп, а не от дма. Может потому и не столкнулся с подобными глюками.
Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 2 2011, 09:48
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(akimych @ Feb 2 2011, 01:23) *
Хм, а почему 1? В SCAN-mode там будет столько, сколько каналов оцифровывается. В этом режиме оцифр. все каналы друг за другом, после чего выставляется EOC.

Думаю, 1 максимум потому что по оси времени процесс должен выглядеть так (поканально, для всей группы из 6 каналов): EOC#1-DMA
#1,EOC#2-DMA#2,...,EOC#6(из здесь прерывание по окончанию конверсии всей группы EOC, куда и попадаем)-DMA#6. Так вот в момент прерывания по EOC идут одновременно два процесса - переход в прерывание EOC и последняя передача по DMA(аппаратно декрементируемый счётчик DMA=1), и в момент входа в EOC-обработчик DMA может уже завершить передачу ( и счётчик будет=0) или быть в процессе (счётчик=1).


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
akimych
сообщение Feb 2 2011, 20:13
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Правильно, я что-то стормозил, счетчик же к нулю считает. Либо 1 либо 0. Но тогда лучше сделать буфер с запасом, иначе не видна будет ситуация с "лишними" данными.
Вообще это конечно странно. Если перед запуском ацп дма проинициальзировать, то никаких лишних и наоборот данных быть там не должно. Во всяком случае это легко проверить.

Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 12 2011, 05:14
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Во первых размер буфера посчитан не верно:
Код
DMA_InitStructure.DMA_BufferSize = sizeof(ADC_DualConvertedValueTab)/sizeof(u32);

вообще то надо делить на sizeof(u16) если у вас DMA настроен на 16 битную работу...

Ну и по главное:
Цитата
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
А в цикле надо ловить флаги DMA1_FLAG_HT1 и DMA1_FLAG_TC1 и обрабатывать буфер по половинке.

Надо делать именно так а не иначе. Только я бы добавил, что не надо ловить флаги, а непосредственно написать обработчик прерывания.
Если не получится, выложу свой пример (в понедельник).
Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 12 2011, 11:43
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(kan35 @ Feb 12 2011, 08:14) *
Во первых размер буфера посчитан не верно:
Код
DMA_InitStructure.DMA_BufferSize = sizeof(ADC_DualConvertedValueTab)/sizeof(u32);

вообще то надо делить на sizeof(u16) если у вас DMA настроен на 16 битную работу...

Нет, правильно. АЦП в dual mode работает, два 16-битных результата на одну дма-перемылку.


Ну и по главное:
Цитата(kan35 @ Feb 12 2011, 08:14) *
Надо делать именно так а не иначе. Только я бы добавил, что не надо ловить флаги, а непосредственно написать обработчик прерывания.
Если не получится, выложу свой пример (в понедельник).

Уже решил задачу, но посмотреть как другие делают, всегда полезно. Выложите, пожалуйста.

Сообщение отредактировал pr0m - Feb 12 2011, 11:44


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
kan35
сообщение Feb 12 2011, 17:52
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



да, то, что идет работа синхронно 2 каналов я не учел, у меня только 1 канал задействован.
А в вашем коде, кстати, зачем используете 2 АЦП? Как я вижу большой скорости вам не надо, тогда зачем...
Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 12 2011, 19:00
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(kan35 @ Feb 12 2011, 20:52) *
да, то, что идет работа синхронно 2 каналов я не учел, у меня только 1 канал задействован.
А в вашем коде, кстати, зачем используете 2 АЦП? Как я вижу большой скорости вам не надо, тогда зачем...

Это я проект из готовых ST-шных взял, когда АЦП-шки исследовал. На самом деле нужно опрашивать 6 каналов одновременно с частотой дискретизации 100кГц...


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post
akimych
сообщение Feb 12 2011, 20:35
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073



Цитата
Уже решил задачу, но посмотреть как другие делают, всегда полезно. Выложите, пожалуйста.

В чем все же был косяк?

2 ацп там могут иметь смысл для оцифровки одновременно сигнала и опорного напряжения, у STM-а же "опорное" - это по сути "эталонное", т.е. просто еще один канал, который можно мерить.

Я тут было экспериментировал на F100, у него 1 ацп, оцифровывал тоже на частоте ~100кГц. На слабом сигнале проявляются помехи по питанию. Я пытался это как-то устранить с помощью "опорного", но приходится мерить по очереди, не одновременно. Так по большому счету ничего хорошего не получилось. Иногда помогает, а иногда нет.
Go to the top of the page
 
+Quote Post
pr0m
сообщение Feb 13 2011, 07:56
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 183
Регистрация: 22-06-05
Из: Таганрог
Пользователь №: 6 233



Цитата(akimych @ Feb 12 2011, 23:35) *
В чем все же был косяк?

В следующем: в том варианте я реагировал на EOC в обработчике прерывания там забирал данные АЦП, переинициализировал и перезапускал ДМА, а в самом его начале дополнительно проверял while(DMA->CNTDR != 0), и здесь появлялись "чудеса" (перемешивание порядка каналов). Вместо ожидаемого значения DMA->CNTDR равным 0 или 1 максимум были любые от 1 до 3 (напомню, 2АЦП*3 канала=3 пересылки). Оказалось, забыл в ходе экспериментов при начальной инициализации ДМА сменить CircularMode на Noncircular sm.gif

Цитата(akimych @ Feb 12 2011, 23:35) *
2 ацп там могут иметь смысл для оцифровки одновременно сигнала и опорного напряжения, у STM-а же "опорное" - это по сути "эталонное", т.е. просто еще один канал, который можно мерить.

Дело в том, что в моём случае желательно получить макс. частоту дискретизации, 160 кГц оптимально. При тактовой АЦП 12МГц, миним. времени преобразования 14 тактов и последовательном переборе 6 каналов T=1/12*14*6 = 7мкс, а 160кГц=6.25мкс. Вот и пригодился DualMode, в 2раза быстрее. А Vref действительно тоже понадобится, но думаю измерять его где-то между делом, с большим интервалом чтобы учесть температурный дрейф, да и то не уверен, может будет достаточно один раз при старте его померить.
Кстати, моё железо не позволяет испытать характеристики АЦП (демо-плата, голые ноги, выведены на кросс-контакты, никаких фильтров), сделал пару наблюдений (один из каналов на внутреннем Vref для экспериментов) :
1) взаимное влияние на результат соседних соседних входов, т.е. допустим 5 моих входов просто болтаются в воздухе, на выходах АЦП вижу шумы определённого уровня. При закорачивании на землю одного из входов, уровни шумов соседних каналов тоже меняются. Думаю, особого криминала в этом нет,всё-таки вношу ёмкость. В реальности перед каждым входом будет ФНЧ с низким выходным.
2) для точного измерения внутреннего Vref 1.5...7 тактов на сэмплирование мало. Результат получается меньше. В даташите расплывчато дан пример чтения датчика температуры, там сказано про время сэмплирования 17.5мкс, видимо это и к Vref относится.

Цитата(akimych @ Feb 12 2011, 23:35) *
Я тут было экспериментировал на F100, у него 1 ацп, оцифровывал тоже на частоте ~100кГц. На слабом сигнале проявляются помехи по питанию. Я пытался это как-то устранить с помощью "опорного", но приходится мерить по очереди, не одновременно. Так по большому счету ничего хорошего не получилось. Иногда помогает, а иногда нет.

Тут Вы видимо исходили из предположения о синфазности помехи и по сигналу, и по внутреннему Vref?
Вот тут имхо неправильный посыл "На слабом сигнале проявляются помехи по питанию." - они есть независимо от силы сигнала sm.gif Ну что делать, это же не дельта-сигма какая с дифф. входами. Фильтровать цепи питания, проявить мастерство в разводке платы (цифровые и аналоговые земли разделить и соединить звездой в одной точке, идущей к источнику питания). Ничего нового не сообщаю... А фильтр по входу достаточно хороший был? Может алиас какой пролезал?

Сообщение отредактировал pr0m - Feb 13 2011, 08:11


--------------------
Правильно поставленный вопрос - половина ответа...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 12:38
Рейтинг@Mail.ru


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