Я включил передачу периферийных устройств DMA в память для ADC1 в CubeMX и сгенерировал код. Однако я не понимаю, куда будут записываться данные из АЦП? Должен ли я явно определять переменную для хранения этих данных? Как я могу получить данные в ISR канала 1 DMA?
Где DMA хранит значения АЦП в STM32?
Ответы (4)
DMA не управляет памятью и не выбирает действительный адрес для установки данных. Вообще говоря, DMA позволяет передавать данные без использования ЦП, но не более того.
Микроконтроллеры STM32 обеспечивают передачу от:
- память в память
- память на периферийное устройство
- периферийное устройство в память
Во всех из них разработчики должны знать о своей цели, чтобы настроить (помимо DMA) места источника и назначения, такие как адрес периферийных устройств, резервная память (и какой тип памяти) и т. Д.
В вашем конкретном случае (отметьте RM, AN, docs и т. Д. периферийное устройство в память) переносятся:
- Источник: периферийное устройство АЦП, разработчик должен знать, где находится периферийное устройство АЦП, и настроить (помимо АЦП) DMA на основе параметров АЦП в качестве источника информации.
- Назначение: память, разработчик должен зарезервировать кучу памяти (куча / стек / глобальная / и т. Д.) И настроить DMA в соответствии с уже выделенным пространством памяти. При этом DMA позволит вам устанавливать значения по-разному (в зависимости от устройства), например, непрерывный кольцевой буфер, один цикл, буфер для пинг-понга (stm32 использует термин «двойной кольцевой буфер») и т. Д.
- Конфигурация DMA и ADC: существует огромное количество факторов, которые для простоты я не буду включать, обычно упрощенные производителем HAL (использовать его вам).
Вы указываете драйверу HAL DMA ADC, куда поместить образцы данных при запуске преобразования:
volatile uint32_t adcBuffer[SAMPLE_COUNT];
HAL_ADC_Start_DMA( &hadc,
adcBuffer,
SAMPLE_COUNT );
Обратите внимание, что некоторые части STM32 имеют SRAM, разделенную на несколько шин, причем одна секция намного меньше, чем другие. Резервирование этого раздела для буферов DMA дает преимущества в производительности, так как это снижает конкуренцию на шине с помощью обычных программных выборок данных. Таким образом, вы можете настроить свой сценарий компоновщика для создания разделов и явного размещения буферов DMA в одном, исключая размещение в них данных приложения.
Если вы посмотрите документы и примеры HAL, вы найдете пример того, как использовать ADC с DMA.
Суммируя :
Чтобы начать преобразование, вы используете функцию:
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
Где pData - ваша переменная / массив, куда DMA должен поместить данные.
DMA и uC ничего не знают о переменных. Периферийное устройство DMA имеет два регистра конфигурации, в которых вы храните периферийный адрес и адрес памяти. Если вы начнете с чтения документации uC вместо HAL, все сразу станет ясно
DMA
обозначает прямой адрес памяти. Это означает, что АЦП будет писать прямо в адрес памяти, который вы ему предоставили. Итак, сначалаuint16_t adcvalues[10];
, затем настройте DMA для записи 10 значений в указательadcvalues
, дождитесь завершения, затем вы читаете значения только изadcvalues
. - person KamilCuk   schedule 08.03.2019volatile
, иначе вы можете получить всевозможные странные ошибки оптимизации. Вы также должны учитывать возможность повторного входа между оборудованием DMA и вашим приложением. - person Lundin   schedule 08.03.2019