Главная » Статьи » Проекты

Конфигурируем ШИМ в Bascom
  Достаточно часто появляется необходимость использовать управление какого-либо устройства (будь то лампочка накаливания, двигатель, ТЭН или простой светодиод) посредством ШИМ. 
  Наверно объяснять что это такое и в чем прелесть управления ШИМом не нужно, информации в интернете накопилось уже достаточно много, да и врядли мне получиться разжевать эту тему лучше. Поэтому сразу перейдем к делу, а именно запустим ШИМ на Attiny2313 средствами Bascom-AVR.  
  Шим в микроконтроллерах AVR работает на таймерах-счетчиках, в мк Tiny2313 таких таймеров всего 2: 8-и битный Timer0 считающий до 255 и 16-и битный Timer1 способный считать до 65535. Каждый таймер управляет двумя ШИМ-каналами, таким образом всего аппаратно можно реализовать целых 4 канала ШИМ. 
  Информацию о количестве каналов ШИМ и разрядность каждого канала можно глянуть на страницах даташита на микроконтроллер.  
  Так, на борту Attiny2313 имеются два 8-и битных канала ШИМ работающих от Timer0 и еще два канала под управлением таймера Timer1 имеют программируемую разрядность от 8 до 10 бит. В даташите эти ноги подписываются следующим образом:
 
pinouts attiny2313
 
 
 
  Для того чтобы сконфигурировать таймер Timer1 на генерацию ШИМ в Bascom достаточно записать следующую строку :
 
Config Timer1 = Pwm, Pwm = 8, Compare A Pwm = Clear Up, Compare B Pwm = Clear Down, Prescale = 64    
 

Pwm = 8 выбирается разрядность ШИМ, для Timer1 как писалось выше может быть также Pwm = 9 или Pwm = 10.  

Compare A/B Pwm = Clear Up/Clear Down здесь конфигурируем активное состояние для каждого канала ШИМ (А и В).

Prescale = 64 - уже знакомая строка конфигурации таймера, отвечающая за предварительное деление частоты переполнения таймера, в данном случае делитель будет задавать частоту ШИМ. Можем менять на свое усмотрение Prescale= 1|8|64|256|1024  


 Скважность генерируемого сигнала определяется значением, которые мы записываем в регистры сравнения OCR1A и OCR1B (каналов ШИМ же у нас два на одном таймере, вот по одному регистру на канал А и В). Со значениями, которые лежат в этих регистрах постоянно сравнивается значение счетного регистра (туда оно копируется с таймера), при их совпадении происходит переключение ноги мк в активное состояние, а счетный регистр продолжает считать до своего максимального значения. Досчитав до максимума, таймер начинает считать в обратном направлении, и дойдя до момента когда значения счетного регистра и регистра сравнения снова совпадут, произойдет обратное переключение на ноге микроконтроллера (см. рисунок ниже)
 
 
 
 
 

 Для нас регистры сравнения OCR1A и OCR1B всего-навсего переменные, в которые мы можем положить какое-нибудь значение. Например, так:

OCR1A = 100
OCR1B = 150

 В баскоме для удобства предусмотрено и другое название этих регистров: PWM1A и PWM1B, так предыдущие строки будут равнозначны следующим:

PWM1A = 100
PWM1B = 150
 
Теперь разберемся, как влияет конфигурация активного состояния Clear Up/Clear Down на то, что происходит на выходе ШИМ в зависимости от значения регистра сравнения.
Когда выход сконфигурирован как Compare A Pwm = Clear Down активным состоянием выхода является высокий уровень и при увеличении значения регистра OCR (PWM) пропорциональное напряжение на этой ноге будет расти. С точностью до наоборот все будет происходить, если выход сконфигурирован как Compare A Pwm = Clear Up. Все это хорошо проиллюстрировано на картинке ниже
 
 

 Значения, которые могут принимать эти регистры сравнения зависят от того, какую разрядность канала ШИМ мы выбрали. При PWM = 8 (8-и битный шим) возможно значение от 0 до 255; при PWM = 9  от 0 до 511; при PWM = 10 от 0 до 1023. Тут я думаю, все понятно.

 Теперь небольшой пример: подключим к микроконтроллеру светодиоды как показано на схеме (питание мк на схеме не указано) 
 
 
 И напишем небольшую программку:
 
$regfile = "attiny2313.dat"
$crystal = 4000000

Config Timer1 = Pwm, Pwm = 9, Compare A Pwm = Clear Down, Compare B Pwm = Clear Up, Prescale = 8
Config PORTB.3 = Output
Config PORTB.4 = Output

Do

Incr Pwm1a                                 'плавно увеличиваем значение регистра сравнения OCR1A
Incr Pwm1b                                 'плавно увеличиваем значение регистра сравнения OCR1B

Waitms 20                                  'добавим задержку

Loop

End

 

 

 После того как откомпилировали и прошили программу в контроллер один из светодиодов (D1) будет плавно набирать яркость, а другой (D2) плавно гаснуть  

 Если сейчас ткнуть осциллографом на выходы ШИМ, то можем увидеть такую вот картину с изменяющейся скважностью импульсов (синий сигнал на ОС1А, красный на ОС1В):

 

 Конфигурация таймера Timer0 для генерации ШИМ практически такая же, за исключением того, что timer0 это 8-и битный таймер, и поэтому ШИМ генерируемый этим таймером будет всегда иметь разрядность 8. Поэтому конфигурируя этот таймер, разрядность ШИМ не указывается:  
 
Config Timer0 = Pwm, Compare A Pwm = Clear Up, Compare B Pwm = Clear Down, Prescale = 64    

 


 Теперь аналогичный пример со светодиодами, но теперь шим сгенерируем при помощи Timer0:

 

 

 

$regfile = "attiny2313.dat"
$crystal = 4000000

Config Timer0 = Pwm, Compare A Pwm = Clear Down, Compare B Pwm = Clear Up, Prescale = 8
Config PORTB.2 = Output
Config PORTD.5 = Output

Do

Incr Pwm0a                                   'плавно увеличиваем значение регистра OCR0A
Incr Pwm0b                                   'плавно увеличиваем значение регистра OCR0B  

Waitms 20                                    'добавим задержку

Loop

End

 

 

 

 

  Подключим светодиоды к выходу ШИМ Timer0, как показано на схеме:

 


Тут все аналогично: первый светодиод (D1) будет плавно набирать яркость, а второй (D2) будет плавно гаснуть. 

 

Подсчет частоты генерации ШИМ

 

  Если требуется узнать частоту генерации ШИМ, то сделать это не сложно. Смотри на формулу ниже:

    Частота ШИМ = (частота кварца/предделитель) / (размер счетного регистра *2)

Для примера подсчитаем несколько значений: 

   1. Частота кварца = 4000000 Гц, предделитель = 64, разрядность ШИМ 10 бит => размер счетного регистра = 1024

 Частота ШИМ = (4000000/64)/(1024*2) = 122 Гц 

   2. Частота кварца = 8000000 Гц, предделитель = 8, разрядность ШИМ 9 бит => размер счетного регистра = 512

 Частота ШИМ = (8000000/8)/(512*2) = 976,56 Гц

   3. Частота кварца 16000000 Гц, предделитель = 1, разрядность ШИМ 8 бит => размер счетного регистра = 256

 Частота ШИМ = (16000000/1)/(256*2) = 31250 Гц

 


Категория: Проекты | Добавлено: 18.07.2011
Просмотров: 62563 | Комментарии: 65 | Теги: bascom-avr, ШИМ, Timer1, PWM, Timer0, ATtiny2313 | Рейтинг: 4.7/18
Всего комментариев: 651 2 3 »
+1   Спам
65 lionsitroen   (23.02.2018 13:10) [Материал]
Спустя годы отвечу сам себе и другим страждущим. Для конфигурации ШИМ в режиме Fast PWM придется настроить регистр счетчика напрямую.
Пример конфигурации для Atmega8a на таймере 2:

'Регистр DDRB преобладает над регистром TCCR. По этому порт надо настроить на выход
Config Portb.3 = Output
'Настроим регистр Tccr2: FAST PWM, Set on Compare, Set OC2 on Compare Match, No prescaling. Описание битов смотрим в даташите
Config Timer2 = Timer
Tccr2 = &B01101001
'Установим уровень сравнения
Ocr2 = 128

64 max   (28.03.2017 14:15) [Материал]
http://bascom.at.ua/publ/usb_pwm/1-1-0-43#

63 sand   (27.03.2017 21:38) [Материал]
Добрый день.

Перерыл весь интернет, не могу найти очень простую вещь, может быть вы мне поможете.
Нужен простой пример на Bascom для работы с тремя выходами ШИМ для ATMEGA8. У нее есть двух и одноканальные ШИМ, а во всех примерах используется 1 или 2 канала двухканального. Заранее спасибо.

62 Dmitriy   (28.02.2016 18:11) [Материал]
Pchela5 Да,конечно в протеусе немного побаловался, работает без шима. На цветА три транзистора 60N03 или аналогичные, на каждый светодиод, BSS84. Чтобы не рисковать и не сжечь контроллер.В железе будет собрано не скоро, но поделюсь обязательно.

61 pchela5   (28.02.2016 17:45) [Материал]
Однако, серьезная задумка. А ключи для диодов продумал?

60 Dmitriy   (27.02.2016 15:19) [Материал]
Pchela5 Да, задача странная (сам боюсь). Просьба не падать со стула со смеху :) Я хочу сделать бегущие огни с массой световых эффектов на RGB светодиодах, их будет 80 штук. Купил микроконтроллер в корпусе TQFP-100 Atmega 2560. Десять портов задействованы на выход, регистры не буду ставить. Остается порт G для управления ключами по цвету, вот там и хочу сделать регулировку яркости. Причина, почему не использую родной аппаратный ШИМ, мне так удобнее конструировать эффекты, когда все ножки портов идут по порядку от 0 до 7. Каждый сходит с ума по своему :)
PS Книгу начал читать.

59 pchela5   (27.02.2016 14:39) [Материал]
ЭЭЭЭ, какая то странная задача. Ты бы обрисовал проблему поподробнее. Я встречал много статей про программный ШИМ, да и сам делал. Опять же - шим вызывает прерывание - тоггле ножку в нем и уходи обратно. Вообще у Евстифеева все оч. хорошо описано. Маст риди обязательно.

58 Dmitriy   (26.02.2016 17:46) [Материал]
Pchela5, проблема в том, что мне нужен выход ШИМ на ножках микроконтроллера, которые не являются выходом аппаратного ШИМ. Сейчас пытаюсь сделать программный ШИМ на прерываниях. Если не устроит, добавлю еще один микроконтроллер :) соединю их по UART и все.

57 pchela5   (26.02.2016 15:19) [Материал]
Перебросить можно, если использовать другой таймер.

0  
56 exersizze   (23.02.2016 11:45) [Материал]
Нет, перебросить аппаратный шим на другие ножки не получиться.

55 Dmitriy   (20.02.2016 22:14) [Материал]
Хочу спросить у автора, и посетителей, можно ли перебросить порты ШИМ на другие ноги ? Вот возникла такая необходимость :)

54 koteika   (21.10.2015 12:59) [Материал]
а нет ли у кого-нибудь примера софтового шима каналов на 10? поделитесь

53 cannibal66670   (22.06.2015 15:35) [Материал]
а как организовать, чтоб эти светодиоды светились асинхронно, то есть шим это по сути мерцание с большой частотой, как организовать работу светодиодов так чтоб каждый зажигался в тот момент, когда второй не горит?

+3   Спам
52 pchela5   (28.10.2014 10:52) [Материал]
Для понятия принципа работы ШИМ в разных режимах рекомендую почитать Евстифеева - МК семейства Тини. Сам столкнулся с этой же проблемой неделю назад. После даташита - темный лес, после книги - все ясно. Могу выложить статейку по данному поводу - наработки по преобразователю из 12 в синус 220 с позволения хозяина сайта.

0  
51 exersizze   (14.10.2014 09:13) [Материал]
самому бы разобраться:)

