Модератор: boogyman
-
boogyman
- Модератор
- Сообщения: 183
- Зарегистрирован: 25 дек 2011, 22:48
- Откуда: Москва
#1
Сообщение
boogyman » 29 фев 2012, 23: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);}
}
}
-
Hamito
- Новичок
- Сообщения: 3
- Зарегистрирован: 29 фев 2012, 11:30
#2
Сообщение
Hamito » 01 мар 2012, 12:39
Прогонял в Avrstudio 4 и 5, у меня ошибки
-
Вложения
-

- errors.png (43.95 КБ) 24620 просмотров
-
boogyman
- Модератор
- Сообщения: 183
- Зарегистрирован: 25 дек 2011, 22:48
- Откуда: Москва
#3
Сообщение
boogyman » 01 мар 2012, 18:56
Ошибки скорей всего синтаксические, в коде ничего не менял?
-
Hamito
- Новичок
- Сообщения: 3
- Зарегистрирован: 29 фев 2012, 11:30
#4
Сообщение
Hamito » 01 мар 2012, 19:47
Нет, просто скопировал и вставил. Если посмотреть, то выдает одни и те же ошибки
-
boogyman
- Модератор
- Сообщения: 183
- Зарегистрирован: 25 дек 2011, 22:48
- Откуда: Москва
#5
Сообщение
boogyman » 01 мар 2012, 20:01
WINAVR нормально установлена?
-
Hamito
- Новичок
- Сообщения: 3
- Зарегистрирован: 29 фев 2012, 11:30
#6
Сообщение
Hamito » 02 мар 2012, 12:25
Обновил 4 версию проги, поставил AVR Toolchain 3.3.0 Это тот же винавр, только сейчас по-другому называется. Несколько ошибок осталось, но их удалось исправить. Спасибо за помощь
-
Vlad1m1r
- Новичок
- Сообщения: 3
- Зарегистрирован: 10 окт 2013, 12:46
#7
Сообщение
Vlad1m1r » 10 окт 2013, 13: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, вот как на них правильно включить шим? И вообще я правильно понял что только на них есть шим и таймер счетчики?
-
boogyman
- Модератор
- Сообщения: 183
- Зарегистрирован: 25 дек 2011, 22:48
- Откуда: Москва
#8
Сообщение
boogyman » 10 окт 2013, 23: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
-
Vlad1m1r
- Новичок
- Сообщения: 3
- Зарегистрирован: 10 окт 2013, 12:46
#9
Сообщение
Vlad1m1r » 11 окт 2013, 07:28
boogyman писал(а):В начале кода надо еще заменить канал OCR2 на OCR0A
Большое спасибо за отзывчивость!!!
Ну как я понял еще и входы нужно не забыть поменять
Код: Выделить всё
DDRB |= (1 << PB4)|(1 << PB3)|(1 << PB2); // PB4,3,2 - выходы
-
boogyman
- Модератор
- Сообщения: 183
- Зарегистрирован: 25 дек 2011, 22:48
- Откуда: Москва
#10
Сообщение
boogyman » 11 окт 2013, 12:14
Да, выходы надо обязательно поменять
-
Vlad1m1r
- Новичок
- Сообщения: 3
- Зарегистрирован: 10 окт 2013, 12:46
#11
Сообщение
Vlad1m1r » 13 окт 2013, 16:26
boogyman писал(а):В attiny2313 настройки 8-ми и 16 - ти разрядных таймеров похожи:
Хм... Странно, но работает в точности да наоборот. Сразу загорается цвет максимальной яркости, убавляется постепенно, а потом загорается так же медленно!!

Что-то похоже я еще не разобрался как работает аппаратный шим)))
-
uuu000
- Любитель
- Сообщения: 17
- Зарегистрирован: 08 апр 2019, 00:15
#12
Сообщение
uuu000 » 26 ноя 2020, 19:37
При попытке компиляции нашел11 ошибок в файле delay.h
"__builtin_avr_delay_cycles expects a compile time integer constant pwm 2 c:\program files (x86)\atmel\studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\util\delay.h 187"
Что обозначает эта ошибка?