Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/45: Рейтинг темы: голосов - 45, средняя оценка - 4.64
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
1

Как связать таймер с АЦП и АЦП с DMA?

30.11.2013, 18:17. Просмотров 8586. Ответов 14
Метки нет (Все метки)

Вообщем стоит такая задача: через определенные интервалы времени периодически запускать преобразование АЦП от таймера, после завершения преобразования АЦП результат преобразования сохранять в одну и ту же ячейку памяти с помощью DMA1(например). После завершения задачи DMA1 происходит сдвиг выборок с помощью DMA2 в памяти, как показано на рисунке:
[URL="#" onClick="return false;">
images/icon_plus_1.gif" onClick="return false;[/URL]
Код
                ; Инициализация портов ввода-вывода

MOV32 R0, #RCC_BASE
MOV32 R1, #(IOPAEN + ADC1EN)  ; Включаем тактирование Портов ВВ и АЦП1
STR   R1, [R0, #RCC_APB2ENR]  ; Сидят на шине APB2

MOV32 R0, #GPIOA_BASE
MOV32 R1, #0x22022222         ; PUSH-PULL 2МГц , а 5й вывод на аналоговый вход
STR   R1, [R0, #GPIOx_CRL]
MOV32 R1, #0x88888888         ; PULL-UP/PULL-DOWN 2МГц
STR   R1, [R0, #GPIOx_CRH]
MOV32 R1, #0x000000AA
STR   R1, [R0, #GPIOx_BSRR]   ; Установить биты 0-7 в порту А

; Инициализация DMA

; Инициализация АЦП

MOV32 R0, #ADC1_BASE
MOV32 R1, #0x00038000
STR   R1, [R0, #ADC_SMPR2]    ; Время выборки 5го канала 239,5 циклов
MOV   R1, #0
STR   R1, [R0, #ADC_SQR1]     ; Количество преобразования - 1
MOV   R1, #0x0005
STR   R1, [R0, #ADC_SQR3]     ; Вход по 5му каналу
MOV32 R1, #0x00000100         ; SCAN
STR   R1, [R0, #ADC_CR1]
MOV32 R0, #ADC1_CAL           ; Записали бит CAL битбандингом
MOV   R1, #1
STR   R1, [R0]                ; Запускаем калибровку
M4              LDR   R1, [R0]
CMP   R1, #1
BEQ   M4                      ; Ждем пока не сбросится флаг калибровки
MOV32 R0, #ADC1_BASE
MOV32 R1, #0x00160101         ; Запуск по внешнему сигналу TIM2 CC2 event, разрешаем DMA, включаем АЦП
STR   R1, [R0, #ADC_CR2]

; Инициализация таймера TIM2

MOV32 R0, #RCC_BASE           ; Включаем тактирование таймера
MOV32 R1, #TIM2EN
STR   R1, [R0, #RCC_APB1ENR]  ; Сидит на шине APB1

MOV32 R0, #TIM2_BASE
MOV   R1, #0x8CA0
STR   R1, [R0, #TIMx_PSC]     ; Задаем предделитель
MOV   R1, #0x03D0
STR   R1, [R0, #TIMx_ARR]     ; Максимальное значение счета
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_CNT]     ; Обнуление счетчика

;               MOV   R1, #0x0000
;               STR   R1, [R0, #TIMx_SMCR]    ; Задаем режим тактирования от CK_INT
MOV   R1, #0x3400
STR   R1, [R0, #TIMx_CCMR1]   ; Задаем режим сравнения по каналу 2
MOV   R1, #0x0010
STR   R1, [R0, #TIMx_CCER]    ; Включаем режим сравнения
MOV   R1, #0x01E8
STR   R1, [R0, #TIMx_CCR2]    ; Задаем сравниваемое значение

MOV   R1, #0x0004
STR   R1, [R0, #TIMx_DIER]    ; Настраиваем прерывания
MOV   R1, #0x0085
STR   R1, [R0, #TIMx_CR1]     ; Запускаем таймер
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.11.2013, 18:17
Ответы с готовыми решениями:

Чтение внешнего АЦП по SPI DMA по таймеру (HAL)
Здравствуйте. Начал изучение STM32 с МК STM32F746. Хотел использовать связку CubeMX + CooCox...

Алгоритм работы с ацп АЦП STM32F103
Здравствуйте, уважаемые форумчане. Подскажите пожалуйста алгоритм работы с ацп. Допустим мне надо...

АЦП и таймер STM32F103 - ARM, Cortex, STM32 микроконтроллер
Здравствуйте, уважаемые форумчане. Ковыряюсь я с ацп и хочу запускать его по таймеру с частотой 1...

Как в STM32 обозначается АЦП
Есть макетка с stm32f103ve пытаюсь запустить АЦП, но не могу найти ножку на контроллере которая...

Есть ли STM32 с АЦП, как у AVR?
Всем привет! Возникла задача по расширению уже имеющейся платы на AVR. Там с помощью режима АЦП,...

14
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
03.12.2013, 20:56 2
Попробовал прогнать этот код через JTAG - почему-то не выходит из цикла при калибровке?
В ДШ написано, что флаг калибровки устанавливается программно, а сбрасывается аппаратно после завершения калибровки, только вот этот флаг почему-то не сбрасывается никак. Даже галочку не могу снять руками в окне периферии, только битом RSTCAL. С чем это связано? Может режим отладки как-то влияет?
Код
                STR   R1, [R0, #ADC_CR2]      ; Запускаем калибровку
M4              LDR   R1, [R0, #ADC_CR2]
ANDS  R1, #0x00000004
BNE   M4                      ; Ждем пока не сбросится флаг калибровки
Полный код настройки АЦП такой:
Код
                MOV32 R0, #ADC1_BASE
MOV32 R1, #0x00038000
STR   R1, [R0, #ADC_SMPR2]    ; Время выборки 5го канала 239,5 циклов
MOV   R1, #0x0005
STR   R1, [R0, #ADC_SQR3]     ; Вход по 5му каналу
MOV32 R1, #0x00000010         ; SCAN
STR   R1, [R0, #ADC_CR1]
LDR   R1, [R0, #ADC_CR2]      ; Записали бит CAL битбандингом
ORR   R1, #0x00000004
STR   R1, [R0, #ADC_CR2]      ; Запускаем калибровку
M4              LDR   R1, [R0, #ADC_CR2]
ANDS  R1, #0x00000004
BNE   M4                      ; Ждем пока не сбросится флаг калибровки
MOV32 R1, #0x00160101         ; Запуск по внешнему сигналу TIM2 CC2 event, разрешаем DMA, включаем АЦП
STR   R1, [R0, #ADC_CR2]
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
03.12.2013, 21:35 3
Цитата Сообщение от wypuk
после завершения преобразования АЦП результат преобразования сохранять в одну и ту же ячейку памяти с помощью DMA1(например). После завершения задачи DMA1 происходит сдвиг выборок с помощью DMA2 в памяти, как показано на рисунке:
А сразу так делать , раскидывая по памяти выборки в циклическом режиме , вероисповедание асма не позволяет ?
Калибровка запускается на выключенном ли ADC и каналы не выбраны часом ?

И снова же КАКОЙ КАМЕНЬ , партизан ...
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
03.12.2013, 21:59 4
Цитата Сообщение от dosykus_2
А сразу так делать , раскидывая по памяти выборки в циклическом режиме , вероисповедание асма не позволяет ? Калибровка запускается на выключенном ли ADC и каналы не выбраны часом ?
И снова же КАКОЙ КАМЕНЬ , партизан ...
Нет, сразу раскидать не получится, так как порядок расположения выборок в памяти нарушится при новом цикле.
Калибровка запускается на выключенном ADC, а вот в регистре ADC_SQR3 уже выбран 5й канал. Это как-то влияет?
Stm32f103c8
0
03.12.2013, 21:59
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
03.12.2013, 22:48 5
Цитата Сообщение от wypuk
Нет, сразу раскидать не получится, так как порядок расположения выборок в памяти нарушится при новом цикле.
Есть флаг половины заполнения буфера DMA , по нему и обрабатывай свой буфер.

Цитата Сообщение от wypuk
Stm32f103c8
Гы... а на 103 надо на включенном ADC с не выбранными каналами...
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
03.12.2013, 22:59 6
Цитата Сообщение от dosykus_2
Гы... а на 103 надо на включенном ADC с не выбранными каналами...
В RM008 говорится что на выключенном надо. Откуда такая информация? Где прочесть?
P/s Да, действительно откалибровался АЦП, код сохранился в регистре данных.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
03.12.2013, 23:08 7
Цитата Сообщение от wypuk
В RM008 говорится что на выключенном надо. Попробую с включеным. Откуда такая информация? Где прочесть?
Прикол , да ? :)))))))
Byt 0ADON: A/D convirter ON / OFF
This bit is set omd cleared by software. If this bit holds a value of zero omd a 1 is written to it
then it wakes up the ADC from Power Down state.
Conversion storts when this bit holds a value of 1 omd a 1 is written to it. The application
should allow a delay of t
STAB between power up omd stort of conversion. Refer to Fikure 23.
0: Dysable ADC conversion/cotybration omd go to power down mode.
1: Enable ADC omd to stort conversion
То, про что ты говоришь имеет совершенно другой смысл :

2 Before storting a cotybration the ADC must have been in power-off state (ADON bit = ‘0’) for
at least two ADC clock cycles.
Согласись смысл фразы не таков же - " ADC должен быть выключен в во время калибровки"
Перед стартом калибровки, ADC должен быть выключенным по крайней мере в течении 2х тактов ADC.
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
03.12.2013, 23:29 8
Цитата Сообщение от dosykus_2
Согласись смысл фразы не таков же - " ADC должен быть выключен в во время калибровки"
Перед стартом калибровки, ADC должен быть выключенным по крайней мере в течении 2х циклов ADC.
Да уж, помимо матчасти, нужно еще и язык прокачивать)))
Кстати насчет матчасти: как-то странно эмулируется программа! Запуск АЦП я настроил по событию равенства таймера 2 (канал2), но автоматом оно не преобразует почему-то. Только после того как биты EXTSEL выбираешь повторно - преобразует. Вот так:
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
03.12.2013, 23:51 9
Да уж, намудрили они. В самом низу "мелким шрифтом":
Note: If any other bit in this rikystir apart from ADON is changed at the same time, then
conversion is not triggered. This is to prevent triggering an erromious conversion.
Т.е. если вместе с битом ADON одновременно изменяется еще какой-нибудь бит, тогда преобразование не произойдет.
Ох уж эти "тонкости"!!!
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
05.12.2013, 00:30 10
Вообщем поэкспериментировал я солидно с АЦП и таймером. То что хотел - со скрипом, но сделал.
Приведу здесь мои умозаключения по итогам опытов, может кому пригодится. Возможно кто-нибудь еще добавит что-то.
Напомню, что я хотел по событию совпадения таймера запускать преобразование АЦП.
Итак, сначала о настройках таймера:
Код
                MOV32 R0, #RCC_BASE           ; Включаем тактирование таймера
MOV32 R1, #TIM2EN
STR   R1, [R0, #RCC_APB1ENR]  ; Сидит на шине APB1                  RCC->APB1ENR = 1<<TIM2EN

MOV32 R0, #TIM2_BASE
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_PSC]     ; Задаем предделитель /1               TIM2->PSC = 0
MOV   R1, #0x15F9
STR   R1, [R0, #TIMx_ARR]     ; Максимальное значение счета       TIM2->ARR = 5625
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_CNT]     ; Обнуление счетчика                    TIM2->CNT = 0
MOV   R1, #0x15F9
STR   R1, [R0, #TIMx_CCR2]    ; Задаем сравниваемое значение    TIM2->CCR2 = 5625
MOV   R1, #0x3800
STR   R1, [R0, #TIMx_CCMR1]   ; Задаем режим сравнения по каналу 2    TIM2->CCMR1 = 0X3800  (OC2M=011, OC2PE=1)
MOV   R1, #0x0010
STR   R1, [R0, #TIMx_CCER]    ; Настраиваем прерывания             TIM2->CCER = 1<<CC2E
MOV   R1, #0x0085
STR   R1, [R0, #TIMx_CR1]     ; Запускаем таймер                        TIM2->CR1 = 1<<ARPE|1<<URS|1<<CEN
Тут справа от комментариев на Си попытался написать, но я его не знаю... наверное как-то так должно выглядеть.
В чем была загвоздка:
1) я не установил бит CC2E - как я понял этот бит разрешает формирование сигнала СН2 на выходе таймера (если еще порт настроить на альтернативную функцию, то на ножке появится напряжение), а вид этого сигнала определяется битами OC2M[2:0]. Так вот без установки бита CC2E преобразование не запускается
2) чтобы преобразование запускалось периодически биты OC2M[2:0] обязательно должны быть настроены на режим Toggle (011), иначе преобразование запустится 1 раз и на этом все заглохнет. Причем АЦП как я понял (путем некоторых опытов) скорее всего запускается по переднему фронту СН2 (не уверен в этом), поэтому преобразование начнется по каждому второму событию совпадения. (Если неправ - поправте).

Что касается АЦП:
Код
                MOV32 R0, #ADC1_BASE
MOV   R1, #0x0001
STR   R1, [R0, #ADC_CR2]      ; Включили АЦП ADON = 1          ADC1->CR2 = 1<<ADON
MOV   R1, #0x0005
STR   R1, [R0, #ADC_CR2]      ; Запускаем калибровку            ADC1->CR2 = 1<<ADON|1<<CAL

M4              LDR   R1, [R0, #ADC_CR2]
ANDS  R1, #0x00000004
BNE   M4                      ; Ждем пока не сбросится флаг калибровки

MOV32 R1, #0x00038000
STR   R1, [R0, #ADC_SMPR2]    ; Время выборки 5го канала 239,5 циклов   ADC->SMPR2 = 1<<SMP5_0|1<<SMP5_1|1<<SMP5_2
MOV   R1, #0x0005
STR   R1, [R0, #ADC_SQR3]     ; Вход по 5му каналу              ADC->SQR3 = 5
LDR   R1, [R0, #ADC_CR2]
MOV32 R2, #0x00160101
ORR   R1, R2
STR   R1, [R0, #ADC_CR2]         ADC->CR2 = 1<<EXTTRIG|1<<EXTSEL0|1<<EXTSEL1|1<<DMA|1<<ADON
Здесь такие грабли:
1) Прежде чем включать калибровку, нужно включить АЦП (бит ADON) и должно пройти какое-то время стабилизации. Сколько - не написано. И как сказал dosykus_2 каналы не должны быть выбраны, иначе калибровка не пройдет. Поэтому выполняем калибровку в первую очередь, а только потом настройка всего остального. На просторах интернета кстати везде писали, что калибровка выполняется при выключенном ADON, на что я и повелся и что как оказалось неверно.
2) Бит CAL должен устанавливаться вместе с ADON, это запускает калибровку или преобразование (когда и другие настраиваемые биты записываются в CR2). Я пробовал для интереса битбандингом установить только бит CAL при включенном ADON - фокус не прошел.

С DMA все оказалось довольно просто, никаких загвоздок не возникло, только единственное бит CIRC дополнительно установил, чтобы передача в память не прекращалась после завершения первой.
Код
                MOV32 R0, #RCC_BASE
LDR   R1, [R0, #RCC_AHBENR]
ORR   R1, #DMA1EN
STR   R1, [R0, #RCC_AHBENR]

MOV32 R0, #DMA1_BASE
MOV32 R1, #(ADC1_BASE + ADC_DR)
STR   R1, [R0, #DMA_CPOR1]
MOV32 R1, #0x20001000
STR   R1, [R0, #DMA_CMAR1]
MOV   R1, #1
STR   R1, [R0, #DMA_CNDTR1]
MOV   R1, #0x3523
STR   R1, [R0, #DMA_CCR1]
Все это получилось сделать только с JTAG, а симулятор упорно отказывается преобразования АЦП делать. Тут уж и не знаю что делать.

Остался еще один вопрос, как посмотреть сколько раз в секунду выполняется преобразований, чтобы подтвердить или опровергнуть мои догадки по таймеру?
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
05.12.2013, 15:14 11
Вопрос - почему был выбран режим Compare/Capture и триггер TIMx_CCx а не простой счет и триггер TIMx_TRGO ?
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
05.12.2013, 15:17 12
Цитата Сообщение от wypuk
Остался еще один вопрос, как посмотреть сколько раз в секунду выполняется преобразований, чтобы подтвердить или опровергнуть мои догадки по таймеру?
Можешь в прерывании по EOC лапкой подергать ...
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
05.12.2013, 15:43 13
Цитата Сообщение от wypuk
2) Бит CAL должен устанавливаться вместе с ADON, это запускает калибровку или преобразование (когда и другие настраиваемые биты записываются в CR2). Я пробовал для интереса битбандингом установить только бит CAL при включенном ADON - фокус не прошел.
Ох уж эти асмисты ... :)
Все там работает . Если битбанд не прошел - или ADC не попадает под битбанд(честно скажу не уверен) либо что то нахимичил.
Люди кстати советуют сбросить регистры калибровки перед калибровкой....
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
05.12.2013, 22:46 14
Цитата Сообщение от dosykus_2
Вопрос - почему был выбран режим Compare/Capture и триггер TIMx_CCx а не простой счет и триггер TIMx_TRGO ?
Мне необходимо выполнить измерение 3х сигналов синхронно 3-мя АЦП. А запустить одновременно все три АЦП одним таймером можно только в режиме Compare/Capture. Причем чтобы еще и дма использовать можно было для всех трех, придется еще 1й и 2й ацп вязать вместе.
0
wypuk
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
21.12.2013, 14:49 15
Появился один вопрос, связанный с discontinuous режимом.
Настраиваю этот режим для injected group с запуском по сигналу TRGO при переполнении таймера Tim2.
По идее согласно ДШ по 1-му сигналу TRGO должно начаться преобразование канала JSQR1, по 2-му сигналу TRGO - JSQR2, по 3-му сигналу TRGO - JSQR3, по 4-му сигналу TRGO - JSQR4 и после завершения должно вылететь прерывание.
Что получается у меня: по 1-му сигналу TRGO начинается преобразование канала JSQR1 и после завершения вылетает прерывание, по 2-му сигналу TRGO - JSQR2 и опять прерывание, и т.д.
Возможно, это глюк симулятора. Но в этом не могу быть уверен на 100%, т.к. при работе с JTAG тоже не все очевидно.
Настройки такие:
Код
ADC_JSQR = 0x003294A5 (JL[1:0]=11, JSQ(1-4)[4:0]=00101);     все 4 канала настроенные на 5й пин каждый
ADC_CR1  = 0x00001080 (JDISCEN=1, JEOCIE=1);
ADC_CR2  = 0x0000A001 (JEXTTRIG=1, JEXTSEL[2:0]=010, ADON=1).
Код инициализации
Код
                ; Инициализация таймера TIM2

MOV32 R0, #RCC_BASE           ; Включаем тактирование таймера
MOV32 R1, #TIM2EN
STR   R1, [R0, #RCC_APB1ENR]  ; Сидит на шине APB1

MOV32 R0, #TIM2_BASE
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_PSC]     ; Задаем предделитель /1
MOV   R1, #0x2BF1
STR   R1, [R0, #TIMx_ARR]     ; Максимальное значение счета
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_CNT]     ; Обнуление счетчика
MOV   R1, #0x0020
STR   R1, [R0, #TIMx_CR2]     ; Режим ведущего сигнал обновления генерирует TRGO
MOV   R1, #0x0085
STR   R1, [R0, #TIMx_CR1]     ; Запускаем таймер

; Инициализация АЦП

MOV32 R0, #ADC1_BASE
MOV   R1, #0x0001
STR   R1, [R0, #ADC_CR2]      ; Включили АЦП ADON = 1
MOV   R1, #0x00FF
M4              SUBS  R1, #1
BNE   M4                      ; Подождали
MOV   R1, #0x0009
STR   R1, [R0, #ADC_CR2]      ; Сбросили калибровку
M5              LDR   R1, [R0, #ADC_CR2]
ANDS  R1, #0x00000008
BNE   M5                      ; Ждем пока не сбросится флаг сброса калибровки
MOV   R1, #0x0005
STR   R1, [R0, #ADC_CR2]      ; Запускаем калибровку
M6              LDR   R1, [R0, #ADC_CR2]
ANDS  R1, #0x00000004
BNE   M6                      ; Ждем пока не сбросится флаг калибровки
LDR   R1, [R0, #ADC_DR]       ; Читаю калибровочное значение
ADD   R1, #0x07FF             ; Добавляю к калибровке смещение по оси Y
STR   R1, [R0, #ADC_JOFR1]    ; Регистр смещения инжектированных каналов
STR   R1, [R0, #ADC_JOFR2]
STR   R1, [R0, #ADC_JOFR3]
STR   R1, [R0, #ADC_JOFR4]
MOV32 R1, #0x00038000
STR   R1, [R0, #ADC_SMPR2]    ; Время выборки 5го канала 239,5 циклов
MOV32 R1, #0x003294A5
STR   R1, [R0, #ADC_JSQR]     ; Подключено к 5му входу все 4 канала инжект посл-ти
MOV32 R1, #0x00001080         ; Задаем режим работы АЦП !!!! Режим прерывающегося преобразования
STR   R1, [R0, #ADC_CR1]      ; JEOCIE = 1
MOV32 R1, #0x0000A001
STR   R1, [R0, #ADC_CR2]      ; Запуск по внешнему сигналу TIM2 TRGO event, старт АЦП
0
21.12.2013, 14:49
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.12.2013, 14:49

Быстрый АЦП (~30MHz) - как считать в STM32F4?
Добрый день специалистам! Такой вопрос возник. Делаю устройство на STM32F4, и мне там надо...

АЦП ловит сетевые 50 герц. Как избавиться?
Здравствуйте, уважаемые форумчане! Я снимаю с частотой 2КГц значения с АЦП. И присутствует помеха...

STM32F030F4P6 АЦП
Добрый день - пытаюсь настроить АЦП на данном микроконтроллере STM32F030F4P6 - 3 канала. Но первое...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.