AVR и аппаратный ШИМ

Модератор: boogyman

AVR и аппаратный ШИМ

Сообщение:#1  Сообщение boogyman » 29 фев 2012, 22:26

Чем аппаратный ШИМ отличается от программного? В программном мы просто переключаем ножку контроллера с нуля на единицу с большой частотой и меняем задержку между переключениями. В аппаратном ШИМе мы снимаем сигнал с ножек контроллера OC1A, OC1B, OC2 которые напрямую подключены к таймерам/счетчикам, тут остается лишь настроить сами таймеры и менять верхний предел счета для изменения коэффициента заполнения ШИМ. Ниже представлен код проекта управления RGB светодиодом на atmega8.
Код: Выделить всё
/*** Управление RGB светодиодом. Аппаратный ШИМ ***/
#include <avr/io.h>
#include <util/delay.h>

#define pwm_r OCR1A // канал для красного цвета
#define pwm_g OCR1B // канал для зеленого цвета
#define pwm_b OCR2 // канал для синего цвета

/*** красный цвет ***/
void red (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_r = 255 - a; //увеличение
         pwm_g = 0;
         pwm_b = 0;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
            pwm_r = a; //уменьшение
         pwm_g = 0;
         pwm_b = 0;
         _delay_ms(time);
      }
   }

/*** зеленый цвет ***/
void green (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
          pwm_g = 255 - a;
         pwm_r = 0;
         pwm_b = 0;
         _delay_ms(time);
      }     
       
      for (char a = 0; a<254; a++)
      {
         pwm_g = a;
         pwm_r = 0;
         pwm_b = 0;
         _delay_ms(time);
      }

   }
/*** синий цвет ***/
void blue (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_b = 255 - a;
         pwm_g = 0;
         pwm_r = 0;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
         pwm_b = a;
         pwm_g = 0;
         pwm_r = 0;
         _delay_ms(time);
      }
   }
/*** белый цвет ***/
void white (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_r = 255 - a;
         pwm_g = 255 - a;
            pwm_b = 255 - a;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
            pwm_r = a;
         pwm_g = a;
         pwm_b = a;
         _delay_ms(time);
      }
   }

/*** переход цветов ***/
void rgb (unsigned int time)
   {
       for (char a = 0; a<254; a++)
      {
         pwm_r = a;
         pwm_b = 255 - a;
         pwm_g = 0;
         _delay_ms(time);
      }

      for (char a = 0; a<254; a++)
      {
         pwm_b = a;
         pwm_g = 255 - a;
         pwm_r = 0;
         _delay_ms(time);
      }
      
      for (char a = 0; a<254; a++)
      {
         pwm_g = a;
         pwm_r = 255 - a;
         pwm_b = 0;
         _delay_ms(time);
      }
   }

int main (void)
{
   DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1); // PB3,2,1 - выходы
   
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10); // сброс OC1A/OC1B при достижении верхнего предела счета
    TCCR1B |= (1<<CS10); // без предделителя
    TCCR2 |= (1<<CS20)|(1<<COM21)|(1<<WGM20); // без предделителя, сброс OC2 при достижении верхнего предела счета
   
   pwm_r = 0; // начальные установки ШИМ
   pwm_g = 0;
   pwm_b = 0;

    while(1)
   {    
   red(5);
    green(5);      
    blue(5);
   white(5);
   for(;;)
   {rgb(100);}
   }
}
Аватара пользователя
boogyman
Модератор
 
Сообщения: 183
Зарегистрирован: 25 дек 2011, 21:48
Откуда: Москва

Re: AVR и аппаратный ШИМ

Сообщение:#2  Сообщение Hamito » 01 мар 2012, 11:39

Прогонял в Avrstudio 4 и 5, у меня ошибки
Вложения
errors.png
errors.png (43.95 КБ) Просмотров: 11644
Аватара пользователя
Hamito
Новичок
 
Сообщения: 3
Зарегистрирован: 29 фев 2012, 10:30

Re: AVR и аппаратный ШИМ

Сообщение:#3  Сообщение boogyman » 01 мар 2012, 17:56

