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

Конфигурируем ШИМ в 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
Просмотров: 39240 | Комментарии: 62 | Теги: bascom-avr, ШИМ, Timer1, PWM, Timer0, attiny2313 | Рейтинг: 4.7/18
Всего комментариев: 621 2 3 »
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)
а как организовать, чтоб эти светодиоды светились асинхронно, то есть шим это по сути мерцание с большой частотой, как организовать работу светодиодов так чтоб каждый зажигался в тот момент, когда второй не горит?

+2   Спам
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 обнулить значение счетчика. Вот тольо как? Простым сбросом: стоп-старт?

35 lionsitroen   (08.08.2013 10:24)
Это не так. Если счетчик будет считать до FF потом сбрасываться, то частота импульсов будет в 2 раза выше. Собственно, все уже сказано.. ну например тут: http://easyelectronics.ru/avr-uchebnyj-kurs-ispolzovanie-shim.html.
Вопрос по прежнему открыт.

34 top   (07.08.2013 20:43)
lionsitroen, а не наоборот ли? Частота уменьшится вдвое! (Читай период увеличивается, частота уменьшается)

33 lionsitroen   (07.08.2013 18:07)
Насколько я понял, приводится описание работы в режиме Phase Correct PWM. Т.е. счетчик считает сначала от 0 до 255, потом от 255 до 0. А как сделать режим в котором счетчик считает от нуля до 255, после достижения переполнения сбрасывается в нуль и счет начинается снова? В эьтом режиме частота ШИМ, насколько я понял, может быть в 2 раза выше.

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






   EasyEDA:  бесплатный редактор схем

   ✓ Создание схем
   ✓ Возможность симуляции
   ✓ Быстрое создание печатных плат
   ✓ Интуитивно понятный интерфейс

   Нарисуй свою схему прямо сейчас!
   Изготовление печатных плат   https://easyeda.com/order
авторизация
Логин:
Пароль:
Комментарии
Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595
01.12.2016 - yorx:
Доброго времени суток, exersizze попробовал Ваш код все равно не работает как на...
Помни об усадке!
30.11.2016 - pchela5:
Автомобильные никакие не лезут?
Помни об усадке!
29.11.2016 - AlekS:
Виктор, спасибо.
С заменой транса в зиму, перестройка не комельфо) Валяет...
Управляем микроконтроллером с ПК по UART
29.11.2016 - exersizze:
Михаил, для работы с инфракрасными датчиками и диодами есть команды RC5SE...
Управляем микроконтроллером с ПК по UART
29.11.2016 - Михаил:
Всем привет.
Подскажите как переменную S передать по инфракрасному каналу...
Помни об усадке!
29.11.2016 - pchela5:
> Если ленту светодиодную порезать и соединить последовательно
Только ...
Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595
29.11.2016 - exersizze:
yorx, вывод Q7 ' первой микросхемы соединен с DS второй микросхемы? С...
Помни об усадке!
29.11.2016 - exersizze:
Можно даже без резистора их включать, если на ленте уже стоят. Но если опасаешьс...
Помни об усадке!
28.11.2016 - AlekS:
Да,пла, из абс как-то грубовато идет. (((
Самое главное, наверное и для т...


Лучшие цены на 3D принтеры
успей сделать себе подарок к Новому Году! ;)


Prusa i3

Prusa i3 от 12500 р.



Rostoсk

Rostock от 15000 р.