Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

stm32 измерение переменного напряжение.

Пт мар 11, 2022 23:11:36

У меня вопрос не только о измерении переменного напряжения .А и как замедлить пульсирующий ток что бы можно было увидеть на lcd

Re: stm32 измерение переменного напряжение.

Пт мар 11, 2022 23:28:36

Оверсемплинг с частотой на порядок выше частоты измеряемого напряжения (тока), затем вычисления.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 07:36:36

Оверсемплинг с частотой на порядок выше частоты измеряемого напряжения (тока), затем вычисления.

Оверсемплинг -что это такое.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:31:14

На порядок выше фигня получится. Нужно хотя бы сотню сэмплов на период: тогда и почистить от шума получится, и даже True RMS измерить, если не синусоидальный сигнал.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:36:58

Вы имеете ввиду что можно замер 100 сделать.А это можно в цикле оператор for&

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:40:04

Да элементарно же: если делаем 100 измерений на каждый период и хотим 10 периодов обработать, нужно выделить буфер в оперативке на 2кБ. Дальше пинаем при помощи таймера DMA и собираем эту 1000 измерений, после чего обрабатываем.
Если частота неизвестна, то принцип тот же самый, но сначала пытаемся замерить частоту. Здесь уже проще: можно и по десятку измерений на период сделать. Т.е. если рассчитываем на то, что частота не выше килогерца, проводим измерения с частотой в 10кГц, затем обрабатываем, выясняем точную частоту, запускаем заново уже с перенастроенным таймером.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:48:36

Частота пульсации 100гц
А без таймера можно?.Так как кол-во таймеров ограниченно.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:52:15

Синхронизируйте АЦП по экстремуму (точка смены знака вектора). Можно синхронизироваться не сам АЦП (что трудно, требует отдельной схемы) а в массиве преобразования с запасом т.е. более нескольких периодов Ваших 100 Гц как это делают в цифровых скопах, правда там для достижения синхронизации в наносекунды используют FPGA на гигагерц, Вам этого не нужно и микроконтроллер справиться с синхронизацией 100 Гц сигнала. Найти точку смены знака вектора напряжения алгоритмически не трудно. После синхронизации выполняйте вычисления среднеквадратичного напряжения по паре тройке оцифрованных периодов Ваших 100 Гц.
Последний раз редактировалось astrahard Сб мар 12, 2022 11:59:41, всего редактировалось 1 раз.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 11:59:17

Нет, без таймера ничего не получится. Ты никак не сможешь обеспечить надежное постоянство интервалов!
Что ж ты там с таймерами-то делаешь, что из 7-9 таймеров у тебя ни одного ни осталось?

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 12:11:25

У меня в stm32f103 4 таймера.Один для кнопок.Другой для срабатывания ацп с задержкой.А третий для старта(пуска) эл .двигателя.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 12:17:01

Другой для срабатывания ацп с задержкой.

Вот его для пинания DMA и используй!
Для кнопок вообще таймер не нужен: используй SysTick для отсчета миллисекунд, по значению системного времени и определяй антидребезговую паузу. Вот так.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 12:29:50

Нет, без таймера ничего не получится. Ты никак не сможешь обеспечить надежное постоянство интервалов!
Что ж ты там с таймерами-то делаешь, что из 7-9 таймеров у тебя ни одного ни осталось?

Ну да, хотя, самозапуск следующего преобразования АЦП может обойтись и без таймера. Таймером может выступить и ДМА шины APB. Тут главное (по опыту кода скопов на STM32) временно остановить ядро, чтобы не нарушать тайминги ДМА для шины APB. А, в случае медленного АЦП по таймеру мы рискуем получить джиттер момента начала преобразования АЦП. Вот такие тонкости влияющие на точность. Ну или ДМА АЦП для APB присвоить найвысший приоритет, что логичней. Темп преобразования АЦП определяет время заряда конденсатора УВХ (устройство выборки хранения) АЦП и, влияет на его входное АЦП сопротивление, что тоже нужно учесть. И последнее, оверсемплинг выше необходимого для восстановления 100 Гц может повысить разрядность АЦП, что повысит точность среднеквадратичного. Нюансов много, ка видите.... :)) Есть еще нюансы не упомянутые....

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 13:36:29

У меня в stm32f103 4 таймера.Один для кнопок.Другой для срабатывания ацп с задержкой.А третий для старта(пуска) эл .двигателя.


