Код (реализацию ШИМ почерпнул в интернете). Работа с EEPROM пока не реализована. Кнопка висит на PB0, а светодиод на PD0,PD1,PD2:
Код: Выделить всё
#include <avr/io.h>//подключаем библиотеку ввода/вывода
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#define nop() {asm("nop");}//функция необходимая для реализации задержки
volatile unsigned int ir,ig,ib,p,pp,c,buf,ms,x;//перечисление переменных
// функция задержки
void delay_ms(int ms)
{
for (x=ms;x>0;x--) nop();
}
// функция включения красного светодиода
void ledon0(int ms)
{
PORTD &= ~_BV(PD0); delay_ms(ms);
}
Спойлер
Код: Выделить всё
// функция включения зеленого светодиода
void ledon1(int ms)
{
PORTD &= ~_BV(PD1); delay_ms(ms);
}
// функция включения синего светодиода
void ledon2(int ms)
{
PORTD &= ~_BV(PD2); delay_ms(ms);
}
// функция выключения красного светодиода
void ledoff0(int ms)
{
PORTD |= _BV(PD0); delay_ms(ms);
}
// функция выключения зеленого светодиода
void ledoff1(int ms)
{
PORTD |= _BV(PD1); delay_ms(ms);
}
// функция выключения синего светодиода
void ledoff2(int ms)
{
PORTD |= _BV(PD2); delay_ms(ms);
}
void normwrk(void)
{
while(1)
{
//Когда кнопка выбора цвета не нажата, остается выбранный цвет
ledon1(ig); ledoff1(pp-ig);
ledon0(ir); ledoff0(pp-ir);
ledon2(ib); ledoff2(pp-ib);
}
}
void selcolor(void)
{
while(1)
{
//Зажигаем красный светодиод
PORTD &= ~_BV(PD0);
//плавное зажигание зеленого светодиода
for (ig = 0; ig < pp; ig++)
{
p=pp-ig; ledon1(ig); ledoff1(p);
}
//Зеленый светодиод остается гореть
PORTD &= ~_BV(PD1);
//плавное гашение красного светодиода
for (ir = 0; ir < pp; ir++)
{
p=pp-ir; ledon0(p); ledoff0(ir);
}
//Зеленый светодиод остается гореть
PORTD &= ~_BV(PD1);
//плавное зажигание синего светодиода
for (ib = 0; ib < pp; ib++)
{
p=pp-ib; ledon2(ib); ledoff2(p);
}
//Синий светодиод продолжает гореть
PORTD &= ~_BV(PD2);
//Плавное гашение зеленого светодиода
for (ig = 0; ig < pp; ig++)
{
p=pp-ig; ledon1(p); ledoff1(ig);
}
//Синий светодиод продолжает гореть
PORTD &= ~_BV(PD2);
//постепенное зажигание красного светодиода
for (ir = 0; ir < pp; ir++)
{
p=pp-ir; ledon0(ir); ledoff0(p);
}
//Красный светодиод продолжает гореть
PORTD &= ~_BV(PD0);
//Плавно тушим синий светодиод
for (ib = 0; ib < pp; ib++)
{
p=pp-ib; ledon2(p); ledoff2(ib);
}
}
}
// interrupt service routine (ISR) for timer 0 A compare match
SIGNAL (SIG_TIMER0_COMPA)
{
static char toggle = 0;
// toggle the LED on each interrupt
if (toggle==0 && bit_is_set(PINB,PB0))
{
delay_ms(50);
if (toggle==0 && bit_is_set(PINB,PB0))
{
toggle = 1;
selcolor();
}
}
else if (toggle==1 && !bit_is_set(PINB,PB0))
{
toggle = 0;
normwrk();
}
}
int main( void ) //главная программа
{
//конфигурирование на вывод порта D
DDRD |= _BV(PD0);//конфигурирование битов
DDRD |= _BV(PD1);//PD0, PD1 и PD2
DDRD |= _BV(PD2);//на выход
PORTD = 0xFF; //включаем подтягивающие резисторы
PORTB = 0b11111111; //Конфигурирование битов порта B ("в воздухе" с порта B будет читаться логическая 1)
DDRB = 0b00000000; //Конфигурирование порта B как входа
pp=255; //задаем скорость зажигания /гашения
ir=ig=ib=128;
TCCR0A = 0b00000000; //обычный режим таймера
TCCR0B = 0b00000011; //режим предделителя CLK/1024
TIMSK = 0b00000001; //разрешаем прерывания по переполнению
sei(); // global interrupt enable
normwrk();
while(1){}
}


