ATtiny2313 C/T1: blikání LED na vývodu PB2 v intervalu 0,5s

Zdravím. Jsem naprostý začátečník v programování a dostal jsem za úkol:
Napište program pro blikání LED na vývodu PB2 v intervalu 0,5 s pomocí C/T1. Použijte režim Output Compare.

Zde přidávám svůj program:

#define F_CPU 20000UL //20 kHz - základní frekvence
#include <avr/io.h> //vlož knihovnu vstupů a výstupů (PORT, DDR)
#include <util/delay.h> //vlož knihovnu čekacích funkcí (_delay_ms() )
#define CEKANI 500 //nadefinuj konstantu “CEKANI” s hodnotou (500 milisekund)
#define LED 0b00000100 //nadefinuj ledky, které mají blikat (D3 na PB2)

int main (void) //hlavní funkce
{
DDRB = 0xff; //(0xff = 0b11111111) -> Piny 0 - 7 portu B jako výstupní

while (1)				//nekonečná smyčka (1 => pořád)
{						//začátek cyklu "while (1)"
	PORTB = LED; 		//rozsviť vybrané ledky
	_delay_ms (CEKANI);	//čekej tolik milisekund, kolik je v konstantě CEKANI
	PORTB = 0;			//zhasni všechny ledky
	_delay_ms (CEKANI);	//čekej tolik milisekund, kolik je v konstantě CEKANI
}						//konec cyklu "while (1)" - program skočí zpět na jeho začátek

}

Mám dvě otázky.

  1. Je tento program napsaný správně?
  2. Proč mi i přez příkaz #define F_CPU 20000UL beží program na frekvenci 1kHz?

Předem děkuji za odpověď a případnou pomoc :wink:

:arrow_right: administrator: přejmenováno z "ATtiny2313"

Přidávám screen.

Zdravím. V první řadě program nemáš dobře, teda je ‘‘funkční’’ ale ne dle zadání.
Co se mi ještě nezdá je to, že máš použít timer 1 a dioda má být na PB2. Dle mého úsudku by mělo být zadání - použít timer 1 a blikat by to mělo na PB3 nebo použít timer 0 a blikaní na PB2. Zkus to prověřit.

Frekvence procesoru se nastavuje pomocí fuse bitů a #define F_CPU 20000UL pouze říká funkci delay jakou máš nastavenou frekvenci procesoru. I kdyby jsi nastavil předděličku, v programu to nemáš, 20kHz z toho nedostaneš, takže s největší pravděpodobností ti to frčí na 4MHz nebo na 8MHz.

Program by vypadal nějak tak(bez záruky)

#include <avr/io.h>	 //vlož knihovnu vstupů a výstupů (PORT, DDR)
#define F_CPU 4000000UL //4MHz - základní frekvence  




int main (void) //hlavní funkce 
{ 
CLKPR=0x80;
CLKPR=0x00;

DDRB = 0x08; //(0xff = 0b00001000) -> Piny 0 - 7 portu B jako výstupní 

//nastavení timeru 1
TCCR1A=0x40;  
TCCR1B=0x0D; 

OCR1AH=0x07;
OCR1AL=0xA1;


while (1)	 //nekonečná smyčka (1 => pořád) 
{	 //začátek cyklu "while (1)" 

//všechno dělá timer 1, takže zde nic mít nemusíš.


}	 //konec cyklu "while (1)" - program skočí zpět na jeho začátek 
} 

podla screenshotu usudzujem, ze to zatial len simulujes. Frekvencia, ktoru nastavujes v programe (#define F_CPU 20000UL) je len pre preklad programu, ako pisal Zalda. Ak to chces na tejto frekvencii aj simulovat, tak to musis simulatoru nastavit. Tak isto ked to budes napalovat do MCU, musis mu zvolit spravnu frekvenciu. MCU sa nevie nastavit na frekvenciu, ktoru si mu napisal v kode. BTW tu frekvenciu mas ozaj divnu, nastav mu aspon 1MHz. to je taka beznejsia frekvencia.

Zdravím. V první řadě děkuji všem, kteří se vyjádřili k mému problému. Zadruhé opravdu jsem vám poslal špatné zadání. V zadání je použijte C/T0 pro PB2 (D3). Dále jsem zjistil, že nechci aby program pracoval na frekvenci 20kHz ale 20MHz viz.: atmel.com/devices/attiny2313.aspx (Max. Operating Frequency: 20 MHz). A měl bych ješte jednu otázku a to co dělají příkazy a jak jsi došel k těm hodnotám:
CLKPR=0x80;
CLKPR=0x00;

a

TCCR1A=0x40;
TCCR1B=0x0D;

OCR1AH=0x07;
OCR1AL=0xA1;

Předem děkuji za odpověď a přejí hezký zbytek dne.

P.S.: Mohl by mi někdo doporučit literaturu, která řeší tuto problematiku? Nemyslím tím příklady, ale spíše vysvětlení.

Ak chces pracovat na 20MHz sa si to definujes na zaciatku

#define F_CPU 20000000

Ak chces pracovat s C/T0 v rezimu OUTPUT COMPARE najprv si pozri v datasheete aky je to rezim aby si pochopil ako pracuje a nasledne aby si vedel co vsetko musis nastavit.

Potom si v datasheete od 2313 najdi registre

TCCR0A
TCCR0B
OCR0A

Tam si nastavis T0 do rezimu OUTPUT COMPARE, Predelicku… Su to 8bitove registre kde si “zapnes” prislusne bity. V datasheete mas vsetko presne vysvetlene co znamena kazdy jeden bit.

Napr:
TCCR0A = 0x40 je to iste ako 0b01000000 cize som zapol 7mi bit takze T0 bude pracovat v rezimu OUTPUT COMPARE, vystup bude na PB2(OC0A).

TCCR0B si nastavujes okrem ineho predelicku T0

OCR0A si nastavujes pri akej hodnote dosiahne T0 TOP vynuluje sa a zacne znovu ratat.

Tusim ak chces aby led blikala budes musiet pouzit prerusenie ktore v tvojom pripade by malo nastat kazdych 0,5s…

datasheet:
atmel.com/Images/doc2543.pdf

Diky alongo. Posledni dva tydny jsem si pravielne zkousel tento program. Ale i prez to jsem se nedopracoval k funkcnimu vysledku. :frowning:

Muj program:

#include <avr/io.h> //vlozi knihovnu vstupu a vystupu
#define F_CPU 20000000UL //nastaví freknvenci procesoru mc na 20MHz

ISR (TIMER0_COMPA_vect)
{
DDRB=0x00;
}

int main(void)
{
//nastaveni oscilatoru:
//(doba vykonavani jedne instrukce trva jednu periodu oscilatoru)
CLKPR=0x80; //povoli zmenu frekvence delicky oscilatoru
CLKPR=0x00; //urcuje frekvenci delicky oscilatoru

DDRB=0x20;					//0x20=0b00100000=>D3 na pinu 3 (PB2) portu B sviti

//nastavení T0:
TCCR0A=0x82;				//0x40=0b10000010;T0 v rezimu OUTPUT COMPARE na vystupech OC0A (tedy i PB2)
TCCR0B=0x0D;				//preddelicka T0

/*tento registr je porovnavan s T0,T0 se pri dosazeni stejne hodnoty s OCR0A
 vynuluje a pocita znovu (=>registr OCR0A urcuje max. hodnotu T0)*/
OCR0A=0xA1;					//nastaví max. hodnotu T0,poté počítá znovu od nuly

}

Zkousel jsem si prekladat ten DATA (ŠÍT) a zcela nechapu funkci jednotlivych bitu. Budu vdecny za jakoukoli pomoc. V připadě, že by někdo poslal jiz prepracovany program, byl bych rad kdyby k tomu napsal i vysvetleni proc to udelat tak a nebo onak. Nejde mi totiz o to, abych tu neco opsal, ale snazim se opravdu pochopit fuknce AVR Studia. Predem dekuji.

Sežeň si knihu “Práce s mikrokontroléry ATMEL AVR” od Davida Matouška.
Vydalo jej nakladatelství BEN.
Je to v češtině a hodně ti může pomoci do začátků…

Divous moc dekuji za tu knihu. Naucil jsem se diky ni spoustu novych veci. Ale program stale nepracuje, tak jak bych chtel. Jde o to ze dioda blika ale v intervalu 13,1072 (nebo 131,072) nejsem si jist spravnym vypoctem :smiley: :wink:

ZDE JE PROGRAM:

#include <avr/io.h> //vloz knihovnu vstupů a výstupů (PIN,DDR,PORT)
#define F_CPU 20000000UL //f==20MHz

int main (void)
{
CLKPR=0x80;
CLKPR=0x00;

DDRB=0x04;				//(0x04==0b00000100) => nastaven vystup PB2 (OC0A) pro D3
PORTB=0x04;				//dioda sviti


/*tento registr je porovnavan s T0, T0 se pri dosazeni stejne hodnoty 
s OCR0A vynuluje a pocita znovu (=>OCR0A urcuje maximalni hodnotu T0)*/
OCR0A=0xff;


//nastavení timeru 0:

TCCR0A=0x42;			//(0x42==0b01000010); toggle + T0 v režimu OUTPUT COMPARE,CTC//
TCCR0B=0x05;			//preddelicka T0;f/1024=>50us


while (1)				//nekonecna smycka
{
//pokud je v registru TIFR bit 0==0,tak registr TCNT0 zatim nepretekl:					
if((TIFR & 0x01)==0)	//0x01==0b00000001
	{
	;					//prazdny prikaz (nic nedela)
	}
//pokud je v registru TIFR bit 0==1,tak registr TCNT0 jiz pretekl:
else
	{
	PORTB=~PORTB;		//negace portu B
	TIFR=TIFR | 0x01;	//0x01==0b00000001 ; nuluje registr TIFR (zapsanim "1") => TIFR==0b00000000 
	}						
}

}

Byl bych velice vdecny za radu kde a co musim zmenit, aby dioda blikala 0,5s. f=20 000 000 Hz, T0 preddelicka=1024. Da se treba udelat jeste nejaka jina preddelicka? Myslel jsem ze treba ta CLKPR, ale nejak to nefaka. Predem dekuji.

sksu postufdovst toto svetelektro.com/clanky/programuj … t-453.html

Nezůstal procesor nastavený na interní RC oscilátor?

Zdravim. Tak jsem se konecne dopracoval k nejakemu vysledku. V symulatoru mi to funguje, ale kdyz svuj program nactu do MC, tak to nefunguje :frowning: Nevite nekdo kde nebo co je CHYBA?

PROGRAM:

#include <avr/io.h> //vloz knihovnu vstupů a výstupů (PIN,DDR,PORT)
#define F_CPU 20000000UL //f==20MHz

volatile unsigned char i;

int main (void)
{
DDRB=0x04; //(0x04==0b00000100) => nastaven vystup PB2 (OC0A) pro D3
PORTB=0x00; //dioda sviti

/*tento registr je porovnavan s T0, T0 se pri dosazeni stejne hodnoty
s OCR0A vynuluje a pocita znovu (=>OCR0A urcuje maximalni hodnotu T0)*/
OCR0A=0xFF;


//nastavení timeru 0:

TCCR0A=0x42;	 //(0x42==0b01000010); T0 v režimu OUTPUT COMPARE CTC//
TCCR0B=0x05;	 //preddelicka T0 ; 20 000 000/1024=>51,2 us ; 256*51,2us=13,1072 ms ;


while (1)	 //nekonecna smycka

{
	//pokud je v registru TIFR bit 0==0, tak registr TCNT0 zatim nepretekl:
	if((TIFR & 0x01)==0)	//0x01==0b00000001
	{
		;	 //prazdny prikaz (nic nedela)
	}
	//pokud je v registru TIFR bit 0==1, tak registr TCNT0 jiz pretekl:
	else
	{
		if (i==38 )				//500/13,1072=38
		{
			PORTB=~PORTB;	//dioda nesviti
			TIFR=0x01;		//0x01==0b00000001 ; nuluje registr TIFR (zapsanim "1") => TIFR==0b00000000
			i=0;				
		} 
		else
		{
			i++;
			TIFR=0x01;		//0x01==0b00000001 ; nuluje registr TIFR (zapsanim "1") => TIFR==0b00000000	
		}
	}
}

}

Program by mel fungovat takto:
1.Nastavi branu jako vystupni + rozsviti diodu
2.Nastavi porovnavaci registr OCR0A
3.Nastavi T0 do patricneho rezimu + nastavi jeho preddelicku
4.Smycka
-obsahuje dve podminky
a) Je nastaven registr TIFR? Nastavi se vzdy po preteceni T0 a to nastane tehdy, kdyz registr TCNT0 ma stejnou hodnotu jako porovnavaci registr OCR0A
b) Kolikrat probehlo preruseni? Pokud probehlo 38x, tak se PORTB zneguje tj. zmeni logickou hodnotu (bud 0 nebo 1). Pokud neprobehlo 38x, tak pripocte +1 do i a vrati se zpet na zacatek smycky.

Predem vsem dekuji za odpovedi a doufam, ze mi tento muj maly problem pomuzete vyresit. Preji hezky zbytek dne, HypnoZzz.

P.S: if (i==38 ) tu mezeru za cislem 38 jsem udelal jen z duvodu, ze kdyz bych to poslal sem na forum udelalo by to smajlika. VIZ 8)

“nefunguje” znamená, že nesvítí LED? Chtělo by to ladit po částech:

  1. krátkým uzemněním pinu ověřit, že LED opravdu svítí
  2. na začátku main nastavit výstup jen aby rozsvítil LED a stop programu, ať se ověří že se ovládá správný pin
  3. softwarově blikat s LED s využitím _delay_ms, tím se ověří že program jede a že odpovídá nastavená rychlost CPU (kdyby byly špatně nastavené pojistky, zvolený špatný oscilátor)
  4. blikat nejdříve s nejjednodušším módem čítače, bez porovnání, jen prostým přetečením

Přehlédl jsem nebo tam není inicializovaný čítač i ?

Uz by ste sa k podobnym veciam bez schemi ani nemali vyjadrovat… tak ze ju tu daj a potom budeme spekulovat.

Omlouvam se, za to ze jsem hned neposlal schema, ale myslel jsem, ze vsechny MC funguji na stejnem principu… Pridavam screen.


Ja myslim, ze to do toho 30.11 uz stejne nestihnes dodelat…

Mam posunuty termin :wink:

Ten reset nemusi byt niekde pripojeny a osetreny ?, nevidim kondik 100n+10uF na vyvodoch napajania.

To Atlan: Čteš vůbec odpovědi na vlastní příspěvky ?

Tady jsem Ti psal, jak to s resetem u AVRka je. Nebo jsem to jenom špatně pochopil a chtěl jsi naznačit to, co jsem ve své odpovědi napsal ?

Abys to nemusel hledat, tak cituji :

U AVR nemusí být RESET pin ošetřen, nicméně nikdo nic nezkazí tím, že externí rezistor přidá.

Prosim zpet k tematu… Nevite nekdo proc mi to nefunguje? Ja tam nemuzu najit zadnou chybu a sem z toho celej spatnej… Uvitam kazdou radu/napad co mate, protoze termin mam sice posunuty ale jen o tyden, tj. do zitrka :frowning: A uz sem zkousel snad vse!