Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Померить переменный ток
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
1245
есть датчик тока ACS712 и контроллер STM32. Стоит задача померить переменный ток. Делаю так, но сильно долго получается:

Код
RCC->APB1ENR    |= 0x00000002;                                        
TIM3->PSC = 35;                            
TIM3->EGR    = 0x0001;


  TIM3->CR1 |= 0x00000001;                    //включить таймер
  ADC1->SQR3=0x0008;                        
  TIM3->CNT=0;
  while((TIM3->CNT<5550)==1)                        //один период
  {
   ADC1->CR2 |=0x00400000;                    //запуск преобразования
   while(((ADC1->SR)&0x0002)==0);            
   rms1+=(ADC1->DR-3070)*(ADC1->DR-3070);        
   c1++;                                    //счётчик числа преобразований
  }
  TIM3->CR1 &= ~0x00000001;                  //выключить таймер
  TIM3->CNT=0;                                
  curbuf1c+=sqrt(rms1/c1);                        
  v1++;
  c1=rms1=0;  
  if(v1>=500)                                                            //взять 500 периодов
  {
   current=curbuf1c/v1;
   v1=curbuf1c=0;
  }


можно ли как-то ускорить процесс измерения?
Herz
Так не берите 500 периодов и будет быстрее.
1245
Цитата(Herz @ Jan 25 2013, 09:33) *
Так не берите 500 периодов и будет быстрее.


так тогда точность сильно падает и разброс большой становится(
hd44780
А Вы обычным вольтметром/осциллографом выход датчика смотрели? Может сам датчик подвирает... Или там помехи какие-то лезут, которые проще фильтром порезать, а не гасить их жутким кол-вом итераций.
Я токовым трансом переменку на ATMega16 мерял, мне и полсекунды (25 периодов) хватило. Частоту дискретизации, кажется 10кГц была... Фильтров никаких я не ставил. Осциллом глядел - синусоида абсолютно чистая идёт. Только операционник для смещения синусоиды на полдиапазона вверх и диодный ограничитель на входе АЦП. Но Вам этого вроде не надо, датчик всё это сам делает.

Вы проверяли, какая часть Вашего алгоритма самая прожорливая по времени?
И сколько времени выполняется Ваш код?
Цикл Ваш какой-то странный. А именно проверки условий.. И возведение в квадрат мне не нравится.. Не раз натыкался на чисто компиляторные глюки, когда простые с виду конструкции неправильно работают, потому что их компилятор как-то не так их уразумел.

Попробуйте так:
Код
while(TIM3->CNT<5550)                        //один период
  {
   ADC1->CR2 |=0x00400000;                    //запуск преобразования
   while ( !((ADC1->SR)&0x0002) );            
   temp = ADC1->DR-3070;
   rms1 += temp*temp;        
   c1++;                                    //счётчик числа преобразований
  }


Только переменную temp объявите.
1245
спасибо за совет, а чем Вам не нравятся проверка условий?

Бегу смотреть выходы датчика...
xemul
Цитата(1245 @ Jan 25 2013, 10:18) *
Стоит задача померить переменный ток.

По коду похоже, что даже RMS. Вот и начните с измерения длительности периода.
(если (по точности) Вам достаточно считать её константой, можете не измерять)
Потом разбейте период на достаточное (опять же по точности) число интервалов, настройте соответственно таймер,
по прерыванию таймера запускайте преобразование АЦП,
по прерыванию окончания преобразования 'rms1+=(ADC1->DR-3070)*(ADC1->DR-3070);' (если 3070 не название полироля для ручки грабель, а постоянное смещение на выходе датчика, то это значение нужно измерять/считать),
по счётчику преобразований == числу интервалов сохраняйте sqrt(rms1/(число интервалов)) в (кольцевой) буфер,
в свободное от прерываний время занимайтесь удобной формой фильтрации этого буфера.
Цитата
можно ли как-то ускорить процесс измерения?

Меньше одного (полу)периода не получится.
Можно завести кольцевой буфер на число интервалов, складывать в него (ADC1->DR-3070)*(ADC1->DR-3070) и считать RMS по каждому новому измерению.
ReAl
Цитата(xemul @ Jan 25 2013, 10:48) *
по прерыванию окончания преобразования 'rms1+=(ADC1->DR-3070)*(ADC1->DR-3070);' (если 3070 не название полироля для ручки грабель, а постоянное смещение на выходе датчика, то это значение нужно измерять/считать),
(про полироль понравилось)
Можно считать, можно в явном виде не считать. Меньше вычислений.
В цикле:
Код
    val    = ADC1->DR;
    sum    += val;
    sum_sq += val*val;
В конце цикла
Код
    mean_square = (sum_sq - sum*sum / N) / N;
    // Т.е. тут "(название полироля) в квадрате" размазалось по коду для уменьшения операций
где N — количество отсчётов.
Если завести для val кольцевой буфер, в sum, sum_sq нужно каждый раз вычитать старое из буфера добавлять новое из АЦП, тогда по каждому отсчёту можно выдавать новое (sum_sq - sum*sum / N) / N; с минимумом вычислений.
1245
Цитата(xemul @ Jan 25 2013, 11:48) *
По коду похоже, что даже RMS. Вот и начните с измерения длительности периода.
(если (по точности) Вам достаточно считать её константой, можете не измерять)
Потом разбейте период на достаточное (опять же по точности) число интервалов, настройте соответственно таймер,
по прерыванию таймера запускайте преобразование АЦП,
по прерыванию окончания преобразования 'rms1+=(ADC1->DR-3070)*(ADC1->DR-3070);' (если 3070 не название полироля для ручки грабель, а постоянное смещение на выходе датчика, то это значение нужно измерять/считать),
по счётчику преобразований == числу интервалов сохраняйте sqrt(rms1/(число интервалов)) в (кольцевой) буфер,
в свободное от прерываний время занимайтесь удобной формой фильтрации этого буфера.

Меньше одного (полу)периода не получится.
Можно завести кольцевой буфер на число интервалов, складывать в него (ADC1->DR-3070)*(ADC1->DR-3070) и считать RMS по каждому новому измерению.


3070- значение измеренное)

вкладывал такую логику: период постоянный, таймер заводится на период, и пока таймер измеряет один период АЦП постоянно работает.
Т.е. измерений будет много).

Возможно неправильно настроен таймер. Может кто подскажет как его настроить на измерение промежутка 20мс ?
ReAl
Цитата(1245 @ Jan 25 2013, 11:11) *
3070- значение измеренное)

Код
int GetRandomNumber()
{
        return 4; // Число получено подбрасыванием кубика
}
©пёрто в интернете.

Какой смысл замерять и заносить как число то, что можно учесть автоматически? (см. мой предыдущий ответ)
Ценой одного вычитания, одного умножения и одного деления на получение значения RMS (а не на один отсчет АЦП).
Все остальные вычисления, что на каждій отсчет АЦП, что на каждое значение rms — ровно как у Вас с магическим числом.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.