Ошибки скорей всего синтаксические, в коде ничего не менял?
Аватара пользователя
boogyman
Модератор
 
Сообщения: 183
Зарегистрирован: 25 дек 2011, 21:48
Откуда: Москва

Re: AVR и аппаратный ШИМ

Сообщение:#4  Сообщение Hamito » 01 мар 2012, 18:47

Нет, просто скопировал и вставил. Если посмотреть, то выдает одни и те же ошибки
Аватара пользователя
Hamito
Новичок
 
Сообщения: 3
Зарегистрирован: 29 фев 2012, 10:30

Re: AVR и аппаратный ШИМ

Сообщение:#5  Сообщение boogyman » 01 мар 2012, 19:01

WINAVR нормально установлена?
Аватара пользователя
boogyman
Модератор
 
Сообщения: 183
Зарегистрирован: 25 дек 2011, 21:48
Откуда: Москва

Re: AVR и аппаратный ШИМ

Сообщение:#6  Сообщение Hamito » 02 мар 2012, 11:25

Обновил 4 версию проги, поставил AVR Toolchain 3.3.0 Это тот же винавр, только сейчас по-другому называется. Несколько ошибок осталось, но их удалось исправить. Спасибо за помощь
Аватара пользователя
Hamito
Новичок
 
Сообщения: 3
Зарегистрирован: 29 фев 2012, 10:30

Re: AVR и аппаратный ШИМ

Сообщение:#7  Сообщение Vlad1m1r » 10 окт 2013, 12:01

boogyman писал(а):Чем аппаратный ШИМ отличается от программного? В программном мы просто переключаем ножку контроллера с нуля на единицу с большой частотой и меняем задержку между переключениями. В аппаратном ШИМе мы снимаем сигнал с ножек контроллера OC1A, OC1B, OC2 которые напрямую подключены к таймерам/счетчикам, тут остается лишь настроить сами таймеры и менять верхний предел счета для изменения коэффициента заполнения ШИМ. Ниже представлен код проекта управления RGB светодиодом на atmega8.
Код: Выделить всё
/*** Управление RGB светодиодом. Аппаратный ШИМ ***/
#include <avr/io.h>
#include <util/delay.h>

#define pwm_r OCR1A // канал для красного цвета
#define pwm_g OCR1B // канал для зеленого цвета
#define pwm_b OCR2 // канал для синего цвета

/*** красный цвет ***/
void red (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_r = 255 - a; //увеличение
         pwm_g = 0;
         pwm_b = 0;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
            pwm_r = a; //уменьшение
         pwm_g = 0;
         pwm_b = 0;
         _delay_ms(time);
      }
   }

/*** зеленый цвет ***/
void green (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
          pwm_g = 255 - a;
         pwm_r = 0;
         pwm_b = 0;
         _delay_ms(time);
      }     
       
      for (char a = 0; a<254; a++)
      {
         pwm_g = a;
         pwm_r = 0;
         pwm_b = 0;
         _delay_ms(time);
      }

   }
/*** синий цвет ***/
void blue (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_b = 255 - a;
         pwm_g = 0;
         pwm_r = 0;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
         pwm_b = a;
         pwm_g = 0;
         pwm_r = 0;
         _delay_ms(time);
      }
   }
/*** белый цвет ***/
void white (unsigned int time)
   {
        for (char a = 0; a<254; a++)
      {
            pwm_r = 255 - a;
         pwm_g = 255 - a;
            pwm_b = 255 - a;
         _delay_ms(time);
      }     
        for (char a = 0; a<254; a++)
      {
            pwm_r = a;
         pwm_g = a;
         pwm_b = a;
         _delay_ms(time);
      }
   }

/*** переход цветов ***/
void rgb (unsigned int time)
   {
       for (char a = 0; a<254; a++)
      {
         pwm_r = a;
         pwm_b = 255 - a;
         pwm_g = 0;
         _delay_ms(time);
      }

      for (char a = 0; a<254; a++)
      {
         pwm_b = a;
         pwm_g = 255 - a;
         pwm_r = 0;
         _delay_ms(time);
      }
      
      for (char a = 0; a<254; a++)
      {
         pwm_g = a;
         pwm_r = 255 - a;
         pwm_b = 0;
         _delay_ms(time);
      }
   }

int main (void)
{
   DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1); // PB3,2,1 - выходы
   
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10); // сброс OC1A/OC1B при достижении верхнего предела счета
    TCCR1B |= (1<<CS10); // без предделителя
    TCCR2 |= (1<<CS20)|(1<<COM21)|(1<<WGM20); // без предделителя, сброс OC2 при достижении верхнего предела счета
   
   pwm_r = 0; // начальные установки ШИМ
   pwm_g = 0;
   pwm_b = 0;

    while(1)
   {    
   red(5);
    green(5);      
    blue(5);
   white(5);
   for(;;)
   {rgb(100);}
   }
}


Здравствуйте, а как нужно этот код поменять чтоб он заработал на attiny2313! :-)
Как я понимаю у 2313 4 аппаратных шим, и два таймер счетчика по два канала пврада один 8 а второй 16 разрядный!
Ножки на которых есть таймер счетчик это oc0b/PD5, это нога стоит как то омобнеком, а три остальные вместе это oc0a/PB2, oc1a/PB3, oc1b/PB4, вот как на них правильно включить шим? И вообще я правильно понял что только на них есть шим и таймер счетчики?
Аватара пользователя
Vlad1m1r
Новичок
 
Сообщения: 3
Зарегистрирован: 10 окт 2013, 11:46

Re: AVR и аппаратный ШИМ

Сообщение:#8  Сообщение boogyman » 10 окт 2013, 22:05

В attiny2313 настройки 8-ми и 16 - ти разрядных таймеров похожи:
Код: Выделить всё
TCCR1A |= (1 << COM1A1)|(1 << COM1B1)|(1 << WGM10); // сброс OC1A/OC1B при достижении верхнего предела счета
TCCR1B |= (1 << CS10); // без предделителя
TCCR0A |= (1 << COM0A1)|(1 << WGM00); // сброс OC0A при достижении верхнего предела счета
TCCR0B |= (1 << CS00); // без предделителя


В начале кода надо еще заменить канал OCR2 на OCR0A
Аватара пользователя
boogyman
Модератор
 
Сообщения: 183
Зарегистрирован: 25 дек 2011, 21:48
Откуда: Москва

Re: AVR и аппаратный ШИМ

Сообщение:#9  Сообщение Vlad1m1r » 11 окт 2013, 06:28

boogyman писал(а):В начале кода надо еще заменить канал OCR2 на OCR0A


Большое спасибо за отзывчивость!!! :-)

Ну как я понял еще и входы нужно не забыть поменять :-)
Код: Выделить всё
DDRB |= (1 << PB4)|(1 << PB3)|(1 << PB2); // PB4,3,2 - выходы
Аватара пользователя
Vlad1m1r
Новичок
 
Сообщения: 3
Зарегистрирован: 10 окт 2013, 11:46

Re: AVR и аппаратный ШИМ

Сообщение:#10  Сообщение boogyman » 11 окт 2013, 11:14

Да, выходы надо обязательно поменять
Аватара пользователя
boogyman
Модератор
 
Сообщения: 183
Зарегистрирован: 25 дек 2011, 21:48
Откуда: Москва

Re: AVR и аппаратный ШИМ

Сообщение:#11  Сообщение Vlad1m1r » 13 окт 2013, 15:26

boogyman писал(а):В attiny2313 настройки 8-ми и 16 - ти разрядных таймеров похожи:


Хм... Странно, но работает в точности да наоборот. Сразу загорается цвет максимальной яркости, убавляется постепенно, а потом загорается так же медленно!! :) Что-то похоже я еще не разобрался как работает аппаратный шим)))
Аватара пользователя
Vlad1m1r
Новичок
 
Сообщения: 3
Зарегистрирован: 10 окт 2013, 11:46


Вернуться в Микроконтроллеры AVR

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

cron
Rambler's Top100