PIC 16f84 - doba stisku tlačitka

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
budsky
Příspěvky: 76
Registrován: 06 srp 2007, 02:00
Kontaktovat uživatele:

PIC 16f84 - doba stisku tlačitka

#1 Příspěvek od budsky »

Zdravím,potřeboval bych poradit:
řečim konstukci s danýám picem
tlačitko je na pinu RA0
výstup je RB0
je to děláne v Cečku
moje část programu:
int main(int argc, char** argv) {

TRISA0 = 1; //RA0 jako vstup
TRISB0 = 0; //RB0 jako výstup
RB0 = 0; //výchozí stav

do
{
if(RA0 == 1)
{
__delay_ms(100);
if(RA0 == 1)
{
RB0 = 1; //LED ON
__delay_ms(10000); // aktivní výstup 10sekund
RB0 = 0; //LED OFF
}
}
}while(1);
}

a jde mi o to že bch tam potřeboval dodělat aby se sepnul výstup jen při dlouhém stisku tlačitka cca delším stisku jak 10s.
pokud by byl stisk kratší tak by se nic nestalo.
a nějak na to nemohu v cěcku přijít poradil by někdo prosím

Uživatelský avatar
Zaky
Příspěvky: 6129
Registrován: 30 říj 2010, 02:00
Bydliště: Praha

#2 Příspěvek od Zaky »

Třeba tak, že budeš točit smyčku 1x za sekundu (spíš aspoň 10x za sekundu) a inkrementovat proměnou dokud bude stiské tlačítko, až dojde k puštění tlačítka, smyčka se ukončí a porovná se, do kolika se napočítala ona proměnná.

Uživatelský avatar
Jirka525
Příspěvky: 325
Registrován: 22 kvě 2013, 02:00
Bydliště: Psáry JN79GW

#3 Příspěvek od Jirka525 »

Já jsem si pro tento případ udělal funkci t_on (zpožděné zapnutí). Výhodou je, že program nečeká na uplynutí 10 s ale obsluhuje ostatní periferie a po uplynutí 10 s zapne výstup.

Jestli se ti to povede optimalizovat, napiš, rád si vylepším svůj SW park.

struct casovac {
int cas1;
char stav;
} ton1, ton2, tof1;


ISR(TIMER0_COMPA_vect) //Preruseni od casovace
{
ton1.cas1--;
ton2.cas1--;
tof1.cas1--;
}

/*Zpozdene zapnuti
vstup: signal - signal, ktery se zpozdene zapina
casovac.stav
B0 - vystupni signal
B1 - minuly stav vstupu signal
B2 - casovac bezi
casovac.cas1 - casovac aktualni cas do zapnuti vystupu
zpozdeni - nastavene zpozdeni v 1 ms
vystup: zpozdeny signal
*/
char t_on(char signal, int zpozdeni, struct casovac *data)
{
char pom_hrana, pom_sig;

pom_sig = signal;
pom_hrana = (pom_sig << 1);
if(((pom_hrana ^ data->stav) & 2) || (data->stav & 4) == 0) //je hrana signalu nebo jeste nezacalo casovani
{
data->cas1 = zpozdeni;
data->stav |= 4;
}
if (signal) //zapis minule hodnoty vstupu pro pristi prubeh
{
data->stav |= 2;
}
else
{
data->stav &= 0xfd;
}
if ((signal && (data->cas1 < 1)) || (data->stav & signal & 1))
{
data->stav |= 1;
}
else
{
data->stav &= 0xfe;
}
return data->stav & 1;
}
Naposledy upravil(a) Jirka525 dne 25 kvě 2015, 09:07, celkem upraveno 2 x.
Jirka

Uživatelský avatar
Zaky
Příspěvky: 6129
Registrován: 30 říj 2010, 02:00
Bydliště: Praha

#4 Příspěvek od Zaky »

Moje verze se dá slušně (tedy, aby se nečekalo ve smyčce, ale MCU mohl provádět další kód) udělat tak, že se timerem generuje přerušení řekněme každých 10 nebo 100 ms, a v přerušení od timeru se nahazuje příznak. V hlavní smyčce se testuje, zda je příznak nahozen, tím se dá časovat v kódu běžícím jinak plnou rychlostí MCU. Tento základní interval pak není problém programově dále dělit na pomalejší intervaly. Kód pak samozřejmě nesmí nikde na nic čekal, musí být maximálně "propustný", aby se bezpečně stihl protočit rychleji, než je základní interval timeru. Je to obecně platná věc. Takový kód je vždu trochu složitější, než, když se čeká ve smyčkách, ale pokud má být kdykoli zaručená odezva, není jiné cesty.

Uživatelský avatar
monterjirka
Příspěvky: 2761
Registrován: 14 čer 2003, 02:00
Bydliště: Blížejov

#5 Příspěvek od monterjirka »

Musí to být s PICem?
Kdybych to řešil s Arduinem, počkal bych si na stisk tlačítka,
odečetl hodnotu millis, hlídal jak mě millis roste a jestli je pořád stisknuto.
Pokud vydrželo stisknuto tak dlouho, že by se millis zvětšilo o 10000, bylo by "splněno".

termit256
Příspěvky: 10071
Registrován: 06 pro 2007, 01:00

#6 Příspěvek od termit256 »

Je nutne aby bezela hlavni smycka kdyz drzis tlacitko stiskle? Pokud ne, testuj az u uvolneni tlacitka. Pri stisku spust cekaci smycku 10s ve ktere prubezne testuj uvolneni tlacitka. Pokud dojede na konec, spust danou akci. Pokud dojde k uvolneni driv, udelej to se ma provest pri kratkem stisku.

Usetris si tak timer pro jine pouziti.

Pokud mas ovsem timer volny, neni co resit. Pokud je tlacitko stiskle, v obsluze preruseni vzdy inkrementuj nejakou hodnotu, az dosahne poctu odpovidajici 10 sec, nastav nejaky priznak na jehoz zaklade pak pohodlne v hlavni smycce provedes potrebnou akci.

Uživatelský avatar
budsky
Příspěvky: 76
Registrován: 06 srp 2007, 02:00
Kontaktovat uživatele:

#7 Příspěvek od budsky »

Arduino určitě nepřipadá v uvahu..
Je nutne aby bezela hlavni smycka kdyz drzis tlacitko stiskle? Pokud ne, testuj az u uvolneni tlacitka
není nutné jde jen o to vyhodnotiti tlačítko jestli bylo stisklé oněch cca 10 vteřin a pokud ano tak sepnout jen výstup nic víc

hakamusai
Příspěvky: 943
Registrován: 17 dub 2007, 02:00

#8 Příspěvek od hakamusai »

V čem to píšeš ?
Z mýho úhlu pohledu se to dá řešit několika způsoby (podle situace).Dá se to řešit celý timerem -při přerušení timeru se testuje log. hodnota požadovanýho vstupu.Pokud je tlačítko stisknuto,inkrementuje se couner(globální proměnná).Pokud je log. 0 nastaví se counter na nulu.Pokud má counter hodnotu požadovanou vykoná se požadovaný kód (nastavení výstupu).Naposled je třeba testovat velikost counteru a případně dekrementovat.
Jde to řešit více způsoby.

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#9 Příspěvek od mtajovsky »

Tohle není vždy spolehlivé a záleží na periodě časovače. Pokud například bude časovač 1 s, a v době mezi vypršením časovače se tlačítko krátce uvolní a opět stiskne, mělo by to znamenat restart intervalu 10 s. Popsaným způsobem se to ale může promeškat.

Osobně bych to řešil "dvouvrstvě". Na "úrovni HW" v hlavní smyčce testovat změnu tlačítek s ošetřením zákmitů. Třeba časovačem 5 ms, v nejhorším případě čekací smyčkou, ale na to jsem dost alergický. :) Na "logické" úrovni při ověřeném stisku tlačítka pak nahodit časovač 10s (nejspíš softwarový), při ověřeném uvolnění tlačítka jej shodit. Vyhodnocení, že tlačítko bylo stisknuto nepřetržitě 10 s je dáno vypršením časovače 10 s.

hakamusai
Příspěvky: 943
Registrován: 17 dub 2007, 02:00

#10 Příspěvek od hakamusai »

Pochopitelně čas timeru řádově v ms.Hlavně používat při programování selský rozum !

Uživatelský avatar
budsky
Příspěvky: 76
Registrován: 06 srp 2007, 02:00
Kontaktovat uživatele:

#11 Příspěvek od budsky »

píšu to v mplab X ide a v něm v céčku

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#12 Příspěvek od mtajovsky »

budsky píše: ... jde jen o to vyhodnotiti tlačítko jestli bylo stisklé oněch cca 10 vteřin a pokud ano tak sepnout jen výstup nic víc
No, ale předpokládám, že to není jediná akce celé aplikace. Musí se to řešit tak, aby takových a podobných věcí mohlo být z hlediska architektury řešení neomezeně mnoho. Omezení musí být jen výkonem procesoru a dostupnou pamětí. Pokud by to byla skutečně jediná úloha, pak není třeba MCU, kromě toho by periodické mačkání tlačítka zablokovalo MCU na neomezeně dlouhou dobu v čekání na těch 10 s. To asi nebude žádoucí, což?

Uživatelský avatar
budsky
Příspěvky: 76
Registrován: 06 srp 2007, 02:00
Kontaktovat uživatele:

#13 Příspěvek od budsky »

všem dekuji za rady a řešení bylo celkem jednoduché :)

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“