ADC + DMA

В микроконтроллерах STM32 H7 имеются превосходные 16-битные ADC (АЦП), которые позволяют с высокой частотой и точностью менять напряжения на множестве указанных ножек.

Данный мануал также подойдет и для других микроконтроллеров STM32.

Так как на ножку ADC можно подавать напряжение от 0 до 3.3 V, то для замеров больших напряжений нужно будет использовать резистивный делитель (с рекомендациями по расчету делителя вы можете ознакомиться в видео выше).

Так как на отладочных платах линия питания 3.3 V имеет большие пульсации, то, для измерения напряжения нужно будет сделать несколько выборок (10, 100, 1000…) и затем их усреднить для получения точного значения напряжения.

Если запитать аналоговую часть микроконтроллера (вместе с VREF+) отдельным «чистым» напряжением (без пульсаций), то можно сразу получать точные значения напряжений уже без значительных усреднений.

Примечание: Не все микроконтроллеры и отладочные платы имеют выводы VDDA, VREF+ (обычно они подтянуты к VDD микроконтроллера).

Замеры напряждений в STM32CubeIDE можно производить несколькими разными способами:
1) Одиночный замер без использования прерывания (процессор приостановит работу и будет ждать завершения выполнения замера);
2) С использованием прерываний (запуск замера производится из бесконечного цикла и процессор сразу же выполняет следующие операции, но нужно будет обработать прерывание окончания замера напряжения);
3) С использованием DMA (ADC самостоятельно меряет напряжения и записывает полученные значения в указанный массив (буфер), эти значения можно будет читать в любое время из бесконечного цикла, тем самым мы не тормозим процессор).

Как видно, в большинстве проектов необходимо использовать DMA!!!

Следует отметить, если нужно редко измерять напряжения и кратковременные приостановки работы процессора не критичны, можно мерять напряжение без прерываний и DMA следующим образом

int main(void)
{
  ...
  MX_ADC2_Init();
  /* USER CODE BEGIN 2 */
  HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
  ...
  uint32_t MeasuredValue = 0;
  while (1)
  {
    HAL_ADC_Start(&hadc2);
    HAL_ADC_PollForConversion(&hadc2,10);
    MeasuredValue= HAL_ADC_GetValue(&hadc2);
    ...
  }
  ...
}

Где MeasuredValue — RAW данные напряжения с ADC.


Теперь про ADC + DMA

STM32 H7 ADC DMA

STM32 H7 ADC DMA

STM32 H7 ADC DMA

...
/* USER CODE BEGIN PTD */
uint32_t ADC2Data[100] = {0,}; /// В этот массив ADC (+DMA) будет сам складывать полученные замеры, поочередно и циклично обновляя ячейки массива
...
int main(void)
{
  ...
  MX_ADC2_Init();
  /* USER CODE BEGIN 2 */
  HAL_ADCEx_Calibration_Start(&hadc2,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); /// Автоматическая калибровка ADC
  HAL_ADC_Start_DMA(&hadc2,(uint32_t*)&ADC2Data,100); /// Запускаем ADC и он будет постоянно обновлять значения массива ADC2Data
  ...
  uint32_t ADCDataSamplesSUM = 0;
  uint16_t j = 0;
  while (1) /// Бесконечный цикл
  {
    ...
    /// Теперь суммируем все элементы массива в переменную ADCDataSamplesSUM для получения усредненного значения напряжения
    j = 0;
    ADCDataSamplesSUM = 0;
    while (j < 100)
    {
      ADCDataSamplesSUM += ADC2Data[j];
      j++;
    }
 
    /// Далее делим полученную сумму всех замеров на коэффициенты для получения значения напряжения в вольтах или миливольтах (как вам удобно)
    ADCDataSamplesSUM = (ADCDataSamplesSUM / 0.981);
    NEXTION_SendNum("n0",ADCDataSamplesSUM / 1000);
    ...
  }
...
}



1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (2 оценок, среднее: 3,50 из 5)

Загрузка...

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Optionally add an image (JPEG only)