В микроконтроллерах 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



... /* 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); ... } ... } |


(2 оценок, среднее: 3,50 из 5)