Rozsvěcení LED od prvního pinu k poslednímu a pak zhasínání

Ahoj, chtěla bych se zeptat, jestli by mi někdo nepomohl. Chtěla bych, aby se LED diody postupně rozsvicovali od prvního pinu portu do posledního a pak se zase postupně od posledního pinu zhasínali, nějak mi to nejde… Předem děkuji :wink:

:arrow_right: administrator: přejmenováno z "blikání LED"

[code]
main()
{
int i = 0;
DDRD = 0xff;
while(1)
{
for (; i < 7; i++)
{
PORTD = (0xff << i);
_delay_ms(200);
}

for (; i > 0; i–)
{
PORTD = (0xff << i);
_delay_ms(200);
}
}
}[/code]

děkuji :slight_smile:, teď na to koukám a já jsem sem nedala ten můj kód :slight_smile:
nevíte, co jsem tady udělala špatně?
DDRB = 0xff;

while(1)
{
PORTB = 0b11111111;
for(unsigned char n=0;n<8;n++)

	{
	if (n<16)
		{
		PORTB <<=1;	
		}			
	else						
		PORTB <<=0;
		
				
	_delay_ms (100);
	
	}	
}

}

A ještě bych měla takový technický dotaz, kolik mohu maximálně nastavit do delay_ms? když mám krystal 16MHz?

Takže pozpátku…

Max. delay při 16Mhz je zhruba 5,1s.

PORTB <<=1; je bitový posun o jenu posici vlevo
PORTB <<=0; je bitový posun o ŽÁDNOU posici vlevo.

Špatně máš na tom to, že to máš špatně. :slight_smile: Cyklus je jen do 8, takže v testu nebude nikdy n >= 16. Rotace <<= 0 neudělá nic. Tak třeba takhle by to mohlo jít:

[code]DDRB = 0xff;

while(1)
{
PORTB = 0b11111111;
for(unsigned char n=0;n<16;n++)
{
if (n<8)
{
PORTB <<=1;
}
else
{
PORTB >>=1;
PORTB |= 0x80;
}
_delay_ms (100);
}
}[/code]

ještě se zeptám, co tam přesně dělá ten bitový součet? nějak to nechápu :frowning:

A ještě jsem se zapomněla zeptat. Jak se vypočítává to maximální delay? já jsem našla, že se to vypočte jako 262/F_CPU , ale to nějak nevychází…

Myslíš tohle? “PORTB |= 0x80” To nastaví 7. bit portu B na “1”. Bitový posun “PORTB >>= 1” posune bity o 1 pozici dolů, do nejvyššího bitu nastaví “0”, proto je potřeba doplnit chybějící “1” tím |=.

Funkce “_delay_ms” používá smyčku _delay_loop_2 (v assembleru), jejíž 1 průchod trvá 4 strojové takty. Vstupním parametrem funkce je 16-bitový WORD. Maximální hodnota je 65536 (= hodnota 0), což je * 4 = 262144 taktů. U krystalu 16 MHz je doba jednoho taktu 1/16MHz = 0,0625 us. Maximální doba čekací smyčky _delay_ms je proto 0,0625 * 262144 = 16,384 ms. Což není moc a proto se používá ještě obcházka, že pro delší čas než těchto 16 ms se čeká v násobcích 10 ms (proto nad 16 ms se snižuje přesnost čekací smyčky), čítač je unsigned word, proto maximální doba _delay_ms je 6,5 sekundy (nezávisle na rychlosti MCU). … Uvedené platí pro win_avr_20100110, u starších verzí to bylo trochu jinak.

moc děkuji :slight_smile:

a kdybych chtěla, aby mi tam jezdila jen jedna LED dioda?

DDRB = 0xff; PORTB = 0xfe; while(1) { char n; for(n = 7; n > 0; n--) { PORTB <<= 1; PORTB |= 1; _delay_ms(100); } for(n = 7; n > 0; n--) { PORTB >>= 1; PORTB |= 0x80; _delay_ms(100); } }
Teda ono to není tak úplně správně, protože na krajních LED vznikají krátké falešné impulsy. V tomto případě to nevadí, ale kdyby to mělo být přesně, tak se musí dělat rotace v pomocné proměnné a tu pak dávat na výstup, např.:

DDRB = 0xff; unsigned char maska = 1; char n; while(1) { for(n = 7; n > 0; n--) { maska <<= 1; PORTB = ~maska; _delay_ms(100); } for(n = 7; n > 0; n--) { maska >>= 1; PORTB = ~maska; _delay_ms(100); } }nebo ještě lépe:

[code]DDRB = 0xff;
unsigned char maska = 1;
while(1)
{
do {
maska <<= 1;
PORTB = ~maska;
_delay_ms(100);
} while (maska != 0x80);

do {
	maska >>= 1;
	PORTB = ~maska;
	_delay_ms(100);
} while (maska != 1);

}[/code]