Gustav |
Nové stránky BETA
Hlavní nabídka
Technika & Bastlení
Média
Reklama Google

AVR - LED panel - #7 Program PDF Tisk Email
Koutek AVR -
Napsal uživatel Michal, OK1WMR   
Úterý, 04 Říjen 2011 07:09

Kompatibilní zapojení: LED panel s ATmega8

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



Untitled
/*
Nyní již umíme používat p?íkazy k v?tvení programu (podmínky) "if" a "switch". Umíme
také rozložit program na jednoduché funkce a používat cyklus "for". Co se tý?e cykl?,
zbývá nám ješt? vysv?tlit cyklus "while" a "do-while" a p?íkazy "break" a "continue".
*/
/*
Cyklus "while" je velmi podobný cyklu "for". Rozdíl mezi cyklem "for" a "while" je
ten, že cyklus "for" má p?edem daný po?et opakování, cyklus "while" jej p?edem daný
mít nemusí. Funguje to tak, že cyklus "while" má ve své hlavi?ce zadanou podmínku,
která se p?i každém pr?chodu cyklem testuje. Jakmile tedy program narazí na cyklus
"while", otestuje jestli platí podmínka (podobn? jako u "if") a pokud platí, vykoná
p?íkazy ve svém t?le. Poté se program p?esune zp?t na za?átek, a znovu otestuje
podmínku. Pokud je podmínka vyhodnocena jako neplatná, p?íkazy v t?le cyklu se
nevykonají. Rozdíl mezi "for" a "while" tedy spo?ívá v tom, že pokud bude podmínka
vyhodnocena jako neplatná hned napoprvé, p?íkazy v t?le cyklu se neprovedou v?bec.
Zápis je následující:

while (podmínka)
	{
	p?íkazy;
	}
*/
/*
Cyklus "do-while" se od cyklu "while" liší tím, že p?íkazy v t?le cyklu "do-while"
se minimáln? jednou provedou.
Zápis je následující:

do  {
	p?íkazy;
	} while (podmínka);

Podmínka je u tohoto cyklu zapsána až na konci, a program tedy p?ed jejím otestováním
musí vykonat p?íkazy v t?le cyklu. Na konci cyklu narazí na podmínku, kterou otestuje.
Pokud je podmínka platná, cyklus se opakuje (od za?átku), pokud ne, je cyklus ukon?en,
a program pokra?uje za cyklem.
*/
/*
S p?íkazem "break" jsme se setkali již u podmín?ného p?íkazu "switch". Podobn? jako u
p?íkazu "switch", se i u cykl? dá použít p?íkaz "break" k jejich okamžitému ukon?ení.
P?íkaz break se v?tšinou zadává jako jedna v?tev podmínky ("if" nebo "switch").
Zápis:

while (1)
	{
	p?íkazy;
	if (podmínka)
		break;
	}

V tomto p?ípad? p?íkaz break slouží k "vysko?ení" z nekone?né smy?ky. P?íkazy v t?le
smy?ky se tedy budou vykonávat do té doby, dokud nebude platná podmínka
"if".
Ve výše uvedeném p?íkladu si lze také povšimnout, že p?íkaz "break" není zapsán
ve složených závorkách, jak by se v t?le p?íkazu "if" dalo o?ekávat.
Pokud totiž do t?la n?jaké podmínky nebo cyklu zapisuje pouze jeden p?íkaz,
není nutné jej psát do složených závorek {}. Pokud bychom do t?la n?jaké podmínky
nebo smy?ky zapsali více p?íkaz? bez složených závorek, bral by se jako t?lo pouze
první p?íkaz. Ostatní by se vykonaly až za tímto cyklem nebo podmínkou.
Nap?íklad:

if (n<5)
    n++;
    b=n;

je totéž co:

if (n<5)
    {
    n++;
    }
b=n;

*/
/*
P?íkaz "continue" zp?sobí skok na za?átek smy?ky. Neukon?í tedy smy?ku jako "break",
ale pouze vynechá všechny p?íkazy, které po n?m následují až do konce t?la smy?ky.
Cyklus pak pokra?uje zase od za?átku, jako by se nic ned?lo.
Zápis:

while (1)
	{
	p?íkazy;
	if (podmínka)
		continue;
	p?íkazy;		//tyto p?íkazy budou vynechány, pokud bude platit podmínka
	}

*/
/*
Dote? jsme se zabývali, jak na našem p?ípravku "ATmega8_LED_start_2" rozsv?covat
a zhasínat ledky. Co když ale budeme chtít ?ídit jejich jas?
Jas ledky je možné ?ídit tak, že ji rozsv?cujeme a zhasínáme tak rychle, že to
lidské oko nepost?ehne. Když potom budeme r?zn? m?nit periodu sv?tla a tmy, bude
se zdát, že ledka svítí více ?i mén? jasn?. Tato metoda se ozna?uje PWM a je to
vlastn? jeden ze zp?sob?, jak p?evést digitální signál (nuly a jedni?ky) na
analogový (jas žárovky, výkon motoru, aj.).
*/
/*
M?žeme si tedy vyzkoušet, jak bude regulace jasu fungovat u našeho starého známého 
hada. Program had bude podobný jako v minulých programech, pouze místo p?íkaz?:
PORTB=...;
_delay_ms(...);

zam?níme za funkci:
rozsvit(...).

Funkce "rozsvit()" bude zajiš?ovat rychlé blikání ledek (viz výše). Délku periody 
sv?tla v??i period? tmy, bude tato funkce p?ebírat z prom?nné "jas".
*/
/*
Program by mohl vypadat t?eba takto:
*/
#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í
#include <avr/interrupt.h> //Knihovna p?erušení (kv?li vektoru ISR(TIMER0_OVF_vect))


#define VZOR   	0b00000111	//tato konstanta ur?uje délku hada

#define	DOBA	50			//tato konstanta ovliv?uje rychlost hada 
							//(?as na jeden krok v ms)


volatile unsigned char jas=64;	 /*tato prom?nná je globální, protože se nastavuje v 
p?erušení (?tení tla?ítek) a zárove? ji pot?ebujeme ?íst ve funkci "rozsvit". 
V této prom?nné bude uloženo ?íslo (0-128), které bude ur?ovat jas ledek.*/


/********************************************/
/*		****************************		*/
/*		*     Deklarace funkcí     *		*/
/*		****************************		*/ 
/********************************************/
/*
Deklarace funkce je vlastn? hlavi?ka funkce, se st?edníkem. Hlavi?ka se píše tak jak
je uvedena v definici. Pomocí deklarace funkce, dáváme p?eklada?i najevo, že daná 
funkce existuje. Od tohoto místa dále tedy m?žeme funkci volat, i když je ve 
skute?nosti nadefinovaná až na konci programu.
*/
void rozsvit(unsigned char co, unsigned char jakdlouho);
/*
Nadeklarujeme si funkci, která za?ídí regulaci jasu ledek, jak bylo popsáno výše. 
Tato funkce bude p?ebírat parametry: 
"co" = ledky které budou svítit, 
"jakdlouho" = jak dlouho budou svítit [ms]  
Dále tuto funkci ovliv?uje globální prom?nná "jas", která udává jas
ledek v procentech (0 - 128) */



/********************************************/
/*		****************************		*/
/*		*       Hlavní funkce      *		*/
/*		****************************		*/ 
/********************************************/



int main (void)
{
unsigned char had=0;	//nadefinujeme si prom?nnou, ve které bude uložen had



DDRB = 0xff;		//všechny piny na portu  "B" budou výstupní

/*Nyní si nastavíme p?erušení od ?asova?e "0" - bude ?asovat ?tení klávesnice*/
TIMSK|= 1; 		//nastavíme nultý bit na "1"  (vybereme p?erušení od ?asova?e "0")
SREG |=(1<<7); 	//"globální" povolení p?erušení (nastavíme 7. bit registru SREG)
TCCR0 = 5;		//Zapneme ?asova? "0" s p?edd?li?kou 1024.



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

	had<<=1;	//posuneme hada
	if (had<VZOR)	//pokud jsme rozsvítili mén? ledek než je délka hada
		had++;		//rozsvítíme poslední ledku

	rozsvit(had, DOBA);//zavoláme funkci "rozsvit" a ?ekneme jí které ledky má rozsvítit

	}	//konec hlavní smy?ky
} //konec funkce main





/********************************************/
/*		****************************		*/
/*		*      Definice funkcí     *		*/
/*		****************************		*/ 
/********************************************/

/*****************************/
/*          Rozsvit          */
/*****************************/ 
void rozsvit(unsigned char co, unsigned char jakdlouho)
	{

	for(unsigned char i=0; i<jakdlouho; i++) //jeden cyklus trvá cca 1 ms
		{
		for (unsigned char j=1;j<=128;j++)
			{
			if(jas>=j)	//pokud je v prom?nné "j" menší ?íslo než v prom?nné "jas" 
				PORTB=co;	//Rozsvítíme požadované ledky
			else		//jinak
				PORTB = 0;	//zhasneme všechny ledky
			_delay_us(7);	//po?káme 7 us
			}

		}
		/*
		Je snahou, aby tato smy?ka obsahovala co nejmén? p?íkaz?, protože vykonání
		každého p?íkazu zabere procesoru n?jaký ?as. 
		Jeden cyklus tedy netrvá pouze 128  * 7 us = 896 us, nýbrž o n?co déle.
		*/
	}

/*****************************/
/*       ?tení tla?ítek      */
/*****************************/
ISR(TIMER0_OVF_vect)
	{
	TCNT0=157;	//?asova? za?ne po?ítat od 157 (255-157=98) p?edd?li?ka je 1024.
				//Hodinový kmito?et procesoru je 1MHz. Takže: 
				//1 000 000 / 1024 / 98 = 10 Hz (klávesnice se kontroluje p?ibližn?
				//10x za vte?inu, neboli jednou za cca 100 ms)
	
	if (!(PIND&0b00000100)) 	//pokud je stisknuté tla?ítko 1 (jas+)
		{
		if (jas==0) //pokud je jas "0"
			jas=1;	
		else		//pokud jas není "0"
			{
			if(jas<128)	//pokud je menší než 128 (maximální jas)
				jas<<=1;	//zvýšíme jas na dvojnásobek (bitový posun doleva)
				/* 
				Prom?nná "jas" tedy m?že nabývat hodnot: 
				0, 1, 2, 4, 8, 16, 32, 64 a 128
				*/
			}

		TCNT0=60;	//?asova? za?ne po?ítat od 60 místo 157 (po?ítá do 255), takže 
		}
		
	if (!(PIND&0b00001000))	//pokud je stisknuté tla?ítko 2 (jas-)
		{
		jas>>=1;		//snížíme jas na polovinu (bitový posun doprava)

		TCNT0=60;	//?asova? za?ne po?ítat od 60 místo 157 (po?ítá do 255), takže 
					//p?íští ?tení tla?ítka bude za cca 200 ms místo p?vodních 100 ms.

		}

	}
	


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


 
Poslední aktualizace
 5 January 2016, 07:01 
Webkamera
Webkamera na Blatenském vrchu
Change language
Sociální sít?
Náhodné foto
Podporují nás