Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите поднять АЦП в камне STM32L476
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Димон Безпарольный
Прописал конфигурацию:





Прикрутил дисплей SPI. Вывожу ADC1->CR - он спит: 0x20000005 GPIOB->ASCR = 0 - без этого не измерить напряжение на внешнем выводе. ADC123_COMMON->CCR = 0. Вообще непонятно почему. ADC1->SQR1 = 0. Т.е. половину регистров Куб сконфигурировал, тактирование настроил и... бросил. А дальше что? Ручками?

Может у кого есть что - то готовое по регистрам близкое к STM32F476?
scifi
Цитата(Димон Безпарольный @ May 26 2016, 20:05) *
А дальше что? Ручками?

Финиш. Приплыли. Можете ножками попробовать, но если ручки не алё, то шансов крайне мало.
Димон Безпарольный
Цитата(scifi @ May 26 2016, 20:20) *
Финиш. Приплыли. Можете ножками попробовать, но если ручки не алё, то шансов крайне мало.

Да ручками то уже але, только не совсем получилось.

CODE
RCC->AHB2ENR |= 1<<13; //ADCEN - запуск тактирования АЦП стр 225;
RCC->CCIPR |= 3<<28; //System clock selected as ADCs clock стр 243 10000000
ADC1->CR = 0; //DEEPPWD = 0 - пробуждение АЦП 20000005
ADC1->CR = 1<<28; //ADVREGEN - включаем питание АЦП
for(i=0;i<190000;i++) {}; //Ждем T_ADCVREG_STUP
ADC1->CR |= 0x80000000; //ADCAL - запускаем калибровкупри ADEN = 0
while (ADC1->CR & 0x80000000){};//Ждем завершения калибровки
GPIOB->MODER |= (3<<(2*1))|(3<<(2*1));//Analog input mode стр 264
GPIOB->ASCR = 1<<1; //PB1 Connect analog switch to the ADC input стр 270 0

ADC1->CR |= 1| //Разрешить АЦП ADEN
0<<1| //Bit 1 ADDIS: ADC disable command
0<<2| //Bit 2 ADSTART: ADC start of regular conversion
0<<3| //Bit 3 JADSTART: ADC start of injected conversion
0<<4| //Bit 4 ADSTP: ADC stop of regular conversion command
0<<5| //Bit 5 JADSTP: ADC stop of injected conversion command
0<<28| //Bit 28 ADVREGEN: ADC voltage regulator enable
0<<29| //Bit 29 DEEPPWD: Deep-power-down enable
0<<30| //Bit 30 ADCALDIF: Differential mode for calibration
0<<31; //Bit 31 ADCAL: ADC calibration
ADC123_COMMON->CCR = //input ADC clock divided by 256 стр 534 ADC123_COMMON->CCR
0<<0| //Bits 4:0 DUAL[4:0]: Dual ADC mode selection
0<<8| //Bits 11:8 DELAY: Delay between 2 sampling phases
0<<13| //Bit 13 DMACFG: DMA configuration (for dual ADC mode)
0<<14| //Bits 15:14 MDMA[1:0]: Direct memory access mode for dual ADC mode
1<<16| //Bits 17:16 CKMODE[1:0]: ADC clock mode
11<<18| //Bits 21:18 PRESC[3:0]: ADC prescaler
1<<22| //Bit 22 VREFEN: V REFINT enable
0<<23| //Bit 23 CH17SEL: CH17 (Temperature) selection
0<<24; //Bit 24 CH18SEL: CH18 (V_BAT) selection

ADC1->SQR1 = 0| //Число каналов преобразования 1 стр 520 0
16<<6| //Номер канала в последовательности 1
16<<12| //Номер канала в последовательности 2
16<<18| //Номер канала в последовательности 3
16<<24; //Номер канала в последовательности 4

ADC1->IER = 1<<2; //Разрешить прерывание по окончанию EOCIE(2) стр 505
NVIC->ISER[0] |= 1<<18; //= 18, ADC12 global Interrupt

//ADC1->CFGR |= 1<<13; //CONT - постоянные преобразования стр 510
ADC1->CR |= 1<<2; //Начать преобразование ADSTART


Код
void ADC1_2_IRQHandler(void)
{
volatile unsigned int i;
    //ADC1->ISR = 1<<2;                //Сбросить бит прерывания
    Dummy = ADC1->DR;                //Хотя он сбрасывается и при чтении ADC3->DR
    ADC1->CR |= 1<<2;                //Начать преобразование ADSTART    

//При CONT = 1 почему  - то неозможно сбросить бит EOC. Код виснет в прерывании.


}


Хотел у Куба ума занять, а Куб не але... Ацп выдает, но какой - то бред от 80 до 2700 отсчетов.
Obam
ТС, а вы точно уверены в названии проца, который естествуете? В линейке F4xx такого как бы не значится, а следовательно, RefMan от чего вы читаете (если читаете (; )?

"//При CONT = 1 почему - то неозможно сбросить бит EOC. Код виснет в прерывании."

Под отладчиком, останавливаясь в обработчике, вы пытаетесь соревноваться в скорости с АЦП, молотящим в непрерывном режиме преобразования. Уверяю вас он существенно быстрее человека (;
Димон Безпарольный
Цитата(Obam @ May 27 2016, 11:42) *
ТС, а вы точно уверены в названии проца, который естествуете? В линейке F4xx такого как бы не значится, а следовательно, RefMan от чего вы читаете (если читаете (; )?

"//При CONT = 1 почему - то неозможно сбросить бит EOC. Код виснет в прерывании."

Под отладчиком, останавливаясь в обработчике, вы пытаетесь соревноваться в скорости с АЦП, молотящим в непрерывном режиме преобразования. Уверяю вас он существенно быстрее человека (;

Прошу прощения. Проц STM32L476. Код виснет не под отладчиком. Собственно, мне этот режим не нужен. Я однократный использую с програмным стартом.

Раз уж речь зашла - непонятно зачем городить очередь из 16-ти шагов преобразования если регистр для регулярной очереди 1. Все равно после каждого преобразования надо в прерывании (или как еще) забирать данные. Преимущество может быть разве что в DMA. Я с ним еще не работал.
Obam
Очередь не "из 16-ти шагов преобразования", а "цепочка" до 16 разных входов, напряжения с которых измеряются последовательно, но в произольном (согласно номерам из SQx[4:0]) порядке, запускаемая одним телодвижением.
"Все равно после каждого преобразования надо в прерывании (или как еще) забирать данные…" - при достаточной разнице в скорости ядра (в пользу ядра) и АЦП это не является большой проблемой.
Димон Безпарольный
Цитата(Obam @ May 27 2016, 13:05) *
Очередь не "из 16-ти шагов преобразования", а "цепочка" до 16 разных входов, напряжения с которых измеряются последовательно, но в произольном (согласно номерам из SQx[4:0]) порядке, запускаемая одним телодвижением.
"Все равно после каждого преобразования надо в прерывании (или как еще) забирать данные…" - при достаточной разнице в скорости ядра (в пользу ядра) и АЦП это не является большой проблемой.

Вот именно. Забрал данные, переключил канал и вышел. Зачем городить очередь с таким (4) количеством регистров?
Obam
Так ведь забрал даннные и вышел - гораздо веселее. А переключение канала это совсем бесплатно? А в любой последовательности?
Вы не забывайте, длина цепочки задаётся вами (L[3:0]). Если 18 каналов раскладывать в цепочку длиной 16, то 32-разрядных регистров и будет 4.
Димон Безпарольный
Цитата(Obam @ May 27 2016, 15:38) *
Так ведь забрал даннные и вышел - гораздо веселее. А переключение канала это совсем бесплатно? А в любой последовательности?
Вы не забывайте, длина цепочки задаётся вами (L[3:0]). Если 18 каналов раскладывать в цепочку длиной 16, то 32-разрядных регистров и будет 4.

Да это понятно, только переключение каналов софтовое - одна строка на Си или штук пять команд на ассемблере. Если проц работает на 80МГц - совсем ничто.
amiller
Цитата(Димон Безпарольный @ May 27 2016, 19:12) *
Да это понятно, только переключение каналов софтовое - одна строка на Си или штук пять команд на ассемблере. Если проц работает на 80МГц - совсем ничто.

Софтовое переключение каналов АЦП - это что-то из древности, когда других возможностей не было, тип старых Атмег.
Неслучайно реализация блоков АЦП становится всё сложнее и сложнее, значит это кому-то нужно.
Не забывайте, что при отработке аппаратной последовательности измерений, когда Вы забираете очередной результат (неважно по прерыванию, или посредством DMA), уже идёт следующее преобразование, без пауз.
Когда Вы захотите обеспечить 1-2 миллиона преобразований в секунду, терять время на программное переключение каналов не получится.
Obam
"У нас свободная страна…" и "Колхоз - дело добровольное…"
Наличие развитой аппаратной реализации чего угодно (не обязательно АЦП) это только "+".
Хотите софтово - делайте софтово: нет никаких препятствий, но AN3116 на сайте ST найдите и прочитайте. Просветлению поспособствует.

Кстати, однократного преобразования с единственного канала стабильно добились?
Димон Безпарольный
Цитата(Obam @ May 28 2016, 17:35) *
"У нас свободная страна…" и "Колхоз - дело добровольное…"
Наличие развитой аппаратной реализации чего угодно (не обязательно АЦП) это только "+".
Хотите софтово - делайте софтово: нет никаких препятствий, но AN3116 на сайте ST найдите и прочитайте. Просветлению поспособствует.

Кстати, однократного преобразования с единственного канала стабильно добились?

Добился. Кондер надо было ставить на вход. Эти АЦП не любят высокоомных источников. Замотался - упустил из виду. Но вариант Куба так и не заработал. Впрочем уже плевать.

Я изучаю тот камень. Поднял SPI, подключил Нокиа 1100, I2C - DS1621, UART с кольцевым буфером, WD. Теперь хочу SPI через DMA подключить...
Димон Безпарольный
Цитата(Obam @ May 28 2016, 17:35) *
"У нас свободная страна…" и "Колхоз - дело добровольное…"
Наличие развитой аппаратной реализации чего угодно (не обязательно АЦП) это только "+".
Хотите софтово - делайте софтово: нет никаких препятствий, но AN3116 на сайте ST найдите и прочитайте. Просветлению поспособствует.

Замечательный документ. С картинками. Красиво. С примерами использования. Только там не говорится как при подпоследовательности в 16 преобразований и одном буфере определить номер текущего канала. Кому принадлежат данные? Вот приплыли ы в прерывание с очередным результатом. И как определить номер канала откуда пришли данные?
Сергей Борщ
QUOTE (Димон Безпарольный @ Jun 7 2016, 21:09) *
Только там не говорится как при подпоследовательности в 16 преобразований и одном буфере определить номер текущего канала. Кому принадлежат данные? Вот приплыли ы в прерывание с очередным результатом. И как определить номер канала откуда пришли данные?
Объявите структуру из 16 результатов преобразования (каждому результату можно дать осмысленное имя нужного канала), создайте массив из этих структур, натравите ПДП (DMA) в кольцевом режиме на этот массив, получив прерывание ПДП об окончании половины пересылки обрабатываете первую половину массива (все данные уже разложены в структуры), получив прерывание об окончании пересылки - обрабатываете вторую половину массива. Все. Больше никаких телодвижений по настройкам АЦП, ПДП и т.п. делать не нужно - оно работает само, знай себе выгребай данные в прерывании ПДП.
Obam
Цитата(Димон Безпарольный @ Jun 7 2016, 22:09) *
Замечательный документ. С картинками. Красиво. С примерами использования.


А главное, пояснено что такое "injected channels" и как с ними бороться.

Цитата
Только там не говорится как при подпоследовательности в 16 преобразований и одном буфере определить номер текущего канала. Кому принадлежат данные? Вот приплыли ы в прерывание с очередным результатом. И как определить номер канала откуда пришли данные?



Про DMA уже рассказано, а без него: вести индекс в 16 (к примеру) массивах и использовать задержку (аппаратную, заметьте) запуска очередного измерения в цепочке до момента вычитывания DR. Ну и условие существенно большей скорости ядра (намёк на быструю реакцию) чем АЦП, я надеюсь, не менялось.
Димон Безпарольный
Цитата(Сергей Борщ @ Jun 8 2016, 10:26) *
Объявите структуру из 16 результатов преобразования (каждому результату можно дать осмысленное имя нужного канала), создайте массив из этих структур, натравите ПДП (DMA) в кольцевом режиме на этот массив, получив прерывание ПДП об окончании половины пересылки обрабатываете первую половину массива (все данные уже разложены в структуры), получив прерывание об окончании пересылки - обрабатываете вторую половину массива. Все. Больше никаких телодвижений по настройкам АЦП, ПДП и т.п. делать не нужно - оно работает само, знай себе выгребай данные в прерывании ПДП.

Спасибо. Полагаю что DMA будет работать в кольцевом режиме. Что при этом указывать в счетчике пересылок? Число каналов?
Сергей Борщ
QUOTE (Димон Безпарольный @ Jun 8 2016, 12:21) *
Спасибо. Полагаю что DMA будет работать в кольцевом режиме. Что при этом указывать в счетчике пересылок? Число каналов?
Ну хоть немного можно же и самостоятельно подумать? Одно преобразование АЦП = 1 канал = 1 пересылка. Если массив из N структур по M каналов в каждой, то всего будет N * M пересылок.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.