Добрый день! Можно ли как-то программно менять частоту ШИМ в небольших пределах?
Изменение частоты ШИМ
Сообщений 1 страница 30 из 31
Поделиться22017-07-19 08:27:07
Config Timer2 = Timer , Prescale = 1 , Compare = Toggle , Clear Timer = 1 ' сигнал будет на ноге PB.3 #
Ocr2 = Tx_freq ' 32 =120 кгц, 35=110, 39=99, 42=93kHz
Start Timer2
Tcnt0 = 0 : While Tcnt0 < Dlina_tx : Wend ' Длительность посылки, us
Stop Timer2
Config Timer2 = Timer , Prescale = 1 , Compare = Disconnect , Clear Timer = 1
Поделиться32017-10-22 20:03:19
Проверил в протеусе
Config Timer2 = Timer , Prescale = 8 , Compare = Toggle , Clear Timer = 1
Ocr2 = 52
частота меняется при задании ORC2.
Но скважность всегда 50%. Мне же нужен полноценный ШИМ, т.е. скважность будет произвольно меняться, но также нужно изменять и его частоту в небольших пределах - допустим, на 500 Гц или около того. Неужели менять частоту ШИМ невозможно во время работы?
Отредактировано kokosh (2017-10-22 20:26:03)
Поделиться42017-10-22 20:51:16
Прежде всего нужно понимать отчего зависит частота и скважность ШИМ.
Частота от времени переполнения таймера, т. е. есть таймер переполняется скажем 1000 раз в секунду, то частота будет 1000 Гц.
Скважность зависит от числа в OcrX относительно к разрядности таймера. Скажем если таймер 8-ми битный, а в OcrX будет число 64, то скважность равна 25%.
Теперь подумайте каким образом можно изменять частоту переполнения таймера чтобы иметь возможность менять частоту и скважность ШИМ.
Поделиться52017-10-22 20:53:31
Подскажите, если знаете. До ума сам доведу.
Поделиться62017-10-22 21:23:14
На самом деле вариантов не много. Для изменения времени переполнения можно менять частоту тактирования таймера. Предделитель очень грубый и имеет коэффициент деления только 1, 8, 64, 256 и 1024. Вариант изменения частоты тактирования МК наверное рассматривать не стоит.
В ATmega таймеры не такие функциональные как хотелось бы. Непонятно что мешало Atmel сделать нормальный предделитель с коэффициентом деления 0 - 255 или даже 0 - 65535.
Есть еще вариант, но сработает только с Timer1 или аналогичным ему. Таймер настраивается на автосброс по первому каналу сравнения.
Config Timer1 = PWM , Prescale = 1 , Compare_a_pwm = Disconnect , Compare_b_pwm = Clear_up , Clear Timer = 1
В Compare1a следует записать число (0 - 65535) до которого таймер досчитает прежде чем сбросится.
Compare1b изменяет скважность ШИМ и может быть равен от 0 до Compare1a.
Поделиться72017-10-22 21:26:34
Да, с предделителем не получится. Вообще, у меня задача достаточно простая, может я просто неверно её решаю.
Устройство представляет собой частотомер. У него в памяти есть некая фиксированная частота F1, а в реальном времени он замеряет другую частоту - F2. И чем больше эти две частоты отличаются, тем большей частоты звуковой сигнал нужно выводить на динамик. Есть ещё один параметр в измерении, от которого должна зависеть громкость звукового сигнала. Таким образом я поначалу подумал, что громкостью звука можно управлять, изменяя длительность сигнала ШИМ, но всё упёрлось в частоту. Изменение частоты генерируемого звука нужно небольшое, тут уж пришлось бы подстраиваться под ограничения реализации, хоть 500Гц, хоть 5кГц.
Значит нет вариантов сделать это программно и проще сделать генератор звука на отдельной логической микросхеме, а МК бы управлял параметрами его генерации?
PS: я нашёл почти то, что нужно, но не смог понять, как и почему оно работает. В протеусе не заработало. http://www.elektronik-labor.de/AVR/dds/PulsGen.html
Отредактировано kokosh (2017-10-22 21:27:47)
Поделиться82017-10-23 04:42:44
Устройство представляет собой частотомер. У него в памяти есть некая фиксированная частота F1, а в реальном времени он замеряет другую частоту - F2. И чем больше эти две частоты отличаются, тем большей частоты звуковой сигнал нужно выводить на динамик
Металлоискатель строите ?
Поделиться92017-10-23 09:05:48
Нет, прибор для исследования резонансов и колебательных контуров.
Поделиться102017-10-24 23:20:20
Используйте серию Xmega, там по мягче с таймерами и их больше и все 16 битные.
Там есть регистр PER - который ограничивает счёт, есть таймеры с 2 и 4 выходами ШИМ и вообще можно в совокупности аппаратно два таймера объединить.
Поделиться112017-10-26 18:47:02
Atmega8 - Timer1 9bit 8мГц
Рукожопный код:
Код:$regfile = "m8def.dat" $crystal = 8000000 $hwstack = 40 $swstack = 16 $framesize = 32 $baud = 19200 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 1 Config Adc = Single , Prescaler = Auto , Reference = Avcc Config Portc.5 = Input Config Portc.0 = Input Config Timer1 = Pwm , , Pwm = 9 , Compare A Pwm = Clear Up , Prescale = 1 Config Portb.1 = Output Dim Ac1 As Word Dim Ac2 As Word Dim Maxmotor As Word Dim Maxregul As Word Dim Motor As Word Dim Regul As Word Dim Shim As Word Dim Tm1 As Byte Dim Tm2 As Byte Dim Raznica As Byte Dim Vr2 As Word Dim Maxshim As Word Dim Mac As Word Start Adc Do If Tm1 = 4 Then 'Motor = Maxmotor 'Regul = Maxregul If Maxmotor < Maxregul Then Raznica = Maxregul - Maxmotor If Shim < 511 Then Incr Shim Elseif Maxmotor > Maxregul Then Raznica = Maxmotor Shim = Maxregul / 2 ' = Regul / 2 End If Maxregul = 0 Maxmotor = 0 Tm1 = 0 Else Ac1 = Getadc(5) Ac2 = Getadc(0) Incr Tm1 If Maxmotor < Ac1 Then Maxmotor = Ac1 If Maxregul < Ac2 Then Maxregul = Ac2 End If If Raznica > 60 Then If Tm1 = 0 And Tm2 < 250 Then Incr Tm2 Else If Tm1 = 0 Then Tm2 = 0 End If If Shim > 511 Then Shim = 511 If Tm2 = 70 Then Shim = 0 Pwm1a = Shim Loop

Поделиться122017-10-27 11:21:44
некое далекое типа блдц, но пади всё греется как печь (ибо работает от части в шаговом режиме), хотя должно работать: тихо и еле теплое
на самом деле я с этой темой давно возился немного, управляющие мосфеты все горят как свечки при неправильном включении (без норм обвязки входов) и управлении
главное чтобы нигде и ничего не повисло, иначе всё горит
управление грамотное сделать весьма непросто, ибо надо учитывать кучу параметров (само ЭДС катушек т.е. всякие там махинации с грамотном отводом заряда, теневыми задержками...)
на самом деле проще ща драйвер готовый купить, где почти всё сделано (включая все защиты)
ещё есть интересная серия AT90PWM именно под эту тему, правда там как-то безграмотно разведены на чип/ноги аппаратные ШИМы (конфликтуют с ногами программирования)
Отредактировано RDW (2017-10-27 11:25:18)
Поделиться132017-10-27 18:21:51
.... управляющие мосфеты все горят как свечки при неправильном включении (без норм обвязки входов) и управлении
главное чтобы нигде и ничего не повисло, иначе всё горит.....
Спас драйвер IGBT с опторазвязкой А3120, у него на выходе на открытие транзистор, а на закрытие (разряд) полевой, полная пила идёт.
Он годится и для IGBT (двуполярного питания базы) и для MOSFET, проблемы на 110в. были, в основном в качестве этих транзисторов, в руках была три варианта, один с алиэкспресс, сдох в нагрузке 1kW, другой с радио рынка, сдох при нагрузке 2kW,а третий выпаял с одной Германской платы, так от него провод отпаялся несколько раз и выдерживал, при этом все транзисторы были на радиаторе. Они греются, но не обжигают, всё-же 0.3 Ома это много.
Сегодня воткнул в станок и вижу как идёт дым из двигателя и провод дымится, но транзисторы выдержали и даже не нагрелись, чуть тёпленькие, это было при постоянном напряжении 36 вольт, выпрямленного с 3х фазного диодного моста.
Вот, рекомендую - http://datasheet.elcodis.com/pdf/11/4/1 … 0-500e.pdf
Брал ТУТ
Отредактировано Ev3658 (2017-10-27 18:24:35)
Поделиться142018-04-02 23:53:37
Вернулся я к коду, взятому со страницы http://www.elektronik-labor.de/AVR/dds/PulsGen.html
Нарисовал по-человечески в протеусе и всё хорошо заработало. Но не хватает ног МК для нужного мне функционала.
Нужно "портировать" код под другой МК, например - attiny861. В исходнике я заменил Tccr1 на Tccr1a. Компилируется, но на выходе МК нет импульсов. Подскажите, что не так.
Исходный код:
'*************************************************************************** '* '* Title : AT45 pulse generator '* independent setting of frequency and pulse width 0..100% '* frequency range: 10.6 MHz to 1.1 Hz '* '* Pinb.2 button Toggle T1 clock source '* Pinb.0 button inc prescaler 1..15, no interrupt used '* Pinb.3 input poti 10k set frequency '* Pinb.4 input poti 10k set pulse width '* Pinb.1 output OCR1A frequency '* '* fpwm=fck/(OCR1C+1), Pw=Ocr1a -> Freq*Pw=fck*Ocr1a/(OCR1C+1), ratio '* '* program code : BASCOM AVR basic '* Last updated : GS 4-2012 '* Target : ATtiny45 '* '*************************************************************************** ' This program is free software; you can redistribute it and/or ' modify it under the terms of the GNU General Public License. ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; '*************************************************************************** ' ' ATtiny45 dip '(PCINT5/RESET/ADC0/dW) PB5 VCC '(PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3 PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2) '(PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1) ' GND PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0) ' ';*************************************************************************** $regfile = "ATtiny45.DAT" $crystal = 8000000 $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 'default use 10 for the SW stack $framesize = 20 'default use 40 for the frame Dim I As Byte Dim Prescc1 As Byte Dim Channel As Byte Dim W As Word Dim Freq As Word Dim Pw As Word Ddrb = &B00000010 Portb = &B00000101 'pullup PB0,2 '********************************************************************* $asm ' turn on PLL ldi R24, &B00000010 '; Enable PLL (1<<PLLE) out PLLCSR, R24 waitPLL: in R24, PLLCSR '; Wait for PLL to lock (approx. 100ms) sbrs R24, PLOCK rjmp waitPLL in R24, PLLCSR '; Set PLL as clock source ldi R25,&B00000100 ';(1<<PCKE) or R24, R25 Out Pllcsr , R24 $end Asm Didr0 = &B00011000 Config Adc = Single , Prescaler = Auto , Reference = Avcc Start Adc Tccr1 = &B11100011 'CTC, pwm, clr ' B11100000 = 224 dec Prescc1 = 3 Ocr1c = 199 Ocr1a = 100 'Start Timer1 Do 'all in 1 loop Debounce Pinb.2 , 0 , Togt1ck , Sub 'Toggle T1 clock source Debounce Pinb.0 , 0 , Incpre , Sub 'increment prescaler Channel = 2 Freq = 0 For I = 1 To 8 W = Getadc(channel) Freq = Freq + W Next I Channel = 3 Pw = 0 For I = 1 To 8 W = Getadc(channel) '10 bit Pw = Pw + W Next I Freq = Freq / 32 'make 8 bit Pw = Pw / 64 Pw = Pw * Freq Pw = Pw / 128 If Pw = 0 Then Pw = 1 If Freq < 2 Then Freq = 2 Ocr1c = Freq Ocr1a = Pw ' fpwm=fck/(OCR1C+1), Pw=Ocr1a -> Freq*Pw=fck*Ocr1a/(OCR1C+1), ratio Loop '********************************Sub************************************* IncPre: Incr Prescc1 'inc prescaler If Prescc1 >= 16 Then Prescc1 = 1 Tccr1 = 224 + Prescc1 'set prescaler Return ' Togt1ck: 'Toggle T1ck source $asm ' turn on PLL in R24, PLLCSR sbrc R24, 2 '; PCKE not set rjmp dp1 '; if set then clear sbr R24, 4 '; Set PLL as clock source out PLLCSR, R24 rjmp dp2 Dp1: Cbr R24 , 4 '; Set system CK as clock source out PLLCSR, R24 Dp2: $end Asm Return
Поделиться152018-04-03 11:36:59
$regfile = "ATtiny45.DAT"
Поделиться162018-04-03 16:18:51
Это исходный код, он и написан под тини45. При компилировании под attiny861 я, естественно, менял на ATtiny861.DAT. И, как уже говорил, Tccr1 на Tccr1a. Но не заработало. Может эти МК отличаются в плане ШИМ или ещё чем-то?
Поделиться172018-04-03 18:29:37
1. Для начала надо понять, пускается ли МК, сделайте простую мигалку или ещё что-то.
2. Зачем надо было менять Tccr1 на Tccr1а, если код весь настроен на Tccr1? Если вы слабо понимаете в коде, то не следует в него лезть или разбирайтесь с нуля.
Поделиться182018-04-03 21:51:24
Кхм. Вообще-то с Tccr1 код не будет компилироваться. МК, разумеется, запускается. Собственно, что я не понимаю в коде? Он же простой. Я просто не знаком с различиями в МК, поэтому и попросил подсказки.
Поделиться192018-04-03 21:56:46
Я просто не знаком с различиями в МК, поэтому и попросил подсказки.
снизойду до банальностей, но - даташит не листали...? 
Поделиться202018-04-03 22:06:45
Вот в даташите как раз пропустил, что назначение битов в Tccr1 у этих МК разное... В этом, видимо, и косяк.
Поделиться212018-04-03 22:15:25
Вот в даташите как раз пропустил, что назначение битов в Tccr1 у этих МК разное... В этом, видимо, и косяк.
Возможно.
Что мешает восстановить "статус кво" ? 
Использовать вместо TCCR1.2 (к примеру) - TCCR.4... 
Или что-то в этом роде...
Поделиться222018-04-03 22:28:58
Разобрался с битами регистров, спасибо, что ткнули носом почиать внимательно даташит.
Отредактировано kokosh (2018-04-04 01:01:48)
Поделиться232021-01-03 12:49:13
Я реализовывал таким образом, однако частота не меняется, в чем может быть проблема?
Мне требуется частота ШИМ 200Гц
$regfile = "m32def.dat" $crystal = 8000000 Config Portd.7 = Output Tccr2 = 102 Tcnt2 = 250 Enable Interrupts Enable Timer2 Do Disable Timer2 Ocr2 = 127 Enable Timer2 Loop End
Поделиться242021-01-03 19:34:47
А счего вы взяли что так поменяете частоту? Частота настраивается делителем таймера.
Поделиться252021-01-03 20:36:13
На сколько я понял, Ocr2 задает ШИМ, а вот Tcnt2 - частоту
Поделиться262021-01-06 10:27:45
$regfile = "m8def.dat"
$crystal = 4000000
'---------шим с ФЧК реж-8 ---------------
Tccr1b = &B00010001 ' 'presc=1
ICR1 = 64 'период F=4мгц/(2*64)=31.25кгц
OCR1A = 16 'длительность имп.на OC1A
OCR1b = 8 'длительность имп.на OC1B
Tccr1a = &B10100000 'выход на OC1A и OC1B
'-----------быстрая ШИМ реж-14-----------------------
' Tccr1b = &B00011001 'presc=1, fast pwm
' ICR1 = 64 'период F=4мгц/64=62.5кгц
'OCR1A = 16 'длительность имп.
'Tccr1a = &B10000010 'fast pwm, выход на OC1A
'----------------------------------------------
'---------шим с ФЧК реж-9 ---------------
' Tccr1b = &B00010001 ' 'presc=1
' OCR1A = 16 'период
' OCR1b = 8 'длительность имп.на OC1B , OC1A-не работает
' Tccr1a = &B10100001 'выход на OC1A и OC1B
'---------------------------------------------------
Поделиться272021-01-27 20:32:46
Доброго дня !
Уважаемые знатоки, помогите получить шим ~30кгц от Меги328p. Желательно на втором таймере. Или первом. Но не на нулевом.
Обычным баскомовским способом получил 16 кгц. Как я понял, нужно включать Fast Pwm.
А как - пока недовъезжаю.
Нужно за-пвм-ить преобразователь напряжения для питания ИН-14.
Спасибо !
Поделиться282021-01-27 22:48:06
Таймеры 1 у меги8 и меги328 аналогичны.Поэтому можно использовать кусок кода для быстрой шим из предыдущего примера с учетом ваших требований.
$regfile = "m328def.dat" $crystal = 4000000 ddrb.1=1'порт B1 на выход Tccr1b = &B00011001 'presc=1, fast pwm ICR1 = 133 'период F=4мгц/133=30кгц OCR1A = 66 'длительность имп.(меандр) Tccr1a = &B10000010 'fast pwm, выход на OC1A
Поделиться292021-01-28 09:32:47
Таймеры 1 у меги8 и меги328 аналогичны.Поэтому можно использовать кусок кода для быстрой шим из предыдущего примера с учетом ваших требований.
Код:ICR1 = 133 'период F=4мгц/133=30кгц
OCR1A = 66 'длительность имп.(меандр)
Tccr1a = &B10000010 'fast pwm, выход на OC1A
Спасибо ! При конфигурирровании Fast Pwm задействуются оба канала таймера ?
Только я недопонял, как это пересчитать на тактирование от 8 мгц ? ICR = 266 ?
И OCR1A сколько должен быть ?
Поделиться302021-01-28 10:57:54
Если надо задействовать оба канала таймера и использовать 8 мгц нужно написать так:
$regfile = "m328def.dat" $crystal = 8000000 ddrb.1=1'порт B1 на выход ddrb.2=1'порт B2 на выход Tccr1b = &B00011001 'presc=1, fast pwm ICR1 = 266 ' F=8мгц/266=30.075кгц OCR1A = 133 'длительность имп. на OC1A меандр будет если ICR1/OCR1=2 OCR1B = 133 'длительность имп.на OC1B Tccr1a = &B10100010 'fast pwm, выход на OC1A и на OCR1B
