nassus Postat Martie 5, 2007 Partajează Postat Martie 5, 2007 Reusesc sa rezolv probleme complicate de programare si algoritmica dar nu reusesc sa rezolv o problema banala...am un buton conectat la RD1 (de exemplu) si un led la RB1, cand apas odata pe buton se aprinde ledul iar cand mai apas odata sa se stinga ledul.. prblema s-ar rezolva simplu cu sintaxa RB1=!RB1 dar din pacate nu o pot folosi pt ca ledul este aprins de o functie si de alta functie este stins. Am incercat o gramada metode dar nu reusesc sa rezolv 2 probleme : 1 debounce-ul butonulul fara prea mare delay si 2: chestia asta trebuie sa fie intr-o functie care primeste ca parametru pinul de intrare si sa nu returneze nimic...So astept idei... Link spre comentariu
MihaiStoica Postat Martie 6, 2007 Partajează Postat Martie 6, 2007 In primul rand in ce scrii programele? Daca in C te pot ajutaGeneric vorbind daca butonul este pe RD1 (configurata ca intrare) trebuie sa baliezi intrarea pentru a vedea(simti) trecerea din 0 in 1 sau invers. Alta metoda ar fi sa pui butonul pe RB1 si LED-ul pe alt pin (iesire).RB1 trebuie configurat ca intrare care sa genereze o intrerupere la schimbarea starii. Mai departe e treaba de pura programare Link spre comentariu
nassus Postat Martie 6, 2007 Autor Partajează Postat Martie 6, 2007 iar am uitat ca in C muncescfaza e ca nu pot sa folosesc intreruperea de pe PORTB pt ca nu imi permite montajular fi bun un algoritm ceva daca stie careva. Link spre comentariu
Vizitator zuzurelu Postat Martie 6, 2007 Partajează Postat Martie 6, 2007 In assembler ai putea incerca ceva de genul : #define BUTON PORTB,1 #define LED PORTB,2 ; FLAGS este un registru de uz generalMAIN;; etc; etc;;------------------------------------------; Butonul BUTON ;------------------------------------------btfsc BUTON ; Butonul este apasat ? goto NU_S_A_APASAT_BUT ; nope... ; Da, acum este apasat btfsc FLAGS,1 ; Este prima oara apasat ?goto SE_MENTINE_APASAT_BUT ; Nope, butonul se mentine apasat ; Da, acest buton este apasat prima oara ; ( ne intereseaza doar frontul POZ al comutarii )bsf FLAGS,1 ; Ne ajutam de acest flag...;-------------------------------------; Actiunea BUTON, se va executa o singura data; la fiecare apasare de buton. Daca LED aprins, stinge-l si vice-versacall DEBOUNCE ; un delay de 10-20 mSbtfsc LED ; LED-ul era aprins ?bcf LED ; stinge LED-ulbtfss LED ; LED-ul era stins ?bsf LED ; aprinde LED-ul ;-------------------------------------SE_MENTINE_APASAT_BUTgoto END_BUT ; Daca butonul se mentine apasat ; nu facem nimic...NU_S_A_APASAT_BUT bcf FLAGS,1 ; Am terminat cu flagul...END_BUT; END Buton BUT;-------------------------------------------------------------------------------;; etc; etc; Nota : E doar o sugestie, copiii si televizoarele se fac la fata locului.... YO3HCV Link spre comentariu
Vizitator musaraf Postat Martie 6, 2007 Partajează Postat Martie 6, 2007 Uite si o varianta in "pseudocod". Daca nu se poate detecta nivelul pinului cu intreruperi, nu mai ramane decat polling. O mare parte din viata sa programul o sa si-o petreaca verificand starea lui RB1. unsigned char Setat; // variabila globala, nu stiu cu ce compilator mergevoid main(){ Setat = 0; PORTD.PIN1 = LOW; for (;;) // bucla principala { while(!PORTB.PIN1); // asteapta sa apasam butonul schimba_stare_portD(); }} void schimba_stare_portD() // efect colateral{ delay_ms(50); // sau cat trebuie ptr debounce if (Setat) // Schimbam si starea lui Setat, si a lui PORTD PORTD.PIN1 = LOW; else PORTD.PIN1 = HIGH; Setat = ~Setat; // sau Setat = !Setat, Setat = Setat^Setat etc.} Normal, se poate si fara variabila globala, dar atunci functia ar trebui sa intoarca o valoare: void main(){ unsigned char Setat; for(;;) { ... Setat = schimba_stare_portD(); ... }} Link spre comentariu
nassus Postat Martie 7, 2007 Autor Partajează Postat Martie 7, 2007 Bun codul pana la functia care aprinde ledul... Functia asta trebuie sa primeasca, ca si parametru pinul de intrare (RD1).Am incercat sa ii pun ca si parametru pinul dar nu mai merge cum trebuie.. adica atunci cand se apasa butonul se aprinde ledul iar cand se elibereaza butonul se stinge ledul.. Plus ca daca tin butonul apasat ledul se stinge si se aprinde cu o perioada care depinde de delay.So.. alte idei? Link spre comentariu
Vizitator zuzurelu Postat Martie 7, 2007 Partajează Postat Martie 7, 2007 Bun codul pana la functia care aprinde ledul... Functia asta trebuie sa primeasca, ca si parametru pinul de intrare (RD1).Am incercat sa ii pun ca si parametru pinul dar nu mai merge cum trebuie.. adica atunci cand se apasa butonul se aprinde ledul iar cand se elibereaza butonul se stinge ledul.. Plus ca daca tin butonul apasat ledul se stinge si se aprinde cu o perioada care depinde de delay.So.. alte idei?Normal, tu trebuie sa detectezi software FRONTUL butonului si nu PALIERUL. Adica dupa ce ai detectat PRIMA OARA schimbarea, executi ceva si nu mai treci pe acolo pana nu se ia labutza de pe buton. Altfel, vei detecta CU FRECVENTA DE EXECUTIE a buclei principale ( choppata de functia DEBOUNCE ), mereu, acelasi buton apasat si deci vei executa de o multime de ori ACTIUNEA care te intereseaza.Daca vrei un bistabil, poti face foarte simplu treaba asta incrementand cu 1 un byte (un char) oarecare si verificand bitul 0 al sau. O data va fi 0 iar urmatoarea va fi 1 intotdeauna.YO3HCV, Link spre comentariu
Vizitator musaraf Postat Martie 7, 2007 Partajează Postat Martie 7, 2007 Asta cu repetarea cam asa-i. Si in plus era butonul la RD si ledul la RB, eu am scris invers :rolleyes:. Link spre comentariu
nassus Postat Martie 12, 2007 Autor Partajează Postat Martie 12, 2007 Alte idei?? Link spre comentariu
Abram Burel Postat Martie 12, 2007 Partajează Postat Martie 12, 2007 O idee ar fi ca durata debouncing-ului depinde de tipul de buton folosit. Asta inseamna ca ar trebui sa poti astepta stabilizarea starii atata cat sa se potoleasca contactul electric. Avand in vedere ca tu lucrezi la nivel de maxim usec per instructiune, nu prea vad de ce sa nu reusesti sa-l faci mai rapid daca butonuliti permite (daca nu, n-ai de ce sate stresezi in program ca nu rezolvi nimic).O alta idee are fi ca chiar daca faci apelul cu 2 functii diferite, nu vad de ce nu poti "pasa argumentul" intr-o variabila globala. Daca n-ai loc nici de asta, poate gasesti vreun bit de status.... nefolosit Link spre comentariu
Vizitator zuzurelu Postat Martie 12, 2007 Partajează Postat Martie 12, 2007 O idee ar fi ca durata debouncing-ului depinde de tipul de buton folosit. Asta inseamna ca ar trebui sa poti astepta stabilizarea starii atata cat sa se potoleasca contactul electric. Avand in vedere ca tu lucrezi la nivel de maxim usec per instructiune, nu prea vad de ce sa nu reusesti sa-l faci mai rapid daca butonuliti permite (daca nu, n-ai de ce sate stresezi in program ca nu rezolvi nimic).O alta idee are fi ca chiar daca faci apelul cu 2 functii diferite, nu vad de ce nu poti "pasa argumentul" intr-o variabila globala. Daca n-ai loc nici de asta, poate gasesti vreun bit de status.... nefolosit Nu este bine sa folosesti bitii STATUS ca indicatori tip flag. Este o sursa periculoasa de erori stupide, mai ales daca NU lucrezi in assembler. Ai suficienta memorie sa definesti un byte sau un char ca octet de flaguri.Ce idei iti mai trebuie pentru un simplu push-buton ? Ti-am pus o rutina asm ce detecteaza atat frontul crescator cat si palierul + frontul coborator, inclusiv debounce. Retine conceptul si aplica-l in C.YO3HCV, Link spre comentariu
Vizitator musaraf Postat Martie 13, 2007 Partajează Postat Martie 13, 2007 Pentru problema cu debounce nu mai scriu, ca am inteles ca totusi merge, numai timpul pentru debounce este prea mare. Pentru functia care are ca argument un pin, depinde de compilatorul tau. Daca accepta o sintaxa de tipul byte pin;byte val;val = PORTD.pin;este mai simplu. Daca nu, tot va merge cu switch: void schimba_stare_portB(int pin_din_D){ delay_ms(timp_debounce); switch (pin_din_D) { case 0: PORTB.PIN0 = ~Setat0; ..... break; case 1: PORTB.PIN1 = ~Setat1; ..... ... }} Eventual zi cu ce compilator lucrezi, si poate bucata de program care face treaba. Si eu sint curios. Link spre comentariu
Vizitator musaraf Postat Martie 13, 2007 Partajează Postat Martie 13, 2007 Eroarea din post-ul de la inceput ( executa de mai multe ori functia schimba_stare_port(), cat timp se tine apasat butonul ) cred ca se rezolva cam asa: for (;;) // bucla principala { while(!PORTX.PIN1); // asteapta sa apasam butonul schimba_stare_portY(); while(PORTX.PIN1); // asteapta sa lasam butonul delay_ms(timp_debounce); // ziceam ca si la deschidere trebuie debounce } Link spre comentariu
nassus Postat Martie 21, 2007 Autor Partajează Postat Martie 21, 2007 gata am reusit sa rezolv problema... elegant.. mersi pt sfaturi Link spre comentariu
nassus Postat Aprilie 6, 2007 Autor Partajează Postat Aprilie 6, 2007 Revin cu probleme....Vreau sa determin pozitia unui mecanism aflat intr-un mediu mai putin ospitalier (portiera unei masini (dacia)). Mecanismul are o rotatie de vreo 70 grade maxim si din acest motiv ma gandeam sa folosesc un potentiometru dar fiind un mediu asa de nasol cred ca jumatate din timpul alocat pt proiect o sa il petrec realizand o cutie cu filtre de aer si umezeala pt potentiometru si nu prea e ok.M-am mai gandit la un sistem tip mouse dar in cazul in care mecanismul este miscat fara ajutorul motorului atunci se decaleaza totul si nu mai merge. Ce idei aveti pt chestia asta?MersiPS. Daca intereseaza pe cineva codul pt debouncing sa ma anunte sa il postez. Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum