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

Конфигурируем ШИМ в 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
Просмотров: 56087 | Комментарии: 65 | Теги: bascom-avr, ШИМ, Timer1, PWM, Timer0, ATtiny2313 | Рейтинг: 4.7/18
Всего комментариев: 65« 1 2 3 »
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 раза выше.

32 exersizze   (29.07.2013 16:04) [Материал]
jr23, он входит в состав симулятора proteus

31 jr23   (27.07.2013 08:42) [Материал]
Где я могу скачать digital oscilloscope ?

30 sany2   (11.05.2013 14:17) [Материал]
Возможно ли увеличить частоту шим,кроме как кварцем?
Config Timer1 = Pwm , Pwm = 8 , Compare B Pwm = Clear Up , Prescale = 1
Частота при 8мгц примерно 15кгц,а нужно порядка 60
И немного из другой области- можно ли управлять N-канальным полевиком напрямую с микроконтролёра?

29 marss70   (24.03.2013 17:50) [Материал]
Всё скомпилировалось, я так и не понял в чём была засада. Три раза скопировал-вставил ...

28 marss70   (24.03.2013 16:43) [Материал]
У меня при компиляции в первом примере выдаёт ошибку на строчку:
Incr Pwm1b
При её удалении всё компилируется.

27 exersizze   (24.02.2012 00:00) [Материал]
Проверил код. Таки действительно без конфигурирования портов как выходы шима нет. Добавил это в листинг в статье, спасибо!

26 osa   (22.02.2012 13:46) [Материал]
Bascom-AVR
Compiler version :2.0.5.0
Compiler build :2.0.5.0.0
IDE version :2.0.5.0

25 exersizze   (22.02.2012 13:13) [Материал]
Версия компилятора какая? Возможно для новых версий нужно указывать, что порты являются выходами.
Проверю еще раз с кодом из примера, возможно у меня порты были настроены на выход в файле конфига.

24 osa   (22.02.2012 12:02) [Материал]
Все. Разобрался. Все таки ошибка в программе. Чтобы программа корректно заработала нужно после конфигурирования таймера вставить Config Portb.4 = Output Config Portb.3 = Output для первого примера, или Config Portb.2 = Output Config Portb.0 = Output для второго. Без этого, по крайней мере у меня, микросхема ничего не отдает.

23 osa   (21.02.2012 15:37) [Материал]
Другие каналы шим, тоже пробовал использовать. Более того, если я не использую таймеры, а просто подаю на эти ноги логическую единицу, то светодиод прекрасно работает. Видимо проблема в том, что не стартует почему-то таймер.

22 exersizze   (21.02.2012 11:32) [Материал]
интересно.. а точно к выходам шим светодиоды подключил? попробуй использовать другие каналы шим, из второго примера.

21 osa   (21.02.2012 10:34) [Материал]
Токоограничительный резистор само собой стоит, 470 ом. Код я зашиваю тот что приведен здесь, в первом примере.

20 exersizze   (17.02.2012 19:31) [Материал]
токоограничительный резистор стоит на светодиоде? покажи код который зашиваешь в мк

19 osa   (17.02.2012 13:16) [Материал]
Уже неделю бьюсь с этой программкой, в попытке разобраться в ШИМ. Ничего не получается. И фьюзы проверял и микросхему менял и монтаж перепроверял. Хоть убей, в режиме поморгать светодиодом, порты работают а выдать на них ШИМ сигнал не получается. При этом в Протеусе, вроде как все работает, на осциллографе по крайней мере, виден вполне себе нормальный ШИМ сигнал. Чувствую себя клиническим идиотом...

18 exersizze   (17.01.2012 00:24) [Материал]
Да про него и рассказывать особо нечего, в одном из проектов я в коментариях к исходникам описывал работу с ним. Вот здесь http://avrproject.ru/publ/sounds_detector/1-1-0-8 Но может как-нибудь освещу эту тему подробней

17 slava022967   (17.01.2012 00:01) [Материал]
статья супер! Все понятно! А можно и про компоратор в таком стиле? Очень интересует.

16 exersizze   (15.10.2011 10:17) [Материал]
Все правильно делали, командой bin. Проверил в симуляторе Proteus вот этот код:

Code
$regfile = "m32def.dat"
$crystal = 1000000
$baud = 1200
$sim

Dim A As Word

Dim S As String * 16

Config Timer1 = Timer , Prescale = 1024

Start Timer1

Do

S = Bin(tcnt1)

Print S

Loop

End


Все работает:



а вот со встроенным симулятором есть грабли, если не поставить галку "Sim timers", то симуляция таймеров не запустится и будут нули:



и присвоение значения счетчика переменной Word с последующим преобразованием этой переменной командой bin тоже без проблем.
версия компилятора 1.11.9.8

15 pchela5   (15.10.2011 00:41) [Материал]
Доброй ночи! Вопрос немного не в тему, но надеюсь на помощь:
столкнулся с такой проблемой - как считать в строковую переменную разрядностью 16 символов битовое значение timer1?
пример:
Strstring = Bin(tcnt1) - записывает в строчку иладший байт, если я сделаю предварительно вывод на терминал - то оба байта:
Print "tcnt1 : " ; Bin(tcnt1)
Strstring = Bin(tcnt1)
пробовал записать значение счетчика в переменную с типом word с последующим преобразованием - ругается.
и почему то 16-и битный Timer1 не работает на частоте мегагерц и более при внутренней тактовой 8 Мгц (хотя сейчас кажется понял в чем дело - счетчик 74нс590 на выходе переноса - откуда идет тактирование для Timer1 имеет слишком узкий выход)

14 otszn1   (20.09.2011 18:26) [Материал]
Благодарю, всё получилось smile

13 exersizze   (16.09.2011 20:44) [Материал]
да тут кода три строчки =) если камень живой и таймер работает, то шим генерироваться должен полюбому.
проверьте фьюзы, должны быть на 4 МГц (если в тестовой программе не меняли); ну и для отладки можно на другой ноге просто светодиодиком помигать, видно будет, стартанул процессор или нет.

12 otszn1   (16.09.2011 11:56) [Материал]
доброе время суток smile я только начинаю осваивать микроконтроллеры и данная статья помогла в кое чем разобраться, но к сожалению при попытке посмотреть как оно будет в железе, после прошивки контроллера ни каких признаков жизни не появилось,подскажите пожалуйста где может скрываться ошибка

11 tenevikus   (31.07.2011 19:06) [Материал]
у меня пока вот такая кнопка трудиться

http://mklab.net.ua/stati005.html

но тратить столько железок на каждую кнопку, в сравнении с вышеописанным вариантом.... cool как-то surprised ... жуть

надо раскурить более простой вариант biggrin

10 exersizze   (31.07.2011 18:03) [Материал]
Товарищ kip обещал поделится результатами опытов со своими сенсорами, только ближе к осени. Ну или сами попробуйте, код есть, может что получится =)

9 tenevikus   (31.07.2011 17:29) [Материал]
пример в студию biggrin

8 exersizze   (31.07.2011 13:14) [Материал]
Вроде ничего сложного, да и принцип хорошо описан. Было как-то обсуждение реализации на васике: http://bascomavr.3bb.ru/viewtopic.php?id=551

7 tenevikus   (31.07.2011 12:25) [Материал]
кстати может кто сможет набросать на баскоме прогу как тут в статье

http://www.getchip.net/posts/060-drajjver-sensornojj-klaviatury-touch-me-na-attiny2313/

никак не могу догнать как они сделали это? biggrin

6 tenevikus   (31.07.2011 12:20) [Материал]
спасибо огромное за статью

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






авторизация
Логин:
Пароль: