Jag har skrivit en C-kod för min RGB-lampa men det tycks inte fungera som den ska.
Den hoppar totalt över alla funktioner och lägger sig på ca 50% på PWMen.
Så, init_seq(), hoppar den över vilket som annars ska fadea mellan Röd, Grön, Blå sen bli vit.
Interupten för "change program" tycks inte heller fungera.
Jag har setat länge med att försöka hitta ett fel men hittar inget.
Röd sitter på PORTB.0, grön på PORTB.1 och blå på PORTB.2 sen interupten på PINB.5.
Kan någan ta en liten stund att kolla igenom denna kod på 261 rader?
Edit1: Har ändrat koden till hur den ser ut nu.
Edit2: Ändrat efter medelandet 24-sep-2006 21:50.
Kod: Markera allt
/*
This code is specially made for an Atmel AVR ATtiny45.
*/
#define F_CPU 8000000
#define RGB_PIN (1<<0)|(1<<1)|(1<<2)
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#include <stdlib.h>
void init_seq(void);
void rgb_program(void);
void rgb_comp(uint8_t, uint8_t, uint8_t);
void rgb_counter(void);
void rgb_pwm(void);
void delay_x(void);
volatile uint8_t rgb[3] = {0,0,0};
volatile uint8_t rgb_compare[3] = {0,0,0};
volatile uint8_t program_nr = 0;
volatile uint16_t counter = 0;
volatile uint8_t pwm_counter = 0;
volatile uint16_t delay_time = 0;
volatile uint8_t buttom_time = 0;
int main(void)
{
unsigned int addr = 1; // EEPROM adress.
uint8_t out_value = eeprom_read_byte((unsigned char *) addr);
// Increase value on that location in EEPROM and write it to down.
out_value++;
eeprom_write_byte((unsigned char *) addr, out_value);
// Use out_value to get a different rand() after each start.
srand(out_value);
// Set DDRB0,1,2 for output, rest for input.
DDRB = RGB_PIN;
PORTB = ~RGB_PIN; // Enable pullup on the inputs and set RGB Pins to low.
// The interupt sequence for the "Change Program" button.
PCMSK = (1<<5); // Triggen on PORTB.5.
GIFR = (1<<5)|(1<<6);
GIMSK = (1<<5);
// Initialize Timer.
// Enable timer compare interrupt.
TIMSK = (1<<OCIE0A);
// Sets the compare value.
OCR0A = 200;
// Set Clear on Timer Compare (CTC) mode, No prescaler.
TCCR0A = (1<<WGM01)|(0<<WGM00); // CTC mode.
TCCR0B = (1<<CS00); // No prescaler.
init_seq();
while(1)
rgb_program();
return 0;
}
// For the RGB PWM and R,G,B values inc/dec.
SIGNAL(SIG_OUTPUT_COMPARE0A)
{
rgb_counter(); // The counter for a soft color change.
rgb_pwm(); // Run the Software RGB PWM.
}
// For the "Change Program" button.
SIGNAL(SIG_PIN_CHANGE)
{
buttom_time = 0;
if (PINB & (1<<5))
buttom_time = 0xD0;
}
// Then init sequence.
void init_seq(void)
{
rgb_comp(255,0,0);
delay_x();
rgb_comp(0,255,0);
delay_x();
rgb_comp(0,0,255);
delay_x();
}
// The program that changes color after the program number.
void rgb_program(void)
{
const unsigned char RGB_Data[][3] =
{
{255,255,255}, {128,128,128},
{255,0,0}, {128,0,0},
{255,255,0}, {128,128,0},
{0,255,0}, {0,128,0},
{0,255,255}, {0,128,128},
{0,0,255}, {0,0,128},
{255,0,255}, {128,0,128},
{255,156,230}, {128,78,115}
};
uint8_t r1, r2, r3;
if (program_nr < 16)
rgb_comp(RGB_Data[program_nr][0],RGB_Data[program_nr][1],RGB_Data[program_nr][2]);
switch (program_nr)
{
case 16:
{
rgb_comp(255,0,0);
delay_x();
rgb_comp(255,255,0);
delay_x();
rgb_comp(0,255,0);
delay_x();
rgb_comp(0,255,255);
delay_x();
rgb_comp(0,0,255);
delay_x();
rgb_comp(255,0,255);
delay_x();
break;
}
case 17 :
{
rgb_comp(128,0,0);
delay_x();
rgb_comp(128,128,0);
delay_x();
rgb_comp(0,128,0);
delay_x();
rgb_comp(0,128,128);
delay_x();
rgb_comp(0,0,128);
delay_x();
rgb_comp(128,0,128);
delay_x();
break;
}
case 18 :
{
r1 = ((unsigned int) rand() % 128) + 128;
r2 = ((unsigned int) rand() % 128) + 128;
r3 = ((unsigned int) rand() % 128) + 128;
rgb_comp(r1,r2,r3);
delay_x();
break;
}
default: program_nr = 0;
}
}
// The color changer. It tells rgb_counter() what it should count to for a dynamic change.
void rgb_comp(uint8_t r, uint8_t g, uint8_t b)
{
rgb_compare[0] = r;
rgb_compare[1] = g;
rgb_compare[2] = b;
}
// Counts the RGB up and down with aprox 89steps/sec. So it takes aprox 3sec to go from 0-255.
// So it won't be a stepy convertion between colors.
void rgb_counter(void)
{
if (counter > 450)
{
if (rgb_compare[0] < rgb[0])
rgb[0]--;
else if (rgb_compare[0] > rgb[0])
rgb[0]++;
if (rgb_compare[1] < rgb[1])
rgb[1]--;
else if (rgb_compare[1] > rgb[1])
rgb[1]++;
if (rgb_compare[2] < rgb[2])
rgb[2]--;
else if (rgb_compare[2] > rgb[2])
rgb[2]++;
counter = 0;
}
counter++;
}
// The Software PWM that controlls the Red, Green and Blue brightness and mix.
// Works at aprox. 156Hz.
void rgb_pwm(void)
{
if (pwm_counter == 0)
{
if (rgb[0] != 0)
PORTB |= 0x01;
if (rgb[1] != 0)
PORTB |= 0x02;
if (rgb[2] != 0)
PORTB |= 0x04;
delay_time++;
if (buttom_time & 0x80)
buttom_time++;
if (buttom_time == 0xFF)
program_nr++;
}
if (pwm_counter > rgb[0])
PORTB &= ~0x01;
if (pwm_counter > rgb[1])
PORTB &= ~0x02;
if (pwm_counter > rgb[2])
PORTB &= ~0x04;
pwm_counter++;
}
void delay_x(void)
{
delay_time = 0;
while (delay_time >= 450);
}