Что-то мне кажется, Вы топорно используете периферию.
У меня есть проект управления кулерами (6 штук) с цифровыми термометрами (4 штуки), экраном, кнопками, подсветкой и меню. Не совсем меню, по сути, но работает за него.
И вот там... используется ДВА таймера. TIM2 (ch1~ch4) на управление кулерами 1-4, TIM3(ch1-ch3) на управление кулерами 5-6 и подсветкой экрана.
Кнопки опрашиваются в основном цикле. Стандартно, используя по 1 байту на каждую кнопку (счётчик для цифрового фильтра). Длительное нажатие и двойное нажатие - не реализовывались, т.к. не требуются.
В том же цикле идёт игра со всеми One-Wire датчиками.
Из периферии задействовано:
SPI -> LCD
TIM2 + TIM3 -> FAN PWM(6) + LCD_PWM(1)
SysTick -> милисекундный таймер + пробуждение
DMA + USART -> Консоль управления в сторону ПК для управления... со стороны ПК. Тафталогия, но работает.
GPIO + EXTI -> для измерения скорости враащения кулеров.
PVD -> Реакция на пропадание питания. Обычно не срабатывает. Если сработает - проблема на стороне преобразователя питания.
I2C -> Внешняя EEPROM память для хранения настроек кулеров.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 14:01:50

У меня таймера используются в прерывании.Я не понимаю как их использовать с ДМА.АЦП понимаю USART тоже.А вот таймера?

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 15:04:46

Eddy_Em писал(а):Нужно хотя бы сотню сэмплов на период: тогда и почистить от шума получится, и даже True RMS измерить, если не синусоидальный сигнал.
Ложим в прерывании ДМА, половинка и полный, 300к с лихуем отсчетов, и без синхронизации и таймеров, хоть синус хоть меандр хоть ШИМ, а далее хоть трумс хоть среднее хоть квадратное.

Эту тему проходили, даже код где-то есть, скучно, давайте что нибудь другое.
:tea:

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 15:30:13

Это ж сколько оперативы нужно на 300 тысяч отсчетов? Где ты видел недорогой STM32 с мегабайтом ОЗУ?
Ну и да: если тупо делать непрерывные измерения, невозможно гарантировать, что они имеют равноотстоящие отсчеты по времени. Да и промежутки между измерениями неизвестны с нужной точностью. Частоту не измеришь.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 17:03:51

Eddy_Em писал(а):Это ж сколько оперативы нужно на 300 тысяч отсчетов? Где ты видел недорогой STM32 с мегабайтом ОЗУ?
stm32f030f4p6
Эту тему перетрясли и в разделе STM и в разделе AVR.

Добавлено after 3 minutes 20 seconds:
Eddy_Em писал(а):если тупо делать непрерывные измерения, невозможно гарантировать, что они имеют равноотстоящие отсчеты по времени.
С чего это ты взял?
Eddy_Em писал(а):Да и промежутки между измерениями неизвестны с нужной точностью.
И это с чего?
Eddy_Em писал(а):Частоту не измеришь.
А для чего ее мерить, особенно сетевые 50Гц?
Не, если речь идет о каком нибудь дизель-генераторе, то ...

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 17:19:44

У меня таймера используются в прерывании.Я не понимаю как их использовать с ДМА.АЦП понимаю USART тоже.А вот таймера?


Кусок кода из моего проекта:
Спойлер
Код:
void init(void) {
   DBGMCU->CR |= DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP;
   RCC->AHBENR = RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOFEN | RCC_AHBENR_DMAEN | RCC_AHBENR_SRAMEN; // All GPIO + DMA, Enable SRAM during sleep mode.

<...>

   // ADC
   ADC1->CR = ADC_CR_ADCAL;      // Run calibration
   while (ADC1->CR & ADC_CR_ADCAL) {};   // Wait till done
   ADC1->CR = ADC_CR_ADEN;         // Enable ADC
   ADC1->SMPR = 4;            // 41.5 ADC clocks to aquire voltage
   delay_ms(2);
   ADC1->CR = ADC_CR_ADEN | ADC_CR_ADSTART;
   while ((ADC1->ISR & ADC_ISR_EOC) == 0) {};
   ADC_Value = (ADC1->DR * 1730) / 1000;
   
   // ADC DMA
   SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_ADC_DMA_RMP;
   DMA1_Channel1->CCR = DMA_CCR_PL_0 | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_TCIE;
   DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR);
   DMA1_Channel1->CNDTR = Len;
   DMA1_Channel1->CMAR = (uint32_t)&(Samples);
   NVIC_SetPriority(DMA1_Channel1_IRQn, 7);
   NVIC_EnableIRQ(DMA1_Channel1_IRQn);
   // TIM1 Update used as TRGO (Trigger Out)
   TIM1->CR2 = TIM_CR2_MMS_1;
   // 16MHz / 2500 = 6400Hz -> 80ms to 512 samples
   // 20MHz / 6400Hz = 3125 -1 = 3124, but... let it bee~ in run time.
   TIM1->ARR = (SystemCoreClock / 6400) - 1;
   TIM1->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
   // ----------


};


