AVR - LED panel - #5 Program Tisk
Koutek AVR -
Napsal uživatel Michal, OK1WMR   
Sobota, 09 Duben 2011 07:33

Kompatibilní zapojení: LED panel s ATmega8

Ke stažení: LED_005.c == LED_005.pdf == LED_005.htm
.
.

Untitled
/*
V minulém programu jsme si ukázali, jak používat prom?nnou, jak vytvá?et cykly s
ur?itým po?tem opakování (for) a jak používat podmínku (if).
Umíme už tedy rosv?cet a zhasínat ledky v námi zvoleném po?adí.
*/

/*
Naše dosavadní programy mají ale jeden velký nedostatek. Pokud jsme cht?li n?co 
zm?nit (délku hada, rychlost), museli jsme v programu upravit pot?ebné konstanty,
program zkompilovat a znovu nahrát do mikrokontroléru. Hodilo by se nám proto, aby 
bylo možné tyto konstanty m?nit p?ímo za b?hu programu bez nutnosti jej upravovat 
a znovu nahrávat.
Pot?ebujeme tedy, aby program n?jakým zp?sobem zjistil, že jsme se rozhodli n?kterou
konstantu zm?nit, a zm?nil jí sám.
K tomuto ú?elu m?žeme použít tla?ítka. Jakmile program zjistí, že jsme stiskli 
tla?ítko, zm?ní konstantu, a pokra?uje dál.
Nyní tedy pot?ebujeme v programu n?jakým zp?sobem zjistit, že je stisknuté tla?ítko.
*/

/*
Náš p?ípravek ATmega8_LED_start_2 má 3 tla?ítka. Jedno je použito jako reset (resetuje
mikrokontrolér) a dv? jsou volná pro všeobecné použití. Tato dv? tla?ítka jsou 
p?ipojena k pin?m PD2 a PD3. 
Zkusíme pomocí jednoho tla?ítka (t?eba PD2) prodlužovat hada z minulého p?íkladu
Budeme tedy pot?ebovat nastavit port PD2 jako VSTUP a n?jakým zp?sobem pak zjistit, 
jaká je jeho hodnota. Nastavení PD2 jako vstup, by se provedlo pomocí registru DDRD
(registr DDR portu D) tak, že by se na p?íslušné místo (2. bit) zapsala "0". Protože 
však po resetu mikrokontroléru jsou všechny I/O porty nastaveny na "0" - tedy vstup,
nemusíme nic nastavovat.
Otázkou tedy pouze je, jak z portu ?íst. K tomuto ú?elu jsou v mikrokontroléru 
registry PIN. Registr PIN se podobn? jako registry PORT a DDR ozna?uje písmenem portu
(PINA, PINB, PINC...). Protože tla?ítko je p?ipojeno k portu "D", budeme pot?ebovat 
PIND. PIND je stejn? jako ostatní registry osmibitový (obsahuje 8 jedni?ek a nul).
B?hem chodu programu se do tohoto registru automaticky ukládá hodnota všech noži?ek
daného portu.
Pokud je na noži?ce nap?tí 0 - 0,8 V, objeví se v registru PIN na p?íslušném míst? "0".
Pokud však je k noži?ce p?ipojeno nap?tí mezi 2 a 5 V, je p?íslušný bit registru PIN
nastaven na "1".
Tla?ítka jsou na našem "ATmega8_LED_start_2" zapojeny tak, že pokud není tla?ítko 
stisknuto, je na p?íslušnou noži?ku mikrokontroléru p?ivedeno 5 V.Pokud je tla?ítko 
stisknuto, je na noži?ce 0 V.
Když tedy chceme zjistit, zda je stisknuto tla?ítko PD2, musíme se podívat do registru
PIND, zda je t?etí bit vynulován (3 bit proto, že se noži?ky i bity po?ítají od "0"
- 0, 1, 2, (t?etí pozice)).
Abychom zjistili stav jednoho bitu z celého registru, musíme si jej takzvan? 
"vymaskovat". Vymaskovat znamená, že provedeme n?jakou po?etní operaci, která nám 
odstraní ostatní (nepot?ebné) bity. Z?stane nám tak osmibitové ?íslo, kde budou 
všechny bity "0" jen náš požadovaný bit z?stane nezm?n?n ("0" nebo "1"). Nyní m?žeme 
zjistit, zda je tento registr v?tší než "0" (bit byl "1"), nebo ne (bit byl "0").
Vymaskování se dá provést pomocí logického sou?inu (&). Logický sou?in porovná dv? 
prom?nné tak, že postupn? porovnává bity které leží na stejných místech a do výsledku
zapisuje "1" pouze tehdy, pokud byly jedni?ky na tomto míst? v obou prom?nných.
Nap?íklad:

prom?nná1:	10001101 	(dekadicky: 141)
prom?nná2:  01101011	(dekadicky: 107)
Výsledek:	00001001	(dekadicky:   9)	

Když tedy chceme zjistit jestli je nastaven t?etí bit, provedeme to takto:

promenna:	00110101	(dekadicky: 53)
maska:		00000100	(dekadicky:  4)
vysledek:	00000100	(dekadicky:  4 - je v?tší než "0" - bit byl "1")

Zápis je následující:

vysledek = promenna & maska

nebo:

vysledek = maska & promenna

Nyní tedy umíme zjistit stav nap?tí na noži?kách mikrokontroléru (registr PIN) a
vymaskovat si pot?ebnou noži?ku (bitový sou?in - &). M?žeme se tedy pustit do psaní 
programu:
*/

#define F_CPU 1000000UL  // 1 MHz (základní frekvence) kv?li delay.h

#include <avr/io.h>		//Knihovna vstup? a výstup? (PORT, DDR, PIN)
#include <util/delay.h>	//Knihovna ?ekacích funkcí

#define RYCHLOST   5	//Po?et krok? hada za sekundu

#define DELKA_MIN   1	//Po?áte?ní délka hada (po?et ledek)
#define DELKA_MAX   10	//Kone?ná délka hada (kam až se m?že prodloužit)


int main (void)
{
unsigned char delka;	//nadefinujeme si prom?nnou pro délku hada (bude se m?nit)
delka=DELKA_MIN;		//nastavíme délku hada na minimální hodnotu

DDRB = 0xff;			//všechny piny na portu  "B" budou výstupní
//DDRD = 0 nastavovat nemusíme - je nastaveno implicitn? po resetu


for(;;)
	{	//hlavní smy?ka

	for(unsigned char n=0;n<(8+delka);n++)	//Nadefinováním prom?nné "n" p?ímo v
											//cyklu zajistíme, že mimo cyklus tato
											//prom?nná neexistuje a tudíž nezabírá
											//místo v pam?ti.
		{
		if (n<delka)	//pokud jsme rozsvítili mén? ledek než je délka hada
			{
			PORTB <<=1;	//p?idáme ?lánek hada (bity se posunou doleva a 
						//vpravo se doplní "0"
			
			PORTB ++;	//p?i?teme "1" (nastavíme nultý bit na "1")
			}			
		else			//pokud není po?et opakování menší než délka hada
			{			//to znamená, že hada už jsme nakreslili..
			
			PORTB <<=1;	//pouze posuneme bity (hada) doleva a doplní se nula...
			}
						
		_delay_ms (1000/RYCHLOST);	//?ekání (1000 ms = 1 sekunda) 
		
		//V tuto chmíli prob?hlo vykreslení jednoho kroku hada a prob?hlo ?ekání.
		//Než ale program necháme sko?it na za?átek, a nakreslit další krok hada
		//zkusíme se podívat, jestli n?kdo zrovna te? nema?ká tla?ítko:
		if (PIND&0b00000100)	//pokud je 3. bit nastaven na "1" 
			{					//(tla?ítko není stisknuté)		
			;		//nic ned?lej a jdi dál (; = prázdný p?íkaz)
			}
		else		//pokud není 3. bit nastaven na "1" (n?kdo drží tla?ítko)
			{
			delka++; //prodloužíme hada o 1
					
					//Te? by se ale mohlo stát, že jsme už hada prodloužili p?íliž.
					//Musíme tedy zjistit, jestli už had není delší než DELKA_MAX
			if(delka>DELKA_MAX) 	//Pokud je tedy délka v?tší než maximum, které 
				{				//jsme si na za?átku programu nastavili...
				delka=DELKA_MIN;	//...zkrátíme hada na minimum a m?žeme zase 
				}					//prodlužovat.
			}
		}	//...a znovu na za?átek smy?ky


	}	//hlavní smy?ka...
} //konec funkce main


/*
Tento program by m?l po nahrání do mikrokontroléru vytvo?it "sv?telného hada", 
o délce definované konstantou DELKA_MIN. Had se bude pohybovat rychlostí udanou 
konstantou RYCHLOST. Po stisku tla?ítka se had p?íští kolo objeví o jeden ?lánek 
delší.
*/

//Pro radioklub OK1KVK naspal Vašek Král