stiskem zapni stiskem vypni led

Ahoj, učím se pracovat s tlačítkem, chtěl jsem talčítkem zapnout ledku a druhým stiskem ledku vypnout. Ale program nepracuje tak jak jsem si představoval

[code]#define F_CPU 1000000

#include <avr/io.h>
#include <util/delay.h>

int main()
{

DDRD = 0b01111111;
PORTD |= (1 << PD7); // pull-up na PD7

    while(1)
    {   
      if((PIND & (1 << PD7)) == 0) // pokud se na PD7 oběví log 0 
       {            
        PORTD |= (1 << PD6);  // na PD6 přiveď log 1   
       } 
       _delay_ms(300);
      if((PIND & (1 << PD7)) == 0) // pokud se na PD7 oběví log 0 
       {
        PORTD &= ~(1 << PD6); // na PD6 přiveď log 0
       }
       _delay_ms(300);
    }  

return 0;
} [/code]

První věc je, že když se procesor zapne, tak se hned rozsvítí ledka, bez toho aniž bych tlačítko zmáčknul.
Druhá věc, myslel jsem, že stiském tlačítka se zároveň zapne ledka a já ho budu moc hned pustit, tím spožděním 300ms jsem chtěl vyřeší zákmity, a to že minimální doba do dalšího stisku bude 300ms. Ale tak to nefunguje já to tlačítko musím zmáčkout 300ms držet pak až reaguje ledka, zase na 300ms držet a pak ledka zhasne.

do toho programu koukám furt dokola a nechápu proč to musím 300ms držet.

(vím, že delay, není vhodný protože procesor pak nemůže dělat nic jiného, ale zatím neumím časovač)

Děkuju za vysvětlení

cau, ten delay dej do podminky kde testujes stav pinu az po nastaveni vystupu pro led
ten delay staci cca 20-50ms

pull-up mas dobre zaplej ? (s avr nedelal tak nevim)
na zacatku po nastaveni vystupu ho nastav do log 0 a pak jen ten vystup neguj (bude stacit jedna podminka),nebo pouzi nakej flag a pomoci toho nastavuj vystup,(staci jedna promena kterou pri stisku tl. prictes 1 pak budes testovat jen 0 bit a podle toho nastavis vystup)

Díky za rady. Tak nějak nechápu kam přesně mam ten delay dát, při kompilaci na mě řve terminál, že se mu to takhle a takhle nelíbí.

Delay klidně zkrať na těch 20-50 ms. Co se ovládání stiskem týká, tak si musíš uložit načtený stav tlačítka jako minulý a v příští smyčce porovnávat nově načtený stav s tím minulým. Pokud nejsou stavy shodné, víš, že nastala změna. A pokud nastala změna, tak podle nového stavu tlačítka změníš (nebo nezměníš) stav LEDky.

Snad jsem to napsal dostatečně srozumitelně.

Těch 300ms musíš držet tlačítko proto, že program tráví 99.999999999% času v delay smyčkách. Provedení zbytku trvá rádově jednotky us. Program nečeká na stisk klávesy. Program během pár us zkontroluje PIND a jde na 300ms makat na čekání a znova. Je tedy pravděpodobnější, že se trefíš do tý čekací smyčky, než do kontroly PIND. Kromě toho, pokud jsi stisknul tlačítko, máš LEDku zhasnutou a program zrovna skočil do čekací smyčky, které následuje po kontrole PIND na rozsvícení, tak může klidně čekat až 600ms na rozsvícení.

Prostě program má vypadat nějak takto :

1) načtení tlačítka 2) je nová hodnota stejná jako stará ? 3a) ano - nic 3b) ne - 4) je tlačítko stisknuto ? - 5a) ano - přepnout LEDku 5b) ne - nic 6) krátký delay 7) jdi na 1

Nebo počkej na uvolnění tlačítka

[code]
while(1)
{
if(bit_is_clear(PIND,7)) // pokud se na PD7 objeví log 0
{
PORTD |= (1 << PD6); // na PD6 přiveď log 1
_delay_ms(50);
do {} while (bit_is_clear(PIND,7)
}

      if(bit_is_clear(PIND,7))  // pokud se na PD7 objeví log 0 
       {            
           PORTD &= ~(1 << PD6);  // na PD6 přiveď log 0    
           _delay_ms(50);
           do {} while (bit_is_clear(PIND,7)
       }
   }  [/code]

To AB: Jenže má 50% šanci, že příštím stiskem tlačítka “bude chtít” (=trefí se) rozsvítit rozsvícenou LEDku nebo zhasnou zhasnutou.

Máš pravdu. Toto snad bude lepší.

while(1) { if(bit_is_clear(PIND,7)) // pokud se na PD7 objeví log 0 { PORTD ^= (1 << PD6); // invertuj PD6 _delay_ms(50); do {} while (bit_is_clear(PIND,7) _delay_ms(50); } }

Tohle je samozřejmě lepší, nicméně pokud by procesor dělal ještě něco jiného, než přepínal LEDku, tak na dobu držení tlačítka de-facto zamrzne, protože bude čekat na jeho uvolnění. Proto si myslím, že je lepší načíst tlačítko, porovnat s minulým stavem a pokud bylo zrovna stisknuto, tj. pokud je teď stisknuto a minule nebylo, změnit stav LEDky. LEDka bude reagovat jen na stisk a procesor může pracovat i na jiných věcech. Z toho důvodu by tam delay buď neměl být vůbec a tlačítko kontrolovat periodicky (podle časovače nebo nějakého příznaku - těch možností je spousta).

Děkuju moc za příspěvky a rady.

Balů ten postup se mi líbí, je to lepší než napsat kus kódu, protože bych v tom stejně nic moc neviděl, hledám po gůglu, ale sám bohužel nevím co mám najít.

Budu si muset objednat knížku, C# se zaměřením na AVR, koukal jsem na knížku Programování v jazyce C kterou napsal Vladimír Váňa, ale píše se tam že je to se zaměřením na prostředí CodeVisionAVR C, tak nevím jestli to bude vhodná volba.
Ještě něco pohledám

Zatím, díky.

Hlavně nezapomeň na to, že je úplně jedno, jestli programuješ v C, v assembleru nebo v čemkoliv jiným. Vždycky musíš vědět, co od procesoru chceš a jak toho lze dosahnout. Když chci na pin5 dát log. 1, tak musím vědět, že na pinu 5 je brána B, bit 4, tudíž musím bránu B pin 4 nastavit jako výstup a zapsat tam log. 1. Programovací jazyk je jenom způsob, jak to napsat. Osobně si myslím, že začínat s Cčkem není úplně nejšťastnější nápad, protože Tě vzdaluje od HW. Navíc všechny instrukce procesoru jsou v datasheetu i v helpu AVR Studia dobře popsané a vysvětlené. Tím se naučíš, co se v procesoru děje a pak můžeš přejít na vyšší jazyk. Pak se třeba nebudeš dopouštět toho, že cyklus zapíšeš jako for(i=0 ; i<20 ; i++), ale napíšeš ho jako for(i=20;i>0;i–). Na první pohled to vypadá, že je to jedno, ale z hlediska procesoru (a jeho instrukční sady) už není jedno, jestli čítá od 0 nahoru a kontroluje, jestli už proměnná dosahla požadované hodnoty nebo jestli čítá od určité hodnoty a končí nulou.

Nauč se normální obyčejné C. Na internetu je mraky výukových seriálů o céčku, nemusíš nic kupovat. A pak to doplnit o věci co se týkají konkrétně AVR, protože mikrokontroléry mají svoje specifika která je odlišují od počítačů. Jo a C# není C ani C++

co se tyce knizek tak zadnou bych nekupoval vse se da najit na internetu,
skus kouknout tady Programujeme AVR v jazyku C , a mas tam i teda tu knizku