Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Изменение частоты ШИМ


Изменение частоты ШИМ

Сообщений 1 страница 22 из 22

1

Добрый день! Можно ли как-то программно менять частоту ШИМ в небольших пределах?

0

2

код

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

0

3

Проверил в протеусе

Config Timer2 = Timer , Prescale = 8 , Compare = Toggle , Clear Timer = 1
Ocr2 = 52

частота меняется при задании ORC2.

Но скважность всегда 50%. Мне же нужен полноценный ШИМ, т.е. скважность будет произвольно меняться, но также нужно изменять и его частоту в небольших пределах - допустим, на 500 Гц или около того. Неужели менять частоту ШИМ невозможно во время работы?

Отредактировано kokosh (2017-10-22 20:26:03)

0

4

Прежде всего нужно понимать отчего зависит частота и скважность ШИМ.
Частота от времени переполнения таймера, т. е. есть таймер переполняется скажем 1000 раз в секунду, то частота будет 1000 Гц.
Скважность зависит от числа в OcrX относительно к разрядности таймера. Скажем если таймер 8-ми битный, а в OcrX будет число 64, то скважность равна 25%.

Теперь подумайте каким образом можно изменять частоту переполнения таймера чтобы иметь возможность менять частоту и скважность ШИМ.

0

5

Подскажите, если знаете. До ума сам доведу.

0

6

На самом деле вариантов не много. Для изменения времени переполнения можно менять частоту тактирования таймера. Предделитель очень грубый и имеет коэффициент деления только 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.

0

7

Да, с предделителем не получится. Вообще, у меня задача достаточно простая, может я просто неверно её решаю.

Устройство представляет собой частотомер. У него в памяти есть некая фиксированная частота F1, а в реальном времени он замеряет другую частоту - F2. И чем больше эти две частоты отличаются, тем большей частоты звуковой сигнал нужно выводить на динамик. Есть ещё один параметр в измерении, от которого должна зависеть громкость звукового сигнала. Таким образом я поначалу подумал, что громкостью звука можно управлять, изменяя длительность сигнала ШИМ, но всё упёрлось в частоту. Изменение частоты генерируемого звука нужно небольшое, тут уж пришлось бы подстраиваться под ограничения реализации, хоть 500Гц, хоть 5кГц.

Значит нет вариантов сделать это программно и проще сделать генератор звука на отдельной логической микросхеме, а МК бы управлял параметрами его генерации?

PS: я нашёл почти то, что нужно, но не смог понять, как и почему оно работает. В протеусе не заработало. http://www.elektronik-labor.de/AVR/dds/PulsGen.html

Отредактировано kokosh (2017-10-22 21:27:47)

0

8

kokosh написал(а):

Устройство представляет собой частотомер. У него в памяти есть некая фиксированная частота F1, а в реальном времени он замеряет другую частоту - F2. И чем больше эти две частоты отличаются, тем большей частоты звуковой сигнал нужно выводить на динамик


Металлоискатель строите ?

0

9

Нет, прибор для исследования резонансов и колебательных контуров.

0

10

Используйте серию Xmega, там по мягче с таймерами и их больше и все 16 битные.
Там есть регистр PER - который ограничивает счёт, есть таймеры с 2 и 4 выходами ШИМ и вообще можно в совокупности аппаратно два таймера объединить.

0

11

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


:blush:

+2

12

некое далекое типа блдц, но пади всё греется как печь (ибо работает от части в шаговом режиме), хотя должно работать: тихо и еле теплое
на самом деле я с этой темой давно возился немного, управляющие мосфеты все горят как свечки при неправильном включении (без норм обвязки входов) и управлении
главное чтобы нигде и ничего не повисло, иначе всё горит
управление грамотное сделать весьма непросто, ибо надо учитывать кучу параметров (само ЭДС катушек т.е. всякие там махинации с грамотном отводом заряда, теневыми задержками...)
на самом деле проще ща драйвер готовый купить, где почти всё сделано (включая все защиты)

ещё есть интересная серия AT90PWM именно под эту тему, правда там как-то безграмотно разведены на чип/ноги аппаратные ШИМы (конфликтуют с ногами программирования)

Отредактировано RDW (2017-10-27 11:25:18)

0

13

RDW написал(а):

.... управляющие мосфеты все горят как свечки при неправильном включении (без норм обвязки входов) и управлении
главное чтобы нигде и ничего не повисло, иначе всё горит.....


Спас драйвер IGBT с опторазвязкой А3120, у него на выходе на открытие транзистор, а на закрытие (разряд) полевой, полная пила идёт.
Он годится и для IGBT (двуполярного питания базы) и для MOSFET, проблемы на 110в. были, в основном в качестве этих транзисторов, в руках была три варианта, один с алиэкспресс, сдох в нагрузке 1kW, другой с радио рынка, сдох при нагрузке 2kW,а третий выпаял с одной Германской платы, так от него провод отпаялся несколько раз и выдерживал, при этом все транзисторы были на радиаторе. Они греются, но не обжигают, всё-же 0.3 Ома это много.
Сегодня воткнул в станок и вижу как идёт дым из двигателя и провод дымится, но транзисторы выдержали и даже не нагрелись, чуть тёпленькие, это было при постоянном напряжении 36 вольт, выпрямленного с 3х фазного диодного моста.

http://sf.uploads.ru/t/Eyorg.png

Вот, рекомендую - http://datasheet.elcodis.com/pdf/11/4/1 … 0-500e.pdf
Брал ТУТ

Отредактировано Ev3658 (2017-10-27 18:24:35)

+1

14

Вернулся я к коду, взятому со страницы 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                 

0

15

$regfile = "ATtiny45.DAT"

0

16

Это исходный код, он и написан под тини45. При компилировании под attiny861 я, естественно, менял на ATtiny861.DAT. И, как уже говорил, Tccr1 на Tccr1a. Но не заработало. Может эти МК отличаются в плане ШИМ или ещё чем-то?

0

17

1. Для начала надо понять, пускается ли МК, сделайте простую мигалку или ещё что-то.
2. Зачем надо было менять Tccr1 на Tccr1а, если код весь настроен на Tccr1? Если вы слабо понимаете в коде, то не следует в него лезть или разбирайтесь с нуля.

0

18

Кхм. Вообще-то с Tccr1 код не будет компилироваться. МК, разумеется, запускается. Собственно, что я не понимаю в коде? Он же простой. Я просто не знаком с различиями в МК, поэтому и попросил подсказки.

0

19

kokosh написал(а):

Я просто не знаком с различиями в МК, поэтому и попросил подсказки.

снизойду до банальностей, но - даташит не листали...?  :blush:

0

20

Вот в даташите как раз пропустил, что назначение битов в Tccr1 у этих МК разное... В этом, видимо, и косяк.

0

21

kokosh написал(а):

Вот в даташите как раз пропустил, что назначение битов в Tccr1 у этих МК разное... В этом, видимо, и косяк.

Возможно.
Что мешает восстановить "статус кво" ? ;)
Использовать вместо TCCR1.2 (к примеру) - TCCR.4... ;)
Или что-то в этом роде...

0

22

Разобрался с битами регистров, спасибо, что ткнули носом почиать внимательно даташит.

Отредактировано kokosh (2018-04-04 01:01:48)

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Изменение частоты ШИМ