int main (void) {

<...>
   init();

   while (1) {
   <...> main loop code
// ----------
   ADC1->CR = ADC_CR_ADDIS;      // Disable ADC
   while (ADC1->CR & ADC_CR_ADEN) {};   // Wait till OFF
   ADC1->CFGR1 = ADC_CFGR1_EXTEN | ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_DISCEN;
   ADC1->CHSELR = (1 << 2);   // Channel 2 [Radio ADC]
   ADC1->CR = ADC_CR_ADEN;         // Enable ADC
   while (!(ADC1->ISR & ADC_ISR_ADRDY));   // Wait till ready.
   TIM1->CR1 |= TIM_CR1_CEN;
   ADC1->ISR = 0x1F;         // Clear flags.
   ADC1->CR = ADC_CR_ADSTART;      // Required!
   DMA1_Channel1->CNDTR = Len;
   DMA1_Channel1->CCR |= DMA_CCR_EN;
// ----------
   <...>
   __WFI();



Пропуская то, что я привёл только фукнцию инициализации АЦП и канала DMA, а так же код, который запускает преобразование, не добавив массивы... это всё работает.
В моём случае, оцифровывается 40мс сигнала с частотой выборок в 6400 сэмплов в секунду, получая 512 сэмплов в массиве:
Код:
#define Len      512
volatile short Samples[Len] __attribute ((aligned (4)));

После заполнения массива, срабатывает прерывание DMA:
Код:
void DMA1_Channel1_IRQHandler(void) {
   DMA1->IFCR = 0x0000000F;   // Clear ALL bits.
   DMA1_Channel1->CCR &= ~DMA_CCR_EN;
   TIM1->CR1 &= ~TIM_CR1_CEN;
   ADC_Samples_Ready = 1;
};

... взводит переменную-флаг ADC_Samples_Ready, указывающую на то, что буфер заполнен.
После чего в СЛЕДУЮЩИЙ проход по основному же циклу, процессор проверяет эту переменную (кстати, volatile, иначе компилятор посчитает, что переменную в основном цикле не меняют, значит код можно выбросить), видит что в ней вдруг (для компилятора - очень неожиданно, если переменная не volatile) появилось число отличное от 0, сбрасывает эту переменную, и даёт массив сэмплов в функцию обработки FFT.
Всё это крутится на STM32F030F4P6, том маленьком чипе с 20 ножками. На 20МГц обработка спектра выполняется за 20-30мс. Забыл точное время, но не суть важно.

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

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 17:53:49

Таймер запускает АЦП. АЦП преобразует несколько каналов. ПДП пересылает отсчёты в память. ПДП был настроен на кольцевой режим и генерацию прерываний по заполнению половины и полного буфера. Пока обсчитывали одну половину, заполнялась вторая. 9 каналов, 2000 отсчётов в секунду в каждом, частота входного сигнала 30-60 Гц. Измеряли период и частоту в опорном канале, в остальных среднее, среднее квадратическое, минимальное и максимальное значения.

Re: stm32 измерение переменного напряжение.

Сб мар 12, 2022 21:21:07

Если взять минимальное ADC_SampleTime_239_5Cycles, 18мкс на отсчет АЦП, и для 9 каналов, то за 1 секунду можно положить 6172 отсчета для каждого канала.
А частота входного сигнала - где то до ~3кГц.
А период и частоту входного сигнала измерить с помощью таймера, который как раз и предназначен для этого.
Ответить