Форма входа

Категории раздела

Силы природы [10]
Новые технологии [42]
Неопознанное [27]
Интересные факты [32]
Личности [22]
Объявления, предложения пользователей и гостей!!!! [29]
Поисковики хорошо индексирует этот раздел! Вам только остается преподнести как Вам это угодно.
Полезности [83]
Рациональные предложения [26]
Конструирование [68]
СУБКУЛЬТУРЫ [9]
Деньги [10]
Заряди свой комп!!! [49]
Пробуждение ВоинА [39]
Радиолюбителям [75]
Работа с интернетом [14]
Говорун [2]
Энергетика Релейная защита [36]
Авто-мото [3]
Искусство [10]
AliExpress [17]
Видео архив [40]
Рецепты и секреты [0]

Поиск

Слушать

Радио онлайн

"Техстудент"

Наш опрос

НЛО что это?
Всего ответов: 38

Мини-чат

500

Контроль

Партнёры

Воскресенье, 01.12.2024, 7:04:24
Приветствую Вас Интернет ПутниК
Главная | Регистрация | Вход | RSS

tehstudent.net

Журнал

Главная » Статьи » Полезности [ Добавить статью ]

Регулируем скорость вращения двигателя с помощью ШИМ(PWM)

Попробуем сварганить ШИМ, который меньше загружает процессор - это аппаратный ШИМ.
Tiny13 может аппаратно генерировать ШИМ на 2-х ногах PB0 и PB1, для чего необходимо сконфигурировать имеющийся единственный таймер соответствующим образом. Для экспериментов над лампочками нам подойдет "быстрый ШИМ" (Fast PWM) это когда таймер считает (регистр TCNT0) от 0x00 до 0xFF (режим №3) или от 0x00 до значения в регистре OCR0A (режим №7). Самый простой режим - №3, его и выберем. В этом режиме в момент счета таймера от 0 до ORC0A на выводе PB0 присутствует "0", а от OCR0A до 0xFF - "1" - это если выбран "неинвертирующий" (non-inverted) режим. Для "инвертирующего" (inverted) режима - наоборот, сначала "1", а потом "0". Для вывода PB1 все тоже самое, только вместо OCR0A - регистр OCR0B. Таким образом имеем картину, представленную на рисунке (взято из Datasheet):

То есть занося в регистры OCR0A и OCR0B разные значения мы получаем различную скважность импульсов. Собственно такая картина соответствует практически всем AVR контроллерам. Позднее я планирую написать отдельную статью с примерами, которая расскажет о всех режимах функционирования ШИМ в МК AVR. А пока будем использовать вот такую схему:

Здесь я присобачил интегрирующие цепочки R1C1 и R2C2, что бы показать как из ШИМ можно получить аналоговый сигнал, уровень которого будет пропорционален текущей скважности импульсов. Ескость C1 в 10 раз больше C2, что прождает более гладкую кривую нарастания напряжения (красная линия). Вот увеличенный кусочек, полученный по результатам симуляции (зеленая - R2C2):

Итак, как и в прошлый раз составим программу таким образом, что бы при подаче питания, или после нажатия и отпускания кнопки на выходе PB0 процент заполнения импульсов плавно увеличился от 0 до 100%.
Для этого в процедуре прерывания таймера 0 ( interrupt [TIM0_OVF] void timer0_ovf_isr(void) ) необходимо увеличивать значение регистра OCR0A на 1 до тех пор, пока оно не достигнет 0xFE. Значение 0xFF использовать нельзя, т.к. в этом случае на выходе PB0 установится "0", что собственно говоря и происходит приудерживании кнопки. Скорость нарастания яркости в данном случае регулируется константой, с которой сравнивается переменнас cnt в строке №37.

001./*****************************************************
002.This program was produced by the
003.CodeWizardAVR V2.03.9 Standard
004.Automatic Program Generator
005.© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
007. 
008.Project :
009.Version :
010.Date    : 15.09.2009
011.Author  : Valeron
012.Company : Home
013.Comments:
014. 
015. 
016.Chip type               : ATtiny13
017.AVR Core Clock frequency: 9,600000 MHz
018.Memory model            : Tiny
019.External RAM size       : 0
020.Data Stack size         : 16
021.*****************************************************/
022. 
023.#include <tiny13.h>
024.#include <delay.h>
025. 
026.int cnt=0;
027.char Step=0xFF;
028. 
029.// Timer 0 overflow interrupt service routine
030.interrupt [TIM0_OVF] void timer0_ovf_isr(void)
031.{
032.// Reinitialize Timer 0 value
033.TCNT0=0xFE;
034.// Place your code here
035.cnt++;
036.//Каждый 20-й заход в прерывание
037.if (cnt==19){
038.cnt=0;
039.//254 шага увеличения ширины импульса
040.if (Step !=0xFE ) {
041.Step++;
042.OCR0A=Step;   
043.}
044.}
045.}
046. 
047.// Timer 0 output compare A interrupt service routine
048.interrupt [TIM0_COMPA] void timer0_compa_isr(void)
049.{
050.// Place your code here
051. 
052.}
053. 
054.// Declare your global variables here
055. 
056.void main(void)
057.{
058.// Declare your local variables here
059.char st; //Состояние кнопки
060.// Crystal Oscillator division factor: 1
061.#pragma optsize-
062.CLKPR=0x80;
063.CLKPR=0x00;
064.#ifdef _OPTIMIZE_SIZE_
065.#pragma optsize+
066.#endif
067. 
068.// Input/Output Ports initialization
069.// Port B initialization
070.// Func5=Out Func4=Out Func3=In Func2=Out Func1=Out Func0=Out
071.// State5=0 State4=0 State3=P State2=0 State1=0 State0=0
072.PORTB=0x08;
073.DDRB=0x37;
074. 
075.// Timer/Counter 0 initialization
076.// Clock source: System Clock
077.// Clock value: 9600,000 kHz
078.// Mode: Fast PWM top=FFh
079.// OC0A output: Non-Inverted PWM
080.// OC0B output: Disconnected
081. 
082.TCCR0A=0x83;      //83=non-inverted, C3=inverted
083./* TCCR0A
084.(10)=Clear OC0A on Compare Match, set OC0A at TOP
085.|
086.--    --(11)=Fast PWM + WGM02 in TCCR0B=0
087.10000011
088.*/
089. 
090.TCCR0B=0x01;
091./* TCCR0B
092.-(0)=WGM02
093.00000001
094.*/
095.TCNT0=0x10;
096.OCR0A=0x00;
097.OCR0B=0x00;
098. 
099.// External Interrupt(s) initialization
100.// INT0: Off
101.// Interrupt on any change on pins PCINT0-5: Off
102.GIMSK=0x00;
103.MCUCR=0x00;
104. 
105.// Timer/Counter 0 Interrupt(s) initialization
106.TIMSK0=0x06;
107. 
108.// Analog Comparator initialization
109.// Analog Comparator: Off
110.ACSR=0x80;
111.ADCSRB=0x00;
112. 
113.// Watchdog Timer initialization
114.// Watchdog Timer Prescaler: OSC/1024k
115.// Watchdog Timer interrupt: Off
116.#pragma optsize-
117.WDTCR=0x39;
118.WDTCR=0x29;
119.#ifdef _OPTIMIZE_SIZE_
120.#pragma optsize+
121.#endif
122.// Global enable interrupts
123.#asm("sei")
124. 
125.while (1)
126.{   
127.#asm("wdr"); //Сброс сторожевого таймера
128.// Посмотрим состояние кнопки
129.st=PINB & 0b001000;
130.delay_us(50);    
131.if (!st) {
132.//Замкнута
133.Step=0xFF;
134.OCR0A=0xFF;
135.cnt=0;
136.}
137.};
138.}
139. 
140.</delay.h></tiny13.h>
Архив с проектом в CodeVisionAVR 2.03.9 и Proteus 7.5 sp3: pwmT13A.rar
  1. //Подключаем стандартные библиотеки необходимые для работы
  2. #include <avr/io.h>//библиотека ввода/вывода
  3. #include <avr/interrupt.h>//библиотека прерываний
  4.  
  5. #define nop() {asm("nop");}//функция позаимствованная из ассемблера "nop"
  6.  
  7. //перечисление переменных
  8. unsigned int i=1;//переменная для ШИМ
  9. unsigned int p;//переменная для ШИМ
  10. unsigned int pp=50;//переменная для ШИМ скорость нарастания напряжения
  11. unsigned int ms;//переменная для задержки
  12. unsigned int x;//переменная для задержки
  13.  
  14. //Попрограммы обработки прерываний
  15. SIGNAL(SIG_INTERRUPT0)//обработка прерываний кнопки "+"
  16. {
  17. pp=pp+1;//увеличение при нажатии на кнопку "+" на 1
  18. }
  19.  
  20. SIGNAL(SIG_INTERRUPT1)//обработка прерываний кнопки "-"
  21. {
  22. pp=pp-1;//уменьшение при нажатии на кнопку "-" на 1
  23. }
  24.  
  25. //функция задержки
  26. void delay_ms(int ms)
  27. {
  28. for (x=ms;x>0;x--)
  29. nop ();
  30. }
  31.  
  32. //Функция включения бита 0 порта B
  33. void ledon(int ms)
  34. {
  35. PORTB = 0x01;
  36. delay_ms(ms);
  37. }
  38.  
  39. //Функция выключения бита 0 порта B
  40. void ledoff(int ms)
  41. {
  42. PORTB = 0x00;
  43. delay_ms(ms);
  44. }
  45.  
  46. //Основная программа
  47. int main( void )
  48. {
  49. DDRB=0x01;//конфигурирование порта B на выход
  50.  
  51. GIMSK=0b11000000; //разрешаем прерывание int0 и int1
  52. MCUCR=0b00001111;// прерывание по возрастающему фронту - для кнопки 1 и 2
  53.  
  54. sei();//разрешаем прерывания
  55.  
  56. for (;;)//бесконечный цикл
  57. {
  58. p=pp-i;//реализация
  59. ledon(p);//программного
  60. ledoff(i);//ШИМ
  61. }
  62. }

Категория: Полезности | Добавил: snettens (15.02.2012)
Просмотров: 2708 | Теги: Регулируем скорость вращения двигат | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: