В этом проекте я реализовал управление RGB-лентой — цвета плавно меняются.Получилась вот такая схемка.
В схеме можно ставить любые n-канальные транзисторы, я к примеру использовал транзисторы выпаянные с материнской платы.
Алгоритм смены цветов такой:
0) Начнем с красного цвета 255-0-0.
1) Наращивается зеленый цвет 255-1-0, 255-2-0 … 255-255-0.
2) Уменьшается красный цвет 254-255-0, 253-255-0 … 0-255-0.
3) Наращивается синий цвет 0-255-1, 0-255-2 … 0-255-255.
4) Уменьшается зеленый цвет 0-254-255, 0-253-255 … 0-0-255.
5) Наращивается красный цвет 1-0-255, 2-0-255 … 255-0-255.
6) Уменьшается синий цвет 255-0-254, 255-0-253 … 255-0-0.
Вот что получилось , смотрите на видео — правда на видео невидно всей той полноты цветопередачи .
Ничего лишнего, никаких наворотов — просто переливание цветов.
Исходный код программы:
Chip type : ATtiny13 AVR Core Clock frequency: 9,600000 MHz Memory model : Tiny External RAM size : 0 Data Stack size : 16 *****************************************************/ #include <tiny13.h> #include <delay.h> #define OUT_R PORTB.3 #define OUT_G PORTB.4 #define OUT_B PORTB.2 #include <stdlib.h> unsigned char rgb_r =0,rgb_g=0,rgb_b=0; unsigned char count = 0; unsigned char r=0,g=0,b=0; unsigned char step=0; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { count++; //канал красного if (count == 0) { //если счетчик переполнился и принял значение 0 rgb_r = r; //сохранием значения в буфер OUT_R =1; //выставляем ноги, отвечающие за ШИМ в логическую 1 } if (rgb_r == count) { OUT_R = 0;}//по достижении заданной скважности выводим 0 // канал зелёного if (count == 0) { //если счетчик переполнился и принял значение 0 rgb_g = g; //сохранием значения в буфер OUT_G =1; //выставляем ноги, отвечающие за ШИМ в логическую 1 } if (rgb_g == count) { OUT_G = 0;}//по достижении заданной скважности выводим 0 // канал синего if (count == 0) { //если счетчик переполнился и принял значение 0 rgb_b = b; //сохранием значения в буфер OUT_B =1; //выставляем ноги, отвечающие за ШИМ в логическую 1 } if (rgb_b == count) { OUT_B = 0;}//по достижении заданной скважности выводим 0 } void main(void) { // Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B initialization // Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out // State5=P State4=T State3=T State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 9600,000 kHz // Mode: Normal top=0xFF // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x01; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x02; // Global enable interrupts #asm("sei") srand(6); while (1) { /* По-умолчанию формулу R-G-B начнем с красного цвета 255-0-0. 1) Наращивается зеленый цвет 255-1-0, 255-2-0 ... 255-255-0. 2) Уменьшается красный цвет 254-255-0, 253-255-0 ... 0-255-0. 3) Наращивается синий цвет 0-255-1, 0-255-2 ... 0-255-255. 4) Уменьшается зеленый цвет 0-254-255, 0-253-255 ... 0-0-255. 5) Наращивается красный цвет 1-0-255, 2-0-255 ... 255-0-255. 6) Уменьшается синий цвет 255-0-254, 255-0-253 ... 255-0-0. */ if(step==0) { //step = rand() % 6 + 1; step=1; } if(step==1) { r++; g=0;b=0; if(r>=255){step=2;} } if(step==2) { g++; if(g>=255){step=3;} } if(step==3) { r--; if(r<=0){step=4;} } if(step==4) { b++; if(b>=255){step=5;} } if(step==5) { g--; if(g<=0){step=6;} } if(step==6) { r++; if(r>=255){step=7;} } if(step==7) { b--; if(b<=0){step=0;} } delay_ms(30); } }
Фьюзы выставить на 9.6мгц и выключить делитель на 8.
Скачать проект Attiny13 + RGB лента Скачали 4024 раз
Добрый день.
Хтел бы повторить Ваш RGB для ATTiny13-й. Сам не знаток, написать с нуля, копирую.
Но исходник не компилируется. Ошибок много, самая первая — нет файла Tiny13.h.
Для эксперимента делаем эту строку комментарием, начинает ругаться на другие.
Копилятор Atmel Studio 7.0. До этого в этом комипиляторе работал — все в порядке.
Не просветите?
Это исходник в компиляторе CodeVisionAVR, поэтому он у вас и не компилируется
А как нужно изменить программу, что б переход между цветами происходил быстро (полсекунды), а конечный цвет горел долго (пару секунд)?
Здравствуйте, Артем.
Не могли бы Вы скинуть hex -файл мне на почту. Попробовал Ваш код компилировать на AVRStudio, она ругается, попытка получить hex на CоdeVision дает файл в 2 килобайта, что для 13 тиньки многовато. (wish.yurasik@yandex.ru)
И еще вопрос : как изменять скорость нарастания/погасания лампы?
заливайте код полученный в кодевижене — он влезет — поверьте))
Спасибо за исходники. Хочу сделать шим в машину, чтобы свет плавно включался и выключался. Очень полезная статья. Автору +
Та не за что) Удачи с проектом! Если потом захотите опубликовать свою статью здесь — пишите) оформим)
Бросается в глаза — слишком много «if (count == 0) » в обработке прерывания таймера.
Это программная реализация ШИМ — можно сделать и по другому, но я сделал так)
Привет, подскажите пожалуйста какие галочки фьюз битов нужны, а какие — нет, на пример в PonyProg или CodeVision AVR (в UniProf инверстно) желательно скриншотом..хочу повторить, а с фьюзами так и не подружился..
А вот когда перед новым кругом смены цвета есть затухание(перед красным цветом) хотелось бы его убрать, это нужно просто стереть в конце кода строчку
delay_ms(30);
}
или просто «30» заменить на 0 или 1 ?
Скрин добавил к статье. Задержка у нас тут косвенно изменяет скорость смены цветов.
Чтобы убрать последнее затухание:
if(step==7)
{
b—;
if(b<=0){step=2;} } изменяем значение начала. Должно работать.