Zdravím.
Začínám se pomalu učit C na mikrokontrolérech AVR. Po pár pokusech s ledkami a “Hello World” na LCD jsem si pohrál se změnou barev RGB LEDky. Dalo by se tomu nadneseně říkat “můj první program”. Co na to říkáte? Jistě by se to dalo nějak optimalizovat, tak prosím klidně poučte začátečníka
Použil jsem Atmegu 16, anody jsem připojil na piny portu A takto: 4,5 - modrá, 6 - zelená, 7 - červená. Krystal běží na 16 MHz.
Definoval jsem tyto proměnné.
char to_red=0x01; // priznak cervene - 0=inkrementace, 1= po inkrementaci, 2= dekerementace, 3= po dekrementaci
char to_green=0x03; // priznak zelene
char to_blue=0x02; // priznak modre
int tmp_red=0xFF; // toto pricti k cervene
int tmp_green=0x00; // toto pricti k zelene
int tmp_blue=0xFF; // toto pricti k modre
int cnt_red=0; // citac cervene
int cnt_green=0; // citac zelene
int cnt_blue=0; // citac modre
unsigned int cnt_pgm=0; //citac cyklu
Pro řízení barev jsem vycházel z následujícího: Použil jsem 8 bitový model RGB, kde má každá složka intenzitu 0 - 255. Požadovanou intenzitu barvy zapisuji do proměnné tmp_color. Tuto proměnnou přičítám k cnt_color a potom, co přesáhne hodnotu 255 nastavím příslušný bit portu na 1 (ledka svítí). V dalším cyklu nastavím bit opět na nulu.
Barvy chci měnit napříč spektrem postupně od červené k zelené, modré a zpět k červené.
// Vlastni rizeni casu svitu. Kazda barva sviti v rozmezi 1 - 255 cyklu
{
cnt_red=cnt_red + tmp_red; // citani cervene
if (cnt_red >=255)
{PORTA=PORTA |0b10000000;
cnt_red=0;
}
else
{PORTA=PORTA &0b01111111;
};
cnt_green=cnt_green + tmp_green; // citani zelene
if (cnt_green >=255)
{PORTA=PORTA |0b01000000;
cnt_green=0;
}
else
{PORTA=PORTA &0b10111111;
};
cnt_blue=cnt_blue + tmp_blue; // citani modre
if (cnt_blue >=255)
{PORTA=PORTA |0b00110000;
cnt_blue=0;
}
else
{PORTA=PORTA &0b11001111;
};
Zde si nastavuji příznaky, aby se mi barvy měnily postupně tak, jak jsem si určil.
[code] /* Výchozí barvou je po zapnutí je purpurová. Barvy se mění postupně takto:
1. krok - dekrementace modre
2. krok - inkrementace zelene
3. krok - dekrementace cervene
4. krok - inkrementace modre
5. krok - dekrementace zelene
6. krok - inkrementace cervene
Nastaveni priznaku: 0=inkrementace, 1= po inkrementaci, 2= dekerementace, 3= po dekrementaci
*/
// cervena
if (to_red == 0 && tmp_red >=255) { // barva inkrementovala na vrchol
to_red = 1; // nastav priznak barva po inkrementaci
to_blue = 2; // dekrementuj predchozi barvu
};
if (to_red == 2 && tmp_red <=0) { // barva dekrementovala na dno
to_red = 3; // nastav priznak barva po dekrementaci
to_blue = 0; // inkrementuj dalsi barvu
};
//zelena
if (to_green == 0 && tmp_green >=255) { // barva inkrementovala na vrchol
to_green = 1; // nastav priznak barva po inkrementaci
to_red = 2; // dekrementuj predchozi barvu
};
if (to_green == 2 && tmp_green <=0) { // barva dekrementovala na dno
to_green = 3; // nastav priznak barva po dekrementaci
to_red = 0; // inkrementuj dalsi barvu
};
//modra
if (to_blue == 0 && tmp_blue >=255) { // barva inkrementovala na vrchol
to_blue = 1; // nastav priznak barva po inkrementaci
to_green = 2; // dekrementuj predchozi barvu
};
if (to_blue == 2 && tmp_blue <=0) { // barva dekrementovala na dno
to_blue = 3; // nastav priznak barva po dekrementaci
to_green = 0; // inkrementuj dalsi barvu
}; [/code]
Aby se barvy měnily pomalu, inkrementuji nebo dekrementuji obsah tmp_color vždy až po 8000 cyklech.
cnt_pgm ++; // citani cyklu, po kazdem preteceni vynuluj a podle priznaku nastav hodnoty tmp_color
if (cnt_pgm >=8000)
{cnt_pgm=0;
if (to_red == 0)
{tmp_red ++;
}
if (to_red == 2)
{tmp_red --;
}
if (to_green == 0)
{tmp_green ++;
}
if (to_green == 2)
{tmp_green --;
}
if (to_blue == 0)
{tmp_blue ++;
}
if (to_blue == 2)
{tmp_blue --;
}
Programuji pomocí CodevisionAVR a AVR Dragon přes JTAG.