|
Помогите поднять АЦП в камне STM32L476, На плате Nucleo. Опять закипел. |
|
|
|
May 26 2016, 17:21
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(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 отсчетов.
Сообщение отредактировал IgorKossak - May 26 2016, 17:29
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
May 27 2016, 09:33
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(Obam @ May 27 2016, 11:42)  ТС, а вы точно уверены в названии проца, который естествуете? В линейке F4xx такого как бы не значится, а следовательно, RefMan от чего вы читаете (если читаете (; )?
"//При CONT = 1 почему - то неозможно сбросить бит EOC. Код виснет в прерывании."
Под отладчиком, останавливаясь в обработчике, вы пытаетесь соревноваться в скорости с АЦП, молотящим в непрерывном режиме преобразования. Уверяю вас он существенно быстрее человека (; Прошу прощения. Проц STM32L476. Код виснет не под отладчиком. Собственно, мне этот режим не нужен. Я однократный использую с програмным стартом. Раз уж речь зашла - непонятно зачем городить очередь из 16-ти шагов преобразования если регистр для регулярной очереди 1. Все равно после каждого преобразования надо в прерывании (или как еще) забирать данные. Преимущество может быть разве что в DMA. Я с ним еще не работал.
|
|
|
|
|
May 27 2016, 16:38
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(Димон Безпарольный @ May 27 2016, 19:12)  Да это понятно, только переключение каналов софтовое - одна строка на Си или штук пять команд на ассемблере. Если проц работает на 80МГц - совсем ничто. Софтовое переключение каналов АЦП - это что-то из древности, когда других возможностей не было, тип старых Атмег. Неслучайно реализация блоков АЦП становится всё сложнее и сложнее, значит это кому-то нужно. Не забывайте, что при отработке аппаратной последовательности измерений, когда Вы забираете очередной результат (неважно по прерыванию, или посредством DMA), уже идёт следующее преобразование, без пауз. Когда Вы захотите обеспечить 1-2 миллиона преобразований в секунду, терять время на программное переключение каналов не получится.
|
|
|
|
|
May 28 2016, 17:51
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

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

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Димон Безпарольный @ Jun 7 2016, 21:09)  Только там не говорится как при подпоследовательности в 16 преобразований и одном буфере определить номер текущего канала. Кому принадлежат данные? Вот приплыли ы в прерывание с очередным результатом. И как определить номер канала откуда пришли данные? Объявите структуру из 16 результатов преобразования (каждому результату можно дать осмысленное имя нужного канала), создайте массив из этих структур, натравите ПДП (DMA) в кольцевом режиме на этот массив, получив прерывание ПДП об окончании половины пересылки обрабатываете первую половину массива (все данные уже разложены в структуры), получив прерывание об окончании пересылки - обрабатываете вторую половину массива. Все. Больше никаких телодвижений по настройкам АЦП, ПДП и т.п. делать не нужно - оно работает само, знай себе выгребай данные в прерывании ПДП.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 8 2016, 09:18
|

Знающий
   
Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663

|
Цитата(Димон Безпарольный @ Jun 7 2016, 22:09)  Замечательный документ. С картинками. Красиво. С примерами использования. А главное, пояснено что такое "injected channels" и как с ними бороться. Цитата Только там не говорится как при подпоследовательности в 16 преобразований и одном буфере определить номер текущего канала. Кому принадлежат данные? Вот приплыли ы в прерывание с очередным результатом. И как определить номер канала откуда пришли данные? Про DMA уже рассказано, а без него: вести индекс в 16 (к примеру) массивах и использовать задержку (аппаратную, заметьте) запуска очередного измерения в цепочке до момента вычитывания DR. Ну и условие существенно большей скорости ядра (намёк на быструю реакцию) чем АЦП, я надеюсь, не менялось.
--------------------
Пролетарий умственного труда.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|