Использование ADC с DMA на stm32 micrcontroller

Наиболее полученным криком помощи, который я получаю от многих людей, является использование DMA с ADC для непрерывного преобразования аналоговых входов датчиков. Поэтому я принял решение поделиться необходимыми шагами, чтобы настроить его (а также избежать дублирования моего ответа каждый раз).

Я воспользуюсь проектом STM32Cube, чтобы сделать его легким, и я признаю, что у вас уже есть программное обеспечение stm32cubemx и установленная Прошивка Stm32cubef4. Если все в порядке, давайте начнем, то и для других людей они могут следовать ссылки для установки инструмента и прошивки.

Откройте инструмент STM32CubeMX и нажмите на "новый проект" я выбрал из списка микроконтроллер STM32F439BITx. Вы можете выбрать свой собственный, если вы используете определенную доску. Я думаю, что все АЦП в микроконтроллерах STM32 имеют эту функцию.

 

После этого Сформируйте представление Pinout инструмента, разверните ADC peripheral и выберите три внутренних канала (Temperature / Vref и Vbat ). Вы можете выбрать свой собственный, но я использовал эти три канала в качестве демонстрации в этом уроке.

Во втором случае все, что у вас есть, - это подключение аналоговых входов к контактам каналов. Выбранный канал окрашен в зеленый цвет в микроконтроллере или вы можете работать наоборот, выбрав первый ваш pin-код в качестве ADC ввода с помощью правой кнопки мыши на нем. (exp PA0

Теперь пришло время настроить ADC для работы, как мы хотим, (да, и DMA тоже ;)). Так нажмите на АЦП и добавить три регулярных конфигурации канала для преобразования. Также не забудьте включить режим сканирования и непрерывный режим, чтобы иметь непрерывное преобразование трех настроенных каналов.

Теперь перейдите на вкладку "настройки DMA", добавьте запрос DMA, выбрав поток и приоритет. Также включите инкремент памяти, потому что мы будем хранить все преобразованные значения в массиве. Используемый режим является циклическим, потому что у нас будет продолжение передачи слова (Ширина данных).

Нажмите Ok, сгенерируйте проект и откройте его (я использую iar wokbench у вас есть возможность выбрать Keil или TrueSTUDIO тоже). Мы добавим некоторые дополнительные код, чтобы завершить наши демо: в основному.с файл мы объявим 32-битный массив, и мы начнем АЦП и ДМА по телефону HAL_ADC_Start() иHAL_ADC_Start_DMA()После каждого преобразования значение передается из регистра данных ADC в массив, и DMA автоматически увеличивает индекс.

01 1:  /* USER CODE BEGIN PFP */
02 2:  uint32_t ADC1ConvertedValues[1024]; 
03 3:  /* USER CODE END PFP */
04 4:  int main(void
05 5:  { 
06 6:   /* MCU Configuration----------------------------------------------------------*/
07 7:   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
08 8:   HAL_Init(); 
09 9:   /* Configure the system clock */
10 10:   SystemClock_Config(); 
11 11:   /* Initialize all configured peripherals */
12 12:   MX_GPIO_Init(); 
13 13:   MX_DMA_Init(); 
14 14:   MX_ADC1_Init(); 
15 15:   /* USER CODE BEGIN 2 */
16 16:   // -- Enables ADC and starts conversion of the regular channels. 
17 17:   if( HAL_ADC_Start(&hadc1) != HAL_OK) 
18 18:    return 0; 
19 19:   // -- Enables ADC DMA request 
20 20:   if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC1ConvertedValues, 2048) != HAL_OK) 
21 21:    return 0; 
22 22:   /* USER CODE END 2 */
23 23:   /* Infinite loop */
24 24:   while (1){} 
25 25:  } 


Все преобразованные значения передаются и хранятся в ADC1ConvertedValues , который является массивом 1ko размера. Значения хранятся в порядке преобразования (Датчик температуры, затем Vref, затем Vbat).

Это живые часы ADC1ConvertedValues во время выполнения демо.

чтобы получить такого рода информацию может быть, вы должны прочитать 1718-странице документации.Но вам нужна только одна страница, чтобы найти ответ на Ваш вопрос. Итак, как вы сказали, у нас есть массив 1024 элемента uint32_t, и я поставил 2048 как длину данных функции HAL_ADC_Start_DMA ().

В этом случае преобразованное значение АЦП кодируется в 16-битном виде в регистре ADC_DR (действительное значение-в 12 битах в соответствии с нашим разрешением). С другой стороны, Размер нашего элемента массива составляет 32 бита. Таким образом, число передачи данных (сохраненных в регистре DMA_SxNDTR) должно быть кратным 2 (1024*2=2048), иначе мы потеряем некоторые данные.Это ограничение указано в таблице 47 справочного руководства семейства stm32f4.

В циклическом режиме число передаваемых элементов данных автоматически перезагружается с начальным значением, запрограммированным во время фазы настройки потока (хранящейся в регистре DMA_SxNDTR), и запросы DMA продолжают обслуживаться. ваше объяснение является правильным, и вы получите это поведение для транзакции DMA.

ждем Вас в любое время и простите за запоздалый ответ.

Комментарии

скажем, что DMA прерывания в случае, если вы хотите, чтобы поймать одного из этих событий: передачи данных DMA полный/ ДМА половину полный/ ДМА ФИФО об ошибке/ ДМА прямой режим ошибки/ ошибка передачи данных DMA. Обратные вызовы этих функций определяются в указателе 'hdma_adc1' (L lock в структуре DMA_HandleTypeDef в stm32f4xx_hal_dma.H файл).

Настройка производится в функции HAL_ADC_MspInit в созданном файле stm32f4xx_hal_msp.c, таким образом, если вы позволите обратным вызовам как NULL, ни один из них не будет принят во внимание HAL. Это выбор, сделанный, чтобы позволить пользователю контролировать DMA transfert, если он хочет.

Вы можете отключить прерывания DMA, если вы хотите, удалив две строки в /* прерывание DMA init */ comment, а также удалив функцию DMA2_Stream0_IRQHandler в stm32f4xx_it.C сгенерированный файл.

надеюсь, что я ответил на Ваш вопрос и на исходный код,код, что я такой же, как и сгенерированный код версии 4.8 из CubeMX. все изменения, которые я сделал, сделаны в главной функции и перечислены на статье.

Вы можете отключить прерывания DMA, если хотите, удалив две строки в /* блок прерываний DMA */ comment, а также удалив функцию DMA2_Stream0_IRQHandler в stm32f4xx_it. C сгенерированный файл.

Надеюсь, что я ответил на Ваш вопрос и исходный код, код, что я такой же, как и сгенерированный код на 4,8 версии CubeMX. все изменения, которые я сделал, сделаны в главной функции и перечислены в статье.

Добавить комментарий

Обратная связь

Интересуют вопросы реализации алгоритмов, программирования, выбора электроники и прочая информация, постараюсь осветить в отдельных статьях

пишите мне на netdm@mail.ru