Микроконтроллеры ATTiny13A. Восстанавливаем новогоднюю елку.

  • Цена: $4.83/10шт

Иногда нужно запрограммировать маленькую задачку, для которой даже Ардуино слишком избыточен. Для таких небольших задач могут подойти маленькие, недорогие и очень маломощные контроллеры ATTiny.
В этом обзоре я и расскажу о них, как их готовить и с чем есть.

Купил я ATTiny13 довольно давно. Лежали они и ждали своего часа. И тут на работе я нашел настольную световодную елочку со сгоревшей начинкой. Вот тут то и вспомнил про этик контроллеры.
Но все по порядку


Начнем с характеристик ATTiny13

Это 8-битные контроллеры от корпорации Atmel c RISC-архитектурой и сверхнизким потреблением.

  • Память для программ (FLASH) — 1Кб
  • Энергонезависимая память данных (EEPROM) — 64 Байт
    ОЗУ — 64 Байт
    Число входов/выходов — 6
    Выходов ШИМ — 2
    Аналоговых входов (АЦП 10бит) — 4
    Таймер 8 бит — 1
    Напряжение питания 1.8 — 5.5В
    Рабочая частота — до 20МГц
    Потребление в активном режиме 1.8В/ 1МГц — 190мкА
    Потребление в режиме сна 1.8В/1МГц — 24мкА
  • Подробнее можно узнать из даташитаЯ приобрел тиньки в корпусе DIP8. В корпусе SOP8 они стоят дешевлеПо сравнению с ATMega328P из этого обзора они очень маленькие

    Программирование ATTiny

    Программировать я решил из Arduino IDE, Тем более я уже настраивал эту среду для работы с «народным WiFi» ESP8266На сайте arduino.cc есть ветка, посвященная работе ATTiny13 в среде Ардуино. Оттуда же качаю ATTiny core for Arduino IDE. Распаковываю архив в папку c:\Program Files (x86)\Arduino\hardware\ и в Arduino IDE появляются дополнительные платыТеперь загрузка программ. Объем памяти микропроцессора всего 1Кб и никакой загрузчик туда не поместится. Поэтому загрузка скетчей производится программатором по ISP. USBAsp, которым я программировал Atmega328 работать с тинькой не захотел. Нужна специальная прошивка программатора, с которой я не стал возиться. Программировать микроконтроллер можно и при помощи любой Ардуины. Для этого собираю такую схему:В Arduino IDE выбираю «Файл->Образцы->ArduinoISP» и загружаю в Ардуино скетч программатора. Затем выбираю «Инструменты->Программатор->Arduino as ISP». Теперь можно загружать простые скетчи в тиньку. Следует отметить, что ATTiny13 core for Arduino содержит ограниченный набор функций Ардуино.
    Список функций Апдуино, поддерживаемых ATTiny13 core
    map()
    • random()
    • randomSeed()

    • millis()
    • micros()
    • delay()
    • delayMicroseconds() *
    • analogRead()
    • analogWrite()
    • pinMode()
    • digitalRead()
    • digitalWrite()
    • pulseIn() (Untested)
    • shiftIn() (Untested)
    • shiftOut() (Untested)

    Применение ATTiny13

    Решил восстановить такую елочку со световодамиИзначально там стояла галогенная лампочка на 12В и моторчик, который крутил цветной диск-светофильтрВсе это благополучно померло. Собираю такую схему с кусочком светодиодной ленты:на макетной платеПусть тинька плавно изменяет цвета ленты. Но для этого нужно 3-х канальный ШИМ, а у ATTiny13 аппаратно только два таких выхода. Значит ШИМ будет программный на 3 канала, управляемый встроенным таймером.
    Скетч трех-канального ШИМ для ATTiny13
    
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    uint8_t counter=0;
    uint8_t lev_ch1, lev_ch2, lev_ch3;
    uint8_t buf_lev_ch1, buf_lev_ch2, buf_lev_ch3;
    
    
    ISR(TIM0_OVF_vect){
    
      if (++counter==0) //счетчик перехода таймера через ноль
      {
        buf_lev_ch1=lev_ch1; //значения длительности ШИМ
        buf_lev_ch2=lev_ch2;
        buf_lev_ch3=lev_ch3;
        PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2); //подаем 1 на все каналы
      }
      
      if (counter==buf_lev_ch1) PORTB&=~(1<<PB1); //подаем 0 на канал
      if (counter==buf_lev_ch2) PORTB&=~(1<<PB0); //по достижении
      if (counter==buf_lev_ch3) PORTB&=~(1<<PB2); //заданной длительности.
    
    }
    
    int main(void)
    {
      DDRB=0b00000111; // установка PortB пины 0,1,2 выходы
        // таймер работает без предделителя
        TCCR0B = _BV(CS00);
        // прерывания по переполнению таймера разрешены
        TIMSK0 = _BV(TOIE0);
        // глобально прерывания так же разрешены
        sei();
    
    
    
      lev_ch1=0;   //Красный цвет
      lev_ch2=255; //Зеленый цвет
      lev_ch3=0;   //Синий цвет
    
      while (1)     //бесконечная шарманка
      {
    
        for (uint8_t i=0;i<256;i++) {
          lev_ch1  = i;           //Красный увеличиваем
          lev_ch2  = 255-i; //Зеленый уменьшаем
          _delay_us(5000); //Пауза 5мс 
        }
        for (uint8_t i=0;i<256;i++){
          lev_ch3  = i;  //Синий увеличиваем
          lev_ch1  = 255-i;  //Красный уменьшаем
          _delay_us(5000); //Пауза 5мс 
        }
        for (uint8_t i=0;i<256;i++) {
          lev_ch2 = i; //Зеленый увеличиваем
          lev_ch3 = 255-i; //Синий уменьшаем
          _delay_us(5000); //Пауза 5мс
        }
    
      }
    }
    
    

    После этого остается только закрепить плату и ленту в корпусе елочки. Белый скотч наклеиваю для улучшения светоотражения внутри черного корпусаЕлочка готова. Светит не хуже чем с галогенной лампочкой

    Выводы:

    Микроконтроллеры ATTiny13 вполне годятся для несложных задач автоматизации.Их достоинства: низкое потребление и небольшая цена К недостаткам можно отнести очень маленькие ресурсы и довольно сложную (по сравнению с обычным Ардуино) настройку программирования.Но безусловно, эти микроконтроллеры достойно занимают свою нишу

    Полезные ссылки

Планирую купить +71 Добавить в избранное +80 +150
+
avatar
  • olgerd
  • 19 ноября 2015, 20:31
+1
«Значит ШИМ будет программный на 3 каГала,» таки да?
+
avatar
  • sav13
  • 19 ноября 2015, 20:44
+4
Таки поправил )))
+
avatar
  • Ezheg
  • 20 ноября 2015, 03:59
-5
+
avatar
  • akaivp
  • 20 ноября 2015, 08:21
+1
но сделали это небрежно, что почти сводит на нет затраченные усилия
Зачем уже так категорично?..
+
avatar
0
Более чем уверен, что елочку отремонтировали не для того, чтобы накатать обзор на mysku.
+
avatar
  • IOPA4
  • 22 ноября 2015, 17:10
+1
Можно попробовать так:

  lev_ch1=0;   //Красный цвет
  lev_ch2=255; //Зеленый цвет
  lev_ch3=127;   //Синий цвет

while (1)     //бесконечная шарманка
  {
      if (lev_ch1==255) lev_ch1=0;
	  lev_ch1++;           //Красный увеличиваем
      if (lev_ch2==0) lev_ch2=255;
      lev_ch2--; 			//Зеленый уменьшаем
	  if (lev_ch3==255) lev_ch3=0;
	  lev_ch3++;		    //Синий увеличиваем
      _delay_us(5000); //Пауза 5мс 
  }
+
avatar
  • ksiman
  • 19 ноября 2015, 20:37
+1
Можно было добавить кнопочку для хоть какого-нибудь разнообразия (если памяти хватит)
+
avatar
  • sav13
  • 19 ноября 2015, 20:45
+1
Памяти хватит. Там меньше половины ушло. Просто на деле эту кнопку никто не будет трогать на работе. Разве что эффектов больше всяких разных добавить, чтобы перебирались
+
avatar
  • ksiman
  • 19 ноября 2015, 20:51
0
Тогда можно просто плавно менять период изменения яркости каждого канала по случайному закону.
+
avatar
  • IOPA4
  • 22 ноября 2015, 17:49
0
lev_ch1=0;   //красный
  lev_ch2=64; //зеленый
  lev_ch3=127;   //синий


  while (1)     //бесконечный цикл
  {
     for (uint8_t i=0; i<255; i++)
	 {
	   if (lev_ch1==255) lev_ch1=0;
	   lev_ch1++;           //красный
       if (lev_ch2==0) lev_ch2=255;
       lev_ch2--; 			//зеленый
	   if (lev_ch3==255) lev_ch3=0;
	   lev_ch3++;		    //синий
       _delay_us(5000); //задержка
     }
	 temp =lev_ch1; lev_ch1=lev_ch2; lev_ch2 = lev_ch3; lev_ch3=temp; //меняем яркость цветов местами

	 for (uint8_t i=0; i<255; i++)
	 {
	   if (lev_ch1==255) lev_ch1=0;
	   lev_ch1++;           //красный
       if (lev_ch3==0) lev_ch3=255;
       lev_ch3--; 			//синий
	   if (lev_ch2==255) lev_ch2=0;
	   lev_ch2++;		    //зеленый
       _delay_us(5000); //задержка
     }
	 temp =lev_ch2; lev_ch2=lev_ch1; lev_ch1 = lev_ch3; lev_ch3=temp; //меняем яркость цветов местами

	 for (uint8_t i=0; i<255; i++)
	 {
	   if (lev_ch2==255) lev_ch2=0;
	   lev_ch2++;           //синий
       if (lev_ch1==0) lev_ch1=255;
       lev_ch1--; 			//зеленый
	   if (lev_ch3==255) lev_ch3=0;
	   lev_ch3++;		    //красный
       _delay_us(5000); //задержка
     }
	 temp =lev_ch3; lev_ch3=lev_ch2; lev_ch2 = lev_ch3; lev_ch1=temp;  //меняем яркость цветов местами
  }
}

+
avatar
  • ksiman
  • 22 ноября 2015, 19:58
0
Зачем писать _delay_us(5000) если можно delay_ms (5)
+
avatar
  • IOPA4
  • 22 ноября 2015, 21:52
0
Согласен. Сильно не задумывался, хотел только разнообразить эффекты, убрать однообразность.
+
avatar
  • Dimsim
  • 06 октября 2018, 23:26
0
IOPA4, что то ваш скетч не компилируется.
Выдаёт ошибку:
exit status 1
'temp' was not declared in this scope
Можете дать полную версию скетча, который будет компилироваться?
+
avatar
  • IOPA4
  • 07 октября 2018, 07:44
+1
Так добавьте новую переменную и все компилится.

uint8_t buf_lev_ch1, buf_lev_ch2, buf_lev_ch3, temp;
+
avatar
  • Dimsim
  • 07 октября 2018, 12:48
+1
Ну это для вас, может так всё очевидно и просто. Но, не все же здесь программисты.
Большое спасибо за ответ.
+
avatar
  • Dimon_
  • 19 ноября 2015, 20:44
+2
Тот диск с трафаретом был хитрый.
Там полосатые секторы не зря — от них по ветвям бежали интересные тени, т.к. это транспортировалось пучком световодов к кончикам ветвей.
Посему бы не лентой это надо делать, а сконцентировать на малой площади, соразмерной с пучком световодов, n светодиодов сверхярких разноцветных или даже полноцветных. А тиньки вполне хватит для красивой «причудливости» их переливов.
+
avatar
  • sav13
  • 19 ноября 2015, 20:48
+1
N-светодиодов потребует n*3 выводов. У тиньки их максим 6.
Можно поставить светодиоды WS2812. Есть примеры работы с ними, но, ИМХО, овчинка не стоит выделки. Для WS2812 вожно найти гораздо более достойное применение в НГ
+
avatar
  • ksiman
  • 19 ноября 2015, 20:52
0
N-светодиодов потребует n*3 выводов. У тиньки их максим 6.
Reset лучше не трогать, поэтому реально 5 пинов у неё
+
avatar
  • sav13
  • 19 ноября 2015, 20:55
0
Можно, конечно регистры воткнуть, или микросхему многоканального ШИМ, но гляжу я на эту елочку — такой примитив. Тогда нудно пучки световодов разделять, крепить светики напротив.
+
avatar
  • Dimon_
  • 19 ноября 2015, 20:57
0
Не, полноцветных, конечно, много не получится, это я загнул, а вот пяток разноцветных — вполне.

Впрочем — ради праздничного настроения, чего не пожалеешь, можно и не 13, а 2313 туда засунуть. Тогда и разгуляться можно с многоцветием, переливами и прочим :)
+
avatar
  • AFCrio
  • 20 ноября 2015, 13:48
0
TLC5940NT и лепим сколько хотим. Схема чуть больше, но имеем 16 каналов с ШИМ и возможностью каскадного включения.
+
avatar
  • sav13
  • 20 ноября 2015, 14:09
0
Если посмотреть цену на нее, то вполне можно Atmega8/168/328 применить с SoftPWM на всех ее выводах.
+
avatar
  • Kilinic
  • 19 ноября 2015, 22:22
+5
да бросьте вы, хорошо получилось. Большинство бы просто выкинуло елку, а тут руки из правильного места растут.
+
avatar
  • Ammo1
  • 19 ноября 2015, 23:50
+2
Круто как! Завидую чёрной завистью. Как же я хочу научится этим всем ардуинам, аттиням, распберям и эдисонам!
Но некогда и мозгов уже не хватает. :(
+
avatar
  • DVANru
  • 19 ноября 2015, 23:55
0
Класс!!!
+
avatar
  • drv
  • 20 ноября 2015, 00:03
0
Сначала подивился выбору стабилизатора (уж больно избыточен он для тиньки), а потом понял, что видимо с прошлого заказа еще остались, грех не воспользоваться ;)
А за прямые руки и креативный подход однозначно плюс!
13ый очень удачный малыш, и не только для оживления игрушек.
+
avatar
0
там красный и синий от 0 до 254 ходят, а зеленый от 1 до 255) эта елка — тест на перфекционизм?))

"… и лишь слегка несимметрично стоят щербатые котлы...")
+
avatar
  • sav13
  • 20 ноября 2015, 05:16
0
Это вы о чем? Все три цикла 0-255
+
avatar
0
del, это мне спать надо больше) клинит, всё верно там, от 0 до 254 это как раз 255 инкрементов)
+
avatar
  • sav13
  • 20 ноября 2015, 05:37
0
Ладно уговорили. Поправил.
Так лучше для перфикционистов?
+
avatar
0
извиняюсь, там верно было всё, 255 должно быть, поправил прошлое сообщение, но было уже поздно)
+
avatar
0
Что-то мне кажется данные по потреблению энергии сильно оптимистичны. Во-первых тиньки не умеют работать с внешним кварцем, как их производителю удалось затактировать на 1 Мгц — загадка (от внешнего генератора разве что, но такое извращение в реальности не встречается), можно получить 1,2 Мгц включив делитель на 8. На практике потребление 2-3 мА с разгруженными ногами, никак не сотни мкА причем от делителя не зависит (питание 3-4 вольта, питать микроконтроллер от 2 вольт это тоже в реальности очень редкое дело). В режимах энергосбережения, кои в 13 тиньке дельные, там да.
+
avatar
  • sav13
  • 20 ноября 2015, 05:21
0
Я взял характеристики по энергопотреблению с даташита. Там же и про 1МГц.
Кстати, смотрю на фьюзы — вполне сложно сделать 8МГц + тот же делитель на 8
На счет питания — лично мне интересно питания от двух ААА (идеально от одной) Там получае напряжение как раз до 2В будет падать на двух полуразряженных аккумуляторах
+
avatar
0
Эта характеристика — удельное потребление на каждый мегагерц тактовой частоты. берешь частоту на которой работает контроллер и умножаешь на этот показатель получаешь потребление.

А 1Мгц вполне можно сделать, коррекция внутреннего генератора работает в широких пределах. Причем менять корректирующий коэффициент можно прямо во время работы.
+
avatar
  • pranik
  • 20 ноября 2015, 01:14
-1
Идея хороша, реализация ужс. Ожидал увидеть более законченную конструкцию, а не кривой кусок макетной платы и ленту на скотче. И, страшно подумать, использовать ардуину для прошивки тиньки. Есть же avrdude, khazama avr… + usbasp
+
avatar
  • sav13
  • 20 ноября 2015, 05:26
+4
Есть два способа реализации:
1. Купить все детали, вытравить печатную плату, красиво все собрать
2. Выгрести из ящика всякое неиспользуемое барахло, недостающее выпаять со старых плат и из всего этого г… сделать конфетку. Здесь иногда удовольствия от реализации даже поболе.

А чем не нравится Ардуина в качестве программатора. И чем она от USBAsp отличается принципиально? Контроллер чуть помощнее? Конструктив другой? Да и цена у Pro Mini не намного от программатора отличается. Так что дело вкуса.
+
avatar
  • Kiril22
  • 20 ноября 2015, 06:00
0
А как второе противоречит первому? Сам очень часто использую компоненты с плат-доноров и люблю сделать красиво. Как раз для удовольствия от реализации и платы травлю, и детальки в «ровный рядок» запаиваю. Хотя вполне допускаю, что это только моя особенность увлечения.
+
avatar
  • sav13
  • 20 ноября 2015, 07:40
0
Ну кому то нравится делать красивые платы, а кому то писать программы ;)
+
avatar
0
Хотел написать «рад, что кто-то еще помнит про тини13, и жаль, что их нельзя программировать из среды Ардуино»…
А потом прочитал… A Elbereth Gilthoniel! иными словами — ё моё!
В общем — рукоплещу «спасибо!» в 100500 рук!
… если кто не понял, у меня завалялся мешочек 13х тинек… :)
+
avatar
  • sav13
  • 20 ноября 2015, 07:59
+1
Все руки не доходят «простые вольтметры» собирать. Как там у тинек со встроенным ИОН? Противоречивые сведения в интернете
+
avatar
  • Kiril22
  • 20 ноября 2015, 05:37
0
В последнее время все больше ловлю себя на мысли, что в своих проектах стал чаще использовать smd компоненты. И причина этому одна — мне лень сверлить платы. Я один такой? Хотя для макетки DIP самое то.
+
avatar
  • sav13
  • 20 ноября 2015, 05:41
0
А как же двухсторонняя печать монтаж и металлизация отверстий? Не лень делать?
Здесь то я могу дырочек и перемычек сколько угодно сделать.
Хотя SMD на двухсторонке на порядок компактнее и эстетичнее
+
avatar
  • Kiril22
  • 20 ноября 2015, 06:07
0
Я вовсе не призываю отказаться от отверстий. Просто, мне удобнее использовать поверхностный монтаж там, где можно обойтись без сверловки. Про двусторонние платы Вы правы. А вот металлизацию отверстий в домашних условиях еще не осваивал; видимо потребности нет :)
+
avatar
  • sav13
  • 20 ноября 2015, 07:57
0
А я скоро соберу микросверлильный станок из CDROM-привода и маленького моторчика и буду получать удовольствие от сверления
+
avatar
+4
Спасибо за обзор! Думаю, что работа достойна уважения. Не страшно, что сделано на монтажке, тут особая красивость и не нужна.
+
avatar
  • sav13
  • 20 ноября 2015, 08:14
+3
Спасибо за понимание.
А то гнобят за отсутствие печатки.
+
avatar
  • ksiman
  • 20 ноября 2015, 08:24
+4
В единичном экземпляре проще и быстрее делать на макетной плате — для того они и предназначены.
+
avatar
  • Sanja
  • 20 ноября 2015, 17:09
0
Простите за чайницкий вопрос — а ей что, кварц не нужен? Кроме питания 3.3 вольт ей, получается, никакой обвязки не надо?
+
avatar
  • sav13
  • 20 ноября 2015, 17:20
0
Кварц там внутри. Ничего больше не нужно
+
avatar
  • ksiman
  • 20 ноября 2015, 17:43
0
Нет там кварца, есть RC генератор с термокомпенсацией и автоподстройкой частоты.
Для часов точность недостаточна.
+
avatar
0
Нет там термокомпенсации. Она есть только в ATTINY45 и 85 а они стоят в 2 и 4 раза дороже.
+
avatar
  • ksiman
  • 21 ноября 2015, 23:23
0
Да, точно, с ними и попутал :)
+
avatar
  • dansar
  • 21 ноября 2015, 15:15
0
Зачем насилуете несчастную 1кб тиньку всей этой ардуйней? Я понимаю, если это мегапроект с wifi и без ардуино тяжело писать, но программный ШИМ можно было и без библиотек реализовать.
+
avatar
  • sav13
  • 22 ноября 2015, 07:39
0
Ну тиньки от этого не жарко, ни холодно.
Если памяти хватает, то разницы нет, на ассемблере писать или на Си или на «Виринге».
Сейчас хочу еще туда программный сериал порт запихнуть для отладки.

Все равно по ресурсам тинька это игрушка.
+
avatar
0
Я заганял в тиню13-ю 100 строк ардуиновского кода и ещё оставалось место. Главное уметь распоряжаться ресурсами.

Но если тот код переписать на Си то думаю получилось бы 250 строчек, но памяти занимало бы это меньше.
+
avatar
+2
О, моя статья на гиктаймс, моя первая статья…
+
avatar
  • sav13
  • 22 ноября 2015, 16:08
+1
Статья про прошивку через ардуино?
Большое спасибо. Читал с интересом.
+
avatar
0
Да. Спасибо.

Было когда-то желание что-то писать, сейчас уже отбилось напрочь, работа забирает как время так и силы.
+
avatar
  • heruSS
  • 23 ноября 2015, 15:55
0
Плюс в карму за труд)
+
avatar
  • dizzy
  • 26 ноября 2015, 15:19
0
usbasp прекрасно справляется с attiny13. Лично проверял :) Если брать последнюю прошивку для usbasp, то нужно просто выставить перемычку J3, понижающую частоту тактирования. Вот фраза из readme:

J3 SCK option
If the target clock is lower than 1,5 MHz, you have to set this jumper.
Then SCK is scaled down from 375 kHz to about 8 kHz.

Эту перемычку, в принципе, можно и для остальных ардуин использовать — просто время прошивки немного увеличится.

Где-то были упоминание того, что для atmel частота программатора не должна превышать частоту «программируемого» более чем в 8 раз.
+
avatar
  • mregor
  • 20 апреля 2021, 09:39
0
На самом деле можно обойтись и без перемычки. В параметр avrdude добавить параметр -B 2000. Например avrdude -c usbasp -P /dev/ttyUSB0 -p t13 -B 2000 -U flash:w:file.hex. 2000 это максимальная частота с которой у меня заработала тинька. Можно меньше.
+
avatar
0
Скажите, а диск-светофильтр у вас остался? Я просто тоже восстанавливаю елку, но там другого типа светофильтр, а я давно за таким гоняюсь.
+
avatar
  • ikhbin
  • 11 ноября 2017, 01:10
0
обзор tiny13, а рассказ про рукожопство какое-то… кю
+
avatar
  • Dimsim
  • 08 октября 2018, 21:53
0
Повторил проект. Что то у меня не работает как на видео у автора. Светодиоды мерцают, плавного переливания цветов нет.
Прошивал с помощью Arduino 1.8.5.
+
avatar
  • Dimsim
  • 11 октября 2018, 00:24
0
Заработало!!!
Для этого нужно сменить частоту.
К примеру, мне нужно, чтобы ATtiny13 работал на частоте в 4.8 мГц, я выбираю нужную мне частоту и только один раз жму кнопку «Записать загрузчик» — всё. Теперь микроконтроллер будет всегда работать на заданной частоте, если будет нужно изменить частоту опять — проделываем описанную выше процедуру.
Выбрал частоту 4.8 мГц., нажал на кнопку «Записать загрузчик». Теперь светодиоды мигают плавно.
+
avatar
  • ELITE
  • 09 ноября 2018, 17:08
0
очень полузная статейка, какраз делаю герлянду и нужен был код

но вот код кривой — нет павнойти переходов — обрывы по яркости на 0…

переписал малость )
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//макросы для включения, выключения светодиодов
//низкий уровень - на ножке 0 вольт, высокий уровень - на ножке 5 вольт
#define LED1_OFF PORTB &= ~(1<<PB0); //Низкий уровень ножки PB0 (синий)
#define LED2_OFF PORTB &= ~(1<<PB1); //Низкий уровень ножки PB1 (зеленый)
#define LED3_OFF PORTB &= ~(1<<PB2); //Низкий уровень ножки PB2 (красный)
 
#define LED1_ON PORTB |= (1<<PB0);  //Высокий уровень ножки PB0 
#define LED2_ON PORTB |= (1<<PB1);  //Высокий уровень ножки PB1
#define LED3_ON PORTB |= (1<<PB2); //Высокий уровень ножки PB2

uint8_t counter=0, chenal=0, i=0;
uint8_t lev_ch[3];
uint8_t ch[3];
uint8_t buf_lev_ch[3];


ISR(TIM0_OVF_vect){

  if (++counter==0) //счетчик перехода таймера через ноль
  {
    buf_lev_ch[0]=lev_ch[0]; //значения длительности ШИМ
    buf_lev_ch[1]=lev_ch[1];
    buf_lev_ch[2]=lev_ch[2];
  LED1_ON; LED2_ON; LED3_ON; // PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2); //подаем 1 на все каналы BGR (0=B 1=G 2=R)
  }
  
  if (counter==buf_lev_ch[0]) LED1_OFF; //подаем 0 на канал
  if (counter==buf_lev_ch[1]) LED2_OFF; //по достижении
  if (counter==buf_lev_ch[2]) LED3_OFF; //заданной длительности.

}

int main(void)
{
  DDRB=0b00000111; // установка PortB пины 0,1,2 выходы
  TCCR0B = _BV(CS00);   // таймер работает без предделителя  
  TIMSK0 = _BV(TOIE0);// прерывания по переполнению таймера разрешены   
  sei();// глобально прерывания так же разрешены

  lev_ch[0]=0;   //Красный цвет
  lev_ch[1]=0;     //Зеленый цвет
  lev_ch[2]=0;     //Синий цвет

if (lev_ch[0]==0 && lev_ch[1]==0 && lev_ch[2]==0 ) chenal=0;

while (1)     //бесконечная шарманка
  {
    //формирование значений со сдвигом на 128 (0-64-127)
   ch[0]=i%256;
   ch[1]=(i+64)%256;
   ch[2]=(i+127)%256;
   
   i++;
      if( ch[0] < 128) {lev_ch[0] = ch[0]; } else {lev_ch[0] = 256-ch[0]; };
      if( ch[1] < 128) {lev_ch[1] = ch[1]; } else {lev_ch[1] = 256-ch[1]; };
      if( ch[2] < 128) {lev_ch[2] = ch[2]; } else {lev_ch[2] = 256-ch[2]; };

      _delay_us(5000); //Пауза 5мс 
  }
  
}


делает плавно нарастание и уменьшение яркости со сдвигом на 1/2 цвета
+
avatar
  • ELITE
  • 09 ноября 2018, 18:17
0
ай така лучше
j=i%128;   i++;
     if (j==0) ci++;
     if (ci==6) ci=0;
      
      
     if( ci==0) {      lev_ch[0]=j;       lev_ch[1]=0;      lev_ch[2]=127;         } 
     if( ci==1) {      lev_ch[0]=127;     lev_ch[1]=0;      lev_ch[2]=127-j;       } 
     if( ci==2) {      lev_ch[0]=127;     lev_ch[1]=j;      lev_ch[2]=0;           } 
     if( ci==3) {      lev_ch[0]=127-j;   lev_ch[1]=127;    lev_ch[2]=0;           } 
     if( ci==4) {      lev_ch[0]=0;       lev_ch[1]=127;    lev_ch[2]=j;           } 
     if( ci==5) {      lev_ch[0]=0;       lev_ch[1]=127-j;  lev_ch[2]=127;         } 


полный перелив всех цветов