50 Gordon_shumway   (07.10.2014 11:04) [Материал]
Доброго дня !
Уважаемый автор, а не сделаете ли подобную статью про конфигурацию таймеров регистрами ? Столкнулся с тем, что понадобилось сконфигурировать Fast pwm, что нельзя сделать стандартными командами bascom, а можно только регистрами. И, если честно, после курения даташита я окончательно запутался...

49 domrustika   (30.01.2014 17:54) [Материал]
спасибо а какой код будет для использования Timer2 для меги 8? которая на ноге Portb3 (OC2)?

48 sany2   (27.01.2014 22:31) [Материал]
Ноги для Atmega8-для тиньки ищите свои(2313 вообще в глаза ни разу не видел-поэтому не скажу-есть там аналоги или нет,а так же смотрите таймеры-не уверен ,есть ли там таймер2)

Config Portb.1 = Output
Config Portb.2 = Output 'выходы шим
Config Portb.3 = Output

A Alias Ocr2
B Alias Pwm1b
C Alias Pwm1a

Config Timer0 = Pwm , Prescale = 1 , Compare Pwm = Clear Up , Pwm = On
Enable Timer0
Config Timer2 = Pwm , Prescale = 1 , Compare Pwm = Clear Up , Pwm = On
Enable Timer2

A=150
B=200 'для разных светодиодов разные значения-подбирать свои
c=255

47 maratino   (27.01.2014 18:25) [Материал]
Подскажите кто ни будь. Написал код в Баском для тини2313 ПАДАЮЩИЙ МЕТЕОРИТ. Все работает. А вот как сделать, что при движении первые три св-диода загораются полностью, седующие три на половину, а последние три тускло. И получается так, когда все 9 св-диодов метеорита перемещаются по линейке из 17-и свдиодов, то похожа на метеорит. Головка яркая а за ним хвостик. Только Бакском и желательно ати2313
Sub Ar()
Led1 = 1 : Waitms 10
Led2 = 1 : Waitms 10
Led3 = 1 : Waitms 10
Led4 = 1 : Waitms 20
Led5 = 1 : Waitms 20
Led6 = 1 : Waitms 20
Led7 = 1 : Waitms 20 : Led1 = 0
Led8 = 1 : Waitms 20 : Led2 = 0
Led9 = 1 : Waitms 20 : Led3 = 0
Led10 = 1 : Waitms 20 : Led4 = 0
Led11 = 1 : Waitms 20 : Led5 = 0
Led12 = 1 : Waitms 20 : Led6 = 0
Led13 = 1 : Waitms 20 : Led7 = 0
Led14 = 1 : Waitms 20 : Led8 = 0
Led15 = 1 : Waitms 20 : Led9 = 0
Led16 = 1 : Waitms 20 : Led10 = 0
Led17 = 1 : Waitms 20 : Led11 = 0

Led12 = 0 : Waitms 20
Led13 = 0 : Waitms 20
Led14 = 0 : Waitms 20
Led15 = 0 : Waitms 20
Led16 = 0 : Waitms 20
Led17 = 0 : Waitms 60
End Sub

46 T1nK   (09.01.2014 19:16) [Материал]
Сделал RC фильтр - помогло, правда приведенные формулы в статье оказались не верны для ISIS - частота на порядок меньше оказалось, в результате я теперь сомневаюсь в эффективности подбора номиналов элементов в ISIS. Придется видимо как в школе и универе считать все на папирусе с деревянным вычислителем типа счетов...

Дальше буду пытаться переводить ATmega в энергосберегающий режим (к счастью он не один, вроде бы) с пробуждением по событиям, надеюсь тут найдется какая-нибудь статья на это тему ?..

+1   Спам
45 sany2   (08.01.2014 22:50) [Материал]
kip96-ну нафига.Всё так славненько было,и тут бац тебе - ИНТЕГРАТОР.Меня со школы ещё от интегралов не отпустило...Извини - настроение просто хорошее.

44 kip96   (08.01.2014 22:21) [Материал]
Вообще то если по научному, то Вам нужен интегратор
http://ru.wikipedia.org/wiki/Интегратор
Но, некоторых это вводит в тупик.

43 T1nK   (08.01.2014 17:11) [Материал]
Спасибо вам sany2 и kip96 помогли))) Теперь разобрался)))
Правда sany2 с такой схемой чувствую мне пока рано работать, тем более что только недавно начал приобщаться к схемотехнике и микроконтроллерам в частности.
Посмотрю в начале на RC фильтр - что это вообще за зверь, а там видно будет.
Ещё раз спасибо)))
И да, статья действительно отличная

42 sany2   (08.01.2014 09:44) [Материал]
kip96 - классно рассказал!

41 kip96   (08.01.2014 09:27) [Материал]
Яркость меняться будет, кроме того, только так и меняют яркость светодиодов, потому-что ВАХ у него не линейная и аналоговым способом это довольно сложно линейно(визуально) менять яркость светодиода. Если хотите менять напряжение на выходе- добавьте RC фильтр. Импульсами через резистор будет заряжаться конденсатор, в паузах разряжаться. Чем чаще импульсы- тем сильней заряжается. На выходе будет аналоговое напряжение. Если что-то серьёзное - смотрим принцип работы ЦАП. ЗЫ. В изис яркость меняться не будет, просто он этого не умеет(изис)

40 sany2   (08.01.2014 00:03) [Материал]
Например LM2596-ADJ(проще всего:от 0 до 30 вольт)
Подкину схемку http://yadi.sk/d/4YikGvKhFcber

39 T1nK   (07.01.2014 23:56) [Материал]
Нужно изменить яркость светодиода, но как мне показалось для этого нужно изменить напряжение...
Я пока отлаживаю схему в ISIS за неимением программатора под рукой и вижу только изменение частоты импульсов на светодиод с ножки...
В теории конечно это как-то может отразиться на яркости, но проверить это не могу в живую, потому и не понимаю правильно ли делаю.
Скажите, будет ли изменяться яркость моим кодом?

И, спасибо, - действительно глупо было пытаться вывести на аналоговые входы аналоговый сигнал.
Но можно ли как-то управлять именно напряжением (от 0 до напряжения питания)?
Если сам чип этого сделать не может, то какие дополнительные элементы нужно использовать?

38 kip96   (07.01.2014 23:06) [Материал]
И не удивительно! Аналоговых выходов в мк нет! учим дш.
А вообще что Вам нужно, яркость изменять или напряжение?

37 T1nK   (07.01.2014 18:31) [Материал]
Подскажите пожалуйста чем можно заменить analogWrite(pin, value), например, используемое для регулировки яркости светодиода, как говорит автор, с использованием цифровых пинов с поддержкой PWM (видео http://www.youtube.com/watch?v=LkR8rxzAo_A с 4й минуты) ?

Целый день сижу, не могу понять чем можно заменить (без использования цикла)... Пока дошел только до использования таймера (но не уверен, что это то что доктор прописал):

$regfile = "m8def.dat"
$crystal = 16000000

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Prescale = 1
Config Portb.1 = Output

On Int0 Button

Enable Interrupts
Enable Int0

Dim Led As Byte
Led = 0

Do
Waitms 255
Loop

Button:
Led = Led + 51
If Led >= 255 Then
Led = 0
End If
Compare1a = Led
Return

End

PS. В результате меняется частота импульсов на светодиод, но напряжение не меняется. Светодиод у меня подключен к PB1, а кнопка (последовательные нажатия на которые регулируют увеличивают яркость) висит на PD2.
Использовать аналоговые выходы то же не получилось - так же выводится либо 0, либо й (2 с хвостиком Вольт).

36 top   (08.08.2013 18:53) [Материал]
Исправлюсь. Да, частота увеличится. Во сколько? все зависит от величины регистра сравнения. Да и какой разговор может быть о частоте меандра (у которого скважность равна двум) как таковой, если здесь мы меняем скважность. А по вопросу: думаю можно. В момент когда досчитали до FF обнулить значение счетчика. Вот тольо как? Простым сбросом: стоп-старт?

1-30 31-60 61-65
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






авторизация