Vizitator Postat Mai 13, 2012 Partajează Postat Mai 13, 2012 Un ciclu de delay la mine înseamnă 1 microsecundă pentru că ceasul este lasat pe default. Default la G2231 e 1 MHz, probabil la fel e şi la G2553, n-am verificat, trebuie să te uiţi în catalog. Revenind, să lăsăm debouncing-ul. În linia P1OUT = BUTON_S2; vroiai de fapt să stingi LED-ul roşu. Atunci foloseşte te rog măştile, cum am învăţat. Altfel am pierdut timpul degeaba. Stinge doar LED-ul. Acolo tu ai suprascris toşi biţii din P1OUT. Odată ce ai configurat bitul 3 din P1OUT la începutul programului, îl laşi aşa. Nu are rost să mai umbli la el în interiorul instrucţiunii if. Ca să stingi doar LED-ul roşu, fără să modifici ceilalţi biţi, faci aşa: P1OUT &= ~LED_RED; La fel, P1OUT = 0x09; nu e bun pentru că face şi alte chestii. Chiar dacă programul funcţionează, nu e bine, pentru că îţi creezi obiceiuri proaste. Înseamnă că m-am zbătut degeaba. Vrem să aprindem doar LED-ul roşu, fără să umblăm la ceilalţi biţi. Acum spune tu, te rog, cum se aprinde LED-ul roşu fără să afectezi restul biţilor? Link spre comentariu
adyyo Postat Mai 13, 2012 Autor Partajează Postat Mai 13, 2012 Vroiam sa testez ideea cu delay-ul si am deschis proiectul cu prima varianta de stins/aprins LED-ul. Cred ca asa trebuia de fapt scris programul: if (!(P1IN & BUTON_S2)) // Daca S2 este apasat _delay_cycles(160000); //Asteapta perioada if (!(P1IN & BUTON_S2)) //Verifica din nou daca S2 e apasat, daca da if ((P1OUT & LED_ROSU)) //Daca e aprins LED_ROSU P1OUT &= ~LED_ROSU; //Stinge LED_ROSU else P1OUT |= LED_ROSU; //Aprinde LED_ROSU Link spre comentariu
Vizitator Postat Mai 13, 2012 Partajează Postat Mai 13, 2012 Acum codul tau arata ca al unui adevarat profesionist! Deşi formalismul l-ai respectat, nu am avut timp să testez logica. Pe viitor, pune te rog programele complete, ca sa fie mai usor de testat. Există multe metode de a face debouncing. Cel mai elegant e cu intreruperi. Ce vezi mai jos e fara intreruperi şi e doar cu scop didactic. Am definit o funcţie care se ocupă de citirea butonului. Funcţia o poţi folosi în programul principal (main), de câte ori e nevoie. Dezavantajul este că programul principal asteaptă până ridici degetul de pe buton. În unele programe, metoda asta poate deveni imposibil de folosit. #include "msp430g2231.h"#define LED_ROSU BIT0 //deoarece LED-ul rosu este montat la pinul P1.0#define LED_VERDE BIT6 //deoarece LED-ul verde este montat la pinul P1.6#define BUTON_S2 BIT3 //deoarece butonul S2 este montat intre pinul P1.3 si GND//Functia ApasareCompletaS2() intoarce 1 daca apare o apasare completa,// altfel intoarce 0//Apasare completa inseamna apasare sustinuta cel putin 20 ms,// dupa care se asteapta oricat pana la relaxarea butonuluichar ApasareCompletaS2(void) { char StareButon = 0; // la inceput presupun butonul neapasat if ((P1IN & BUTON_S2) == 0) //Daca P1.3 e zero { _delay_cycles(20000); //astept 20 ms if ((P1IN & BUTON_S2) == 0) //Daca P1.3 inca mai e zero inseamna ca nu e vibratie { while ((P1IN & BUTON_S2) == 0); //Acum astept la infinit pana ia degetul de pe buton StareButon = 1; // dupa ce a luat degetul consider ca apasarea a fost completa } else StareButon = 0; // consider ca butonul nu a fost apasat complet } return (StareButon);}//aici incepe executia (programul principal)void main(void){ WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer P1DIR = LED_VERDE | LED_ROSU; //Configureaza pinii P1.0 si P1.6 ca iesiri (restul ca intrari) P1REN = BUTON_S2; //Activeaza rezistoarele de pe intrarea P1.3 P1OUT = LED_VERDE | BUTON_S2; //Aprinde LED-ul verde, stinge restul, iar pe P1.3 activeaza pull up resistor while (1) // bucla infinita { if (ApasareCompletaS2()) //Daca se detecteaza o apasare completa P1OUT ^= LED_ROSU; // inverseaza doar starea LED-ului rosu, restul bitilor raman nemodificati }} Azi nu mai am timp, baftă la programat în continuare! Link spre comentariu
Liviu M Postat Mai 13, 2012 Partajează Postat Mai 13, 2012 Alinierea frumoasă a codului în scopul unei citiri mai uşoare, se numeşte identare. Iar ai dreptate. Si eu care eram mandru ca limba romana (inca) o (mai) stiu. LE Da' ca sa nu zici ca n-am si eu ceva de comentat, ai mancat o litera indentare Cat despre scris, pe scurt tu scrie ca ne descurcam noi cu cititul. Daca nu, mai intrebam/te provocam cu nestiinta noastra. Link spre comentariu
Vizitator Postat Mai 13, 2012 Partajează Postat Mai 13, 2012 Indiferent de discuţie, nu contează cine are sau nu are dreptate, că nu ne propunem să facem clasamente. Important e ca în urma duscuţiei fiecare să-şi clarifice ce nu ştia. ... LE Da' ca sa nu zici ca n-am si eu ceva de comentat, ai mancat o litera indentare ... Eram convins că e identare dar greşeam. Corect e indentare.Mulţumesc pentru observaţie. Link spre comentariu
Liviu M Postat Mai 13, 2012 Partajează Postat Mai 13, 2012 Acum codul tau arata ca al unui adevarat profesionist! Prea profesionist pentru gustul meu. Mie imi place mai "didactic", asa ca folosesc peste tot (if, while...) acoladele (dupa cum folosesc aproape de fiecare data () la operatiile/testele logice. In felul asta stiu ca programul face ce vreau eu, nu compilerul (sau daca nu face inseamna ca-s singur de vina ).Asa ca la mine codul ar fi aratat:if (!(P1IN & BUTON_S2)) // Daca S2 este apasat{ _delay_cycles(160000); //Asteapta perioada if (!(P1IN & BUTON_S2)) //Verifica din nou daca S2 e apasat, daca da { if ((P1OUT & LED_ROSU)) //Daca e aprins LED_ROSU P1OUT &= ~LED_ROSU; //Stinge LED_ROSU else P1OUT |= LED_ROSU; //Aprinde LED_ROSU }} In unele cazuri as pune acolade si pentru al treilea if si else-ul lui. Link spre comentariu
adyyo Postat Mai 13, 2012 Autor Partajează Postat Mai 13, 2012 Si ca o concluzie la ce am invatat azi, de fapt ieri , am facut un programel cu de toate. Va aprinde ambele LED-uri la o apasare de buton, apoi le va stinge si reaprinde pe rand de 4 ori. #include "msp430g2553.h"#define Rosu BIT0 //defineste BIT0 ca fiind led-ul rosu#define Verde BIT6 //defineste BIT6 ca fiind led-ul verde#define S2 BIT3 //defineste BIT3 ca fiind butonul S2int i; //declara variabila ichar Comandavalida(void){ char butonS2 = 0; //declara o variabila butonS2 cu valoarea 0 if ((P1IN & S2) == 0) //daca este apasat S2 _delay_cycles(20000); //asteapta 20000 cicluri if((P1IN & S2) == 0) //daca si acum S2 este apasat butonS2 = 1; //atunci apasarea este valide else butonS2 = 0; //altfel apasarea este invalida return (butonS2); //intoarcere la inceputul subprogramului}void main(void){ WDTCTL = WDTPW + WDTHOLD; //opreste timerul watchdg P1DIR = Rosu | Verde; //seteaza biti 0 si 6 ca iesiri P1REN = S2; //initializeaza rezistorul de pe bit-ul 3 P1OUT = S2; //activeaza rezistorul pe bit-ul 3 while (1) { if (Comandavalida()) //daca subprogramul returneaza 1 { P1OUT ^= Rosu | Verde; //aprinde ambele LED-uri _delay_cycles(300000); for (i = 0 ; i<5 ; i++) //repeta de 4 ori { P1OUT &= ~Rosu; //stinge rosu _delay_cycles(300000); P1OUT &= ~Verde; //stinge verde _delay_cycles(300000); P1OUT |= Rosu; //aprinde rosu _delay_cycles(300000); P1OUT |= Verde; //aprinde verde } } }} Te rog RoGeorge, cand vei avea timp liber, sa imi explici cum sa folosesc intreruperile. Multumesc inca odata ca m-ai adus pana la nivelul asta. Acum o saptamana mi se parea imposibil de inteles zecile de linii de cod din programe, iar acum, cu foaia si pixul in fata calculand operatiile din liniile de program, reusesc sa inteleg mare parte. Link spre comentariu
Liviu M Postat Mai 15, 2012 Partajează Postat Mai 15, 2012 Revin la ideea mea fixa cu acoladele. Dupa parerea mea, din cauza ca ai facut economie de acolade debouncingul tau nu functioneaza cum ai vrea tu. char Comandavalida(void){ char butonS2 = 0; //declara o variabila butonS2 cu valoarea 0 if ((P1IN & S2) == 0) //daca este apasat S2 _delay_cycles(20000); //asteapta 20000 cicluri if((P1IN & S2) == 0) //daca si acum S2 este apasat butonS2 = 1; //atunci apasarea este valide else butonS2 = 0; //altfel apasarea este invalida return (butonS2); //intoarcere la inceputul subprogramului} Faptul ca ai indentat codul nu inseamna ca al doilea if se executa numai cand conditia din primul if e TRUE, ci se executa intotdeauna (if actioneaza asupra unei singure instructiuni; cand iti trebuie mai multe instructiuni, le "compui" intr-una singura folosind acoladele). Link spre comentariu
adyyo Postat Mai 15, 2012 Autor Partajează Postat Mai 15, 2012 Am inteles. Inca nu mi-a intrat in reflex sa pun acolade peste tot...ori uit sa le inchid, ori uit sa le deschid. Mai am de scris vreo cateva milioane de randuri de cod pana sa fac totul calumea. Oricum multumesc de indicatii, in general merge bine si asa, dar uneori face figuri felul asta de debouncing, cred ca tocmai din cauza acoladelor lipsa. Link spre comentariu
adyyo Postat Mai 15, 2012 Autor Partajează Postat Mai 15, 2012 Mi-ar place sa evoluez putin in comanda LED-urilor, si ma gandeam sa imi cumpar o matrice de LED-uri. Vreau un 5x7 sau ceva pe aproape. Asi vrea sa stiu daca este bine sa folosesc doar un uln2803 pentru a comanda catodurile maticei, iar anodurile sa le leg direct la porturile MCU-ului, nu exista posibilitatea sa ard pinii unde leg anodurile daca se aprind mai multe LED-uri odata sa zicem o coloana de 8? Link spre comentariu
Liviu M Postat Mai 16, 2012 Partajează Postat Mai 16, 2012 Nu stiu exact specificatiile controllerelor din kitul launchpad, da' un LED pe iesire ar trebui sa poata comanda.Daca vrei sa mergi pe varianta sigura (sau daca comanzi mai multe leduri cu aceeasi iesire) folosesti tranzistori/ULN, da' in cazul asta la iesirile tale legi baza/bazele tranzistorilor si nu ledurile. Ledurile le legi intre tranzistori si sursa (in functie de logica/tranzistori la + sau la GND) cu eventualele rezistente de limitare a curentului. Link spre comentariu
Vizitator Postat Mai 16, 2012 Partajează Postat Mai 16, 2012 In datasheet, la pagina 24 este un tabel, Outputs, Ports Px, iar la pagina 25 sunt graficele de tensiune-curent pentru ieşiri. http://www.ti.com/lit/ds/symlink/msp430g2553.pdf Specificaţiile din catalog sunt garantate pentru +/- 6 mA pe o ieşire, cu condiţia să nu depăşeşti 48 mA pentru toate ieşirile. Poţi avea mai mult de 6 mA, dar atunci tensiunea pe ieşire nu mai e cea garantată. Ca să vezi la ce tensiune de ieşire să te aştepţi pentru curenţi mai mari, trebuie să te uiţi în grafice. Spre deosebire de alte MCU-uri, pentru cele din familia MSP430 nu se dă o limită clară pentru curentul maxim suportat. De aici s-ar putea înţelege că poţi face şi scurt pe ieşiri, dar n-aş încerca aşa ceva. Fiecare pin are 2 diode de protecţie, una între pin şi Vcc şi alta între pin şi GND. Diodele de protecţie sunt pentru cazul în care pe pin ajunge din exterior o tensiune mai mare decât Vcc sau mai mică decât GND. Foarte important este ca prin diodele de protecţie să nu treacă un curent mai mare de 2 mA, ca să nu le arzi. Încă o observaţie importantă. Spre deosebire de alte MCU-uri care merg până 5-6V, MSP430 suportă maxim 3.6V. Tot LaunchPad-ul se alimentează din USB la 5V, dar apoi urmează un stabilizator care reduce tensiunea la 3.3V. MCU-ul este alimentat la 3.3V, NU direct la 5V. Pentru o matrice de LED-uri ar fi bine să pui pe ieşiri tranzistoare sau integrate care garantează curenţi mai mari. Dacă vrei să reduci cu orice preţ numărul de componente, ar mai fi o soluţie software. Aprinzi cele 35 de LED-uri pe rând, multiplexat. Asta se poate numai dacă faci matricea din LED-uri separate. Ca să nu observi pâlpâitul LED-urilor, frecvenţa de refresh trebuie să fie destul de mare. Link spre comentariu
adyyo Postat Mai 16, 2012 Autor Partajează Postat Mai 16, 2012 http://www.best-microcontroller-project ... isplay.pdf Eu ma gandeam sa fac ca in schema asta, doar ca in locul rezistoarelor de 470 sa pun de 300 de ohmi. Daca fac in felul asta, voi aprinde cate o line de LED-uri la un moment dat. Scanare verticala parca se numeste, iar coloanele vor fi selectate de numaratorul 4017. Deci ar fi bine sa pun si in partea cu rezistente un ULN PNP? Link spre comentariu
adyyo Postat Mai 16, 2012 Autor Partajează Postat Mai 16, 2012 De fapt varianta PNP se numeste UDN2580 din ce am gasit pe gogu. Sper sa-l gasesc in magazine. Link spre comentariu
Vizitator Postat Mai 18, 2012 Partajează Postat Mai 18, 2012 ... Tot LaunchPad-ul se alimentează din USB la 5V, dar apoi urmează un stabilizator care reduce tensiunea la 3.3V. MCU-ul este alimentat la 3.3V, NU direct la 5V. ... Am măsurat şi m-am uitat şi în schemă, stabilizatorul e de 3.6V, nu de 3.3V. Deci, MCU-ul este alimentat la 3.6V. 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