wwwglro Postat August 24, 2009 Partajează Postat August 24, 2009 Salut.Am realizat un program care face urmatoarele:-seteaza port a ca intrare si port b jumata intrare jumate iesire (RB4-RB7 ca intrare).-Am definit 2 taste pe intrarile A0 si A1 si 2 leduri pe B0 si B1.Atunci cand apas tasta 1, ledul nr 1 lumineaza ptr 5 secunde si apoi se stinge.Cand apas tasta 2m, ledul 2 lumineaza pentru 5 secunde si apoi se stinge.As vrea ca atunci cand apas tasta 2 cat timp ledul nr. 1 lumineaza, acesta sa se stinga (intrerupere) si sa lumineze ledul 2 si invers, cand apas tasta 1 cat timp ledul nr. 2 lumineaza, acesta sa se stinga (iar o intrerupere) si sa se aprinda ledul 1.Programul l-am facut in CCS.Daca aveti idee cum as putea lucra cu intreruperi in acest caz...raman dator...Merci Link spre comentariu
ohamoha Postat August 24, 2009 Partajează Postat August 24, 2009 Nu ai spus ce oscilator folosesti. Sa zicem ca ai unul de 4Mhz. Asta inseamna ca intreruperea se va activa de 4000000/4*256=3906 ori pe secunda. Acestea fiind zise, eu as face asa: long bec0=1;long bec1=1;#int_rtccvoid clock_isr() { bec0--; bec1--; if(bec0<1) bec0=1; if(bec1<1) bec1=1; if(bec0>1) output_high(pin_b0); else output_low(pin_b0); if(bec1>1) output_high(pin_b1); else output_low(pin_b1);}void main(){set_rtcc(0);setup_counters (RTCC_INTERNAL, RTCC_DIV_1);enable_interrupts (INT_RTCC);enable_interrupts(GLOBAL);do { if(input_state(PIN_a0)==0) //daca butonul este legat ca in imaginea atasata, cu o rezistenta "pullup" { bec0=19530; //3906*5 secunde bec1=1; } if(input_state(PIN_a1)==0) { bec1=19530; //3906*5 secunde bec0=1; }} while(1);} N-am compilat sursa asta, am scris-o acum la repezeala. Scuze daca am scapat greseli. Dar ai prins ideea. Link spre comentariu
wwwglro Postat August 25, 2009 Autor Partajează Postat August 25, 2009 Salut si merci pentru raspuns. Programul merge foarte bine dar...ca sa inteleg si eu: - oscilatorul este de 4MHz. - ai initializat timerul 0 - nu prea inteleg de ce folosesti variabilele bec0 si bec1; cumva incrementezi sau decrementezi o variabila de cate ori se reinitiaza timerul 0 adica cant trece de la 255 la 0 si numara iar? - daca se doreste un timp mai mic in care sta aprins ledul se face 3906 * (timpul cat vreau sa fie aprins ledul)? si de ce se face chestia asta? -de ce decrementezi in functia intrerupere cele 2 variabile la inceput? Daca vreau ca montajul sa faca altceva, trebuie modificat corpul functiei intrerupere cred...nu? In acest sens cum intervin valorile lui bec0 si bec1 de 19530 din programul principal in corpul functiei intrerupere? - in corpul functiei intrerupere, de ce compari bec0 si bec1 cu 1? Deocamdata atat... Merci. Link spre comentariu
ohamoha Postat August 25, 2009 Partajează Postat August 25, 2009 bec0 si bec1 sunt doua variabile long. Adica pot lua valori intre 0 si 65535. In functie de ele aprind sau sting LED-ul. Gandeste-te la ele ca la doua vase cu apa, care au o gaura in fund. Atata timp cat este apa in ele, LED-ul corespunzator sta aprins. Apa se scurge incetisor pana cand vasul se goleste si LED-ul se stinge. Daca in variabila bec0 pun 19530, intreruperea decrementeze variabila cu 1 la fiecare activare. Astfel ca pana epuizeaza variabila, LED-ul sta aprins. Calculand, 19530 ajunge cam pentru 5 secunde. Vezi ca in primele doua randuri din intrerupere fac decrementarea. Astfel "golesc" variabilele putin cate putin. Daca vrei un timp mai scurt in care LED-ul sa stea aprins, modifici valoarea 19530. Cu cat e mai mica, cu atat "pui" mai putina apa in vasele bec0 si bec1 si se scurge mai repede. Sursa asta se aplica la cerinta ta de a aprinde alea doua leduri. Daca vrei sa faca altceva, probabil trebuie regandit algoritmul. Depinde de ce vrei sa faci. In programul principal, modificand variabilele bec0 si bec 1 "umplu" sau "golesc" cele doua vase. Cerinta ta era ca atunci cand este un LED aprins, automat celalalt trebuie stins. Asa ca in momentul in care "umplu" bec0, trebuie sa "golesc" bec1, actiune care va determina stingerea LED-ului 1. Compar bec0 si bec1 cu 1 pentru ca nu vreau sa le las sa ajunga la 0. if(bec0<1) bec0=1;if(bec1<1) bec1=1;Pentru ca daca bec0 este 0, si execut bec0--, bec0 nu va deveni -1 ci 65535. Pentru ca long-ul este unsigned in sursa mea.Poti sa scrii mai simplu: (eu m-am complicat cand am scris sursa ) if(bec0>0) bec0--; //decrementeaza numai daca bec0 este mai mare decat 0. daca e 0, lasa-l 0Ideea e sa nu lasi variabila sa pice sub 0. Link spre comentariu
ratza Postat August 25, 2009 Partajează Postat August 25, 2009 Cînd cade sub zero e de preferat s? reini?ializezi cu valoarea maxim? pe care o poate lua variabila, de exemplu 65535 (0xFFFF) pentru 16 bi?i f?r? semn, aka unsigned int. long e pe 32 de bi?i. Link spre comentariu
ohamoha Postat August 25, 2009 Partajează Postat August 25, 2009 In CCS, long e pe 16 biti. Link spre comentariu
ratza Postat August 25, 2009 Partajează Postat August 25, 2009 Bine, cu un typedef po?i pune ?i lungeanu, scurteanu etc. Se poate s? m? fi obi?nuit eu prost ?i s?-mi fac singur drivere. Link spre comentariu
wwwglro Postat August 25, 2009 Autor Partajează Postat August 25, 2009 Am postat cam repede pe forum inainte sa rumeg un pic programul.Am inteles ce fac cele 2 variabile. (nu stiam partea cu sa nu cada sub zero cele 2)Se complica treaba daca vreau sa fac ca cele 2 leduri sa clipeasca intermitent (pe rand )... Link spre comentariu
ohamoha Postat August 25, 2009 Partajează Postat August 25, 2009 Nu neaparat. Eu personal ma feresc sa pun delay-uri in intreruperi, dar de dragul rapiditatii, poti sa faci si asta. Inlocuieste codul asta: if(bec0>1) output_high(pin_b0); else output_low(pin_b0); if(bec1>1) output_high(pin_b1); else output_low(pin_b1);Cu asta: if(bec0>1) output_high(pin_b0); if(bec1>1) output_high(pin_b1); delay_ms(250); output_low(pin_b0); output_low(pin_b1); delay_ms(250);Dar trebuie recalculat numarul ala 19530, pentru ca acum intreruperile vor surveni mult mai rar datorita delay-ului. Pentru 5 secunde bec0=10 daca ma gandesc bine. Link spre comentariu
wwwglro Postat August 30, 2009 Autor Partajează Postat August 30, 2009 Am mai modificat un pic valorile lui bec pana a fost bine. (bec=7 si delay de 300ms) Problema care am observat-o la simulare este urmatoarea: cand apas scurt pe buton nu se intimpla nimic. Trebuie sa tin apasat pe buton un timp mai lung (aproape o secunda) pentru ca ledul aferent sa inceapa sa clipeasca(la fel se intimpla cand apasa celalalt buton - adica cand apelez intreruperea). Merci Link spre comentariu
wwwglro Postat August 31, 2009 Autor Partajează Postat August 31, 2009 E cumva din cauza delay-ului din intrerupere?Merci Link spre comentariu
ohamoha Postat Septembrie 1, 2009 Partajează Postat Septembrie 1, 2009 Da. Ala e responsabil pentru comportamentul asta. Nu e o solutie buna, clar. Link spre comentariu
wwwglro Postat Septembrie 1, 2009 Autor Partajează Postat Septembrie 1, 2009 Daca nu am definit in main() care sunt porturile de intrare si care sunt cele de iesire, e normal ca programul de mai sus (postul nr. 2) sa functioneze?E suficient sa declar if(input_state(PIN_a0)==0 pentru a sti microcontrolerul ca pinul A0 este de intrare?Eu stiam ca porturile trebuiesc initializate la inceputul programului in main(){}.set_tris_a(0x00); //initializare port A ca intrareset_tris_b(0xff); //initializare port B ca iesireoutput_b(0x00); //seteaza port B in zeroMerci. Link spre comentariu
wwwglro Postat Septembrie 3, 2009 Autor Partajează Postat Septembrie 3, 2009 Va mai cer ajutorul un pic. La programul din postul 1: daca se apasa o tasta sa lumineze un led ptr 5 secunde, daca se apasa cealalta tasta (intrerupere) sa lumineze celalalt led DAR daca se detecteaza ca apasarea de tasta a durat mai mult de jumatate de secunda, ledul aferent tastei respective sa se stinga cand se elibereaza tasta aferenta. Merci Link spre comentariu
wwwglro Postat Septembrie 5, 2009 Autor Partajează Postat Septembrie 5, 2009 Ma puteti ajuta...macar cu o idee...Merci 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