rgb led attiny13
Добавлено: 25 янв 2013, 05:30
Здравствуйте!
этот код написан в WinAVR для attiny13
скажите почему игнорируется, не работает кнопка на PB3?
алгоритм должен быть следующим:
1. При подаче питания (включении) цвета плавно медленно перетекают,
2. Одно быстрое нажатие на кнопку ставит цвет на паузу
3. Одно быстрое нажатие на кнопку в режиме паузы: цвета плавно медленно перетекают
4. Одно долгое (удерживаемое) нажатие: цвета быстро перетекают (типа перемотка) во время нажатия,
5. Отпустили кнопку и цвета перетекают в обычном режиме
этот код написан в WinAVR для attiny13
скажите почему игнорируется, не работает кнопка на PB3?
алгоритм должен быть следующим:
1. При подаче питания (включении) цвета плавно медленно перетекают,
2. Одно быстрое нажатие на кнопку ставит цвет на паузу
3. Одно быстрое нажатие на кнопку в режиме паузы: цвета плавно медленно перетекают
4. Одно долгое (удерживаемое) нажатие: цвета быстро перетекают (типа перемотка) во время нажатия,
5. Отпустили кнопку и цвета перетекают в обычном режиме
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1200000UL
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
#define RED PB0
#define GREEN PB1
#define BLUE PB2
#define BUTTON PB3 // if you shorted to ground
volatile int SPEED = 15;
volatile int count = 0;
typedef struct {
int red;
int green;
int blue;
} rgb;
rgb channels = { 0x00, 0x00, 0x00 };
#define DEBUG_MODE 0
#define RAINBOW_MODE 1
#define SOLID_MODE 2
int lighting_mode;
// overflow interrupt timer
ISR(TIM0_OVF_vect) {
TCNT0 = 230;
if ((PINB & (1 << BUTTON)) !== 1) { // pressed, there was a bounce
count++;
if (count>2) { // made sure that the button is actually pressed
lighting_mode = SOLID_MODE; // stopped changing colors
}
if (count>70) { // if you hold the button for over 1.5 seconds
lighting_mode = RAINBOW_MODE;
SPEED = 3; // rewind
}
}
else {
count = 0;
SPEED = 15;
lighting_mode = RAINBOW_MODE;
}
}
void rainbow_step(void) {
if(channels.blue > 0x00 && channels.red == 0xFF && channels.green == 0x00) {
channels.blue--;
}
if(channels.blue == 0xFF && channels.red < 0xFF && channels.green == 0x00) {
channels.red++;
}
if(channels.green > 0x00 && channels.blue == 0xFF && channels.red == 0x00) {
channels.green--;
}
if(channels.green == 0xFF && channels.blue < 0xFF && channels.red == 0x00) {
channels.blue++;
}
if(channels.red > 0x00 && channels.green == 0xFF && channels.blue == 0x00) {
channels.red--;
}
if(channels.red == 0xFF && channels.green < 0xFF && channels.blue == 0x00) {
channels.green++;
}
}
void solid_step(void) {
}
void do_pwm(int r_duty, int g_duty, int b_duty, int rate) {
int i;
while (rate != 0) {
PORTB |= (1<<RED) | (1<<GREEN) | (1<<BLUE);
for (i=0; i < 255; i++) {
if (i == r_duty)
output_low(PORTB, RED);
if (i == g_duty)
output_low(PORTB, GREEN);
if (i == b_duty)
output_low(PORTB, BLUE);
}
rate--;
}
}
void init(void) {
channels.red = 0xFF;
lighting_mode = RAINBOW_MODE;
DDRB &= ~(1<<PB3); // PB3 configure the input
PORTB |= (1 << PB3); // Pullup Power
set_output(DDRB, RED);
set_output(DDRB, GREEN);
set_output(DDRB, BLUE);
}
int main(void)
{
init();
// timer
TCCR0A = 0;
TCCR0B = 0b00000101; //divider
TCNT0 = 230;
TIMSK0 = 0b00000010; // Resolution overflow interrupt
sei();
while (1) {
switch (lighting_mode) {
case DEBUG_MODE:
break;
case RAINBOW_MODE:
rainbow_step();
break;
case SOLID_MODE:
solid_step();
break;
default:
lighting_mode = RAINBOW_MODE;
}
do_pwm(channels.red, channels.green, channels.blue, SPEED);
}
return 0;
}