Официальный сайт компании Arduino по адресу arduino.cc
Работа с PWM для ПУш-ПУЛ.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пнд, 16/05/2016 - 23:02
Здравствуйте уважаемые форумчане, прошу сильно не пинать я только начина в этом разбираться. Постараюсь покроче. На просторах интернета нашёл сделующий скетч, вопрос следующий, как сделать еще один (3-й) сигнал, с той же частотой что и первые два, такой же фазы как и первый но чтобы можно было независимо меняеть его скважность.
поснительная картинка к тексту, если не понятно.
https://yadi.sk/i/xkpfXXWhrm5o3
#define PIN_PRI_A 9 // OCR1A - high-active primary drive #define PIN_PRI_B 10 // OCR1B - low-active primary drive #define PUSH_PULL false // false = OCR1A only, true = OCR1A + OCR1B #define TIMER1_PRESCALE 1 // clock prescaler value #define TCCR1B_CS20 0x01 // CS2:0 bits = prescaler selection #define PERIOD_US 5.1 #define PERIOD_TICKS (microsecondsToClockCycles(PERIOD_US / 2) / TIMER1_PRESCALE) int count=0; int duty=2; float Verror=0; float Vset=512.0; float Vact; unsigned long last=0; unsigned long wait=20; boolean first=true; void setup() { // pinMode(A0, INPUT); //input tensione НЕ знаю что это но без него работает. //digitalWrite(A0, LOW); analogWrite(PIN_PRI_A,128); // let Arduino setup do its thing analogWrite(PIN_PRI_B,128); TCCR1B = 0x00; // stop Timer1 clock for register updates // Clear OC1A on match, P-F Corr PWM Mode: lower WGM1x = 00 TCCR1A = 0x80 | 0x00; //128 | // Configure Timer 1 for Freq-Phase Correct PWM // Timer 1 + output on OC1A, chip pin 15, Arduino PWM9 // Timer 1 - output on OC1B, chip pin 16, Arduino PWM10 // If push-pull drive, set OC1B on match TCCR1A |= 0x30; //48 ICR1 = PERIOD_TICKS; // PWM period OCR1A = duty; // ON duration = drive pulse width//ucita 9 OCR1B = duty+156; // ditto - use separate load due to temp buffer reg //usita 10 TCNT1 = OCR1A - 1; // force immediate OCR1x compare on next tick // upper WGM1x = 10, Clock Sel = prescaler, start Timer 1 running TCCR1B = 0x10 | TCCR1B_CS20; } void loop() ///////// Тут дальше меняем скважность { OCR1A = duty+count; OCR1B = duty+36-count; if(first) { //delay(2000); first=false; } Vact=analogRead(A0); Verror=100.0*(Vset-(float)(Vact))/Vset; if(millis()-last>=wait) { last=millis(); if(Verror<0) count--; if(Verror>0) count++; if(count<0) count=0; //min duty 2% if(count>=15) count=15; //max duty 95% } }
сейчас частота 200 кГц. Можно ли включить 2-й таймер синхронно первому?
Это как пытаться синхронизировать часы, нужна логика сверки показаний. Не видел что-бы на практике кто-то делал, проще взять другой МК.
3dmax, в принципе можно.
Но без глубинного понимания работы таймеров вы не настроите таймеры на одну частоту. Тем более на 200кГц может полноценно работать только таймер1. И то, не совсем полноценно. Сколько градаций регулировки скважности будет на такой частоте? Не трудно подсчитать 16000000 /2 / 200000 = 40 шагов. Думаю реально запустить в синхроне -на 8 битах ( 62,5 кГц) в режиме FastPWM.
А можно ли на еще один выход продублировать показания с другого ?
ведь частота мне нужна та же, только фазу сдвинуть и скважность поменять.
3dmax, нет ничего дублировать невозможно. Есть простой способ сделать любое кол-во выводов всего на одном таймере - это программная генерация ШИМ. Но будут недостатки, -невысокая частота, дрожание фазы,сильная загрузка контроллера. Лучше всего взять ардуино с трех-канальными таймерами, как вам уже советовали в первом посте.
какой максимальной частоты я могу достигнуть используя 2 таймера ?
MagicianT, в чём мой коммент не верный? 0 и 1 таймер сбрасываются битом PSRSYNC, второй битом PSRASY
Попробуйте залить этот скетч, увидите что все три таймера молотят синхронно такт в такт:
И как вы обьясните что в моём примере есть оффсет, может фаза-коррект мода виновата, она в два раза медленнее вроде?
И зачем сбрасывать прескаллер, если он равен 1? У автора таймер на максимуме 16МГц крутится?
MagicianT, таймер1 в моём скетче работает в 5 моде(fastpwm), wgm13 не ставится, он же =0, просто забыл стереть.Почему у вас фазы разъехались -это нужно изучать исходный скетч, (лень:) скорее всего таймеры работают в разных режимах. Должны в одинаковом.
Да, сейчас нашёл, действительно мода 5. Если ему в эту моду, то все 3 таймера придётся задействовать, канал А будет определять частоту а Б дрыгать пин. Я поигрался ещё, и удостоверился что с таймерами 0 и 2 такой проблемы нет, если у них мода - 7, задавая TCNT можно сдвигать начальный оффсет фазы. Таймер-1 считает то ICR1, и иа-за этого похоже все проблемы, он напрочь отказывается синхронизироваться и в 14 моде фаст-PWM, не только в 8-ой где фаза-коррект, оффсет может быть 1, а если в коде что-нибудь поменять - то непредсказуемый.
Ох, прошу прощения за моё невежество, но я столько всего не знаю.
MagicianT в предыдущем вашем скетче в посте 8, все как надо за исключением того что задние фронты сильно прыгают, о чем кажеться и предупреждал dimax . А в последнем я растерялся и не знаю где меняеться частоста и скважность сигналов. Хотя с самими сигналами все просто прекрасно !
В любом случае, ребята спасибо вам большое !!!
Нет нет нет -- у меня никаких притензий, я ж говорю : "большо спасибо!!" Я уже поковырялся в последнем коде и почти все что надо понял. Это даже больше, чем я ожидал! Спасибо !!!
Ну тогда ладно, а то я подумал претензии какие. Ради любопытства я полазил по и-нету, и накопал что с разницей на единицы фазы (62.5 микросек) таймеров 0-2 и первого сталкивались, но обьяснения этому нету. Впрочем как и в ДШ атмеловском, если кратко - глюк, или недокументированные возможности....
http://www.openmusiclabs.com/learning/digital/synchronizing-timers/
Переписал скетч с поста 8, там был таймер-0, что как я писал не есть хорошо. Теперь на таймере-2, пин-3 дублирует пин-9 точно, пришлось подобрать стартовое значение таймера-2 = 17. Почему 17 не спрашивайте. Вобщем получилось как вам и надо, на 3-ем скважность регулируется независимо, а частота а фаза те-же что и на 9-ом.
Спасибо за труды, мне не ловко говорить, но в последнем коде задние фронты скачут :(
https://yadi.sk/i/tMguclcXrnxuu
Код смотрели? Там на аналог-0 напряжение подать надо, а у вас куда подключено? И ещё там я убрал часть, можете вернуть назад - теперь таймер-2 и милис() не вопрос.
Вауу, если бы вы не сказали я бы и не знал что такое
count = analogRead(A0) /16;
Ок, вечером проверю. Спасибо !!!
Подал 5 вольт с RX на A0 --- все дребезги фронтов пропали !!! :)
Вопрос:
что вот это cli(); и sei(); ???
Вопрос:
что вот это cli(); и sei(); ???
Запрет и разрешение прерываний.
не знаю что оно запрещает, но рабатет и без него :)
Вроде бы самое главное для себя нашел! Сдвиг фаз, скважность все есть !!
MagicianT огромное вам спасибо !!!! :)
На здоровье. Я и для себя что то новое открыл.
обнаружил непонятную штуку, с помощью кнопок пытаюсь менять PERIOD_TICKS или PERIOD_US, но частота не меняеться :(
на мониторе значения перемиенных меняються но частота -нет.
с частотой разобрался.
Здравствуйте уважаемые форумчане, прошу сильно не пинать я только начина в этом разбираться. Постараюсь покроче. На просторах интернета нашёл сделующий скетч, вопрос следующий, как сделать еще один (3-й) сигнал, с той же частотой что и первые два, такой же фазы как и первый но чтобы можно было независимо меняеть его скважность.
поснительная картинка к тексту, если не понятно.
https://yadi.sk/i/xkpfXXWhrm5o3
Всем здравствуйте. я в этом деле новичок, подскажите как собрана плата для этого скетча. собираю индукционный котел и мне надо чтоб частота фиксированная была 47.9391 а скважность менялась. силовую плату собрал на игбт 25n120 полный мост. и хотелось бы лсд запустить на плате. лсд1602 у меня с кнопками
Думаю, через годика полтора это будет тебе под силу. Если книги читать прилежно будешь. А счас пока - забуть.
так хочется отопление запустить
так хочется отопление запустить
А мне Ламборджини на огороде из металлолома выстругать, да, еще сварочник есть и эта, кувалда.)))