Sari la conținut
ELFORUM - Forumul electronistilor

Putin ajutor cu Texas Instruments Lounchpad


adyyo

Postări Recomandate

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
  • Răspunsuri 155
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • adyyo

    64

  • Liviu M

    31

  • picolo

    4

  • MifTy

    1

Top autori în acest subiect

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

Acum codul tau arata ca al unui adevarat profesionist! :aplauze

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

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. :jytuiyu

LE Da' ca sa nu zici ca n-am si eu ceva de comentat, ai mancat o litera indentare :limb:

 

Cat despre scris, pe scurt tu scrie :aplauze ca ne descurcam noi cu cititul. Daca nu, mai intrebam/te provocam cu nestiinta noastra. :rade:

Link spre comentariu

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 :limb:

...

Eram convins că e identare dar greşeam. Corect e indentare.

Mulţumesc pentru observaţie.

Link spre comentariu

Acum codul tau arata ca al unui adevarat profesionist! :aplauze

Prea profesionist pentru gustul meu. :rade: 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 :rade: ).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

Si ca o concluzie la ce am invatat azi, de fapt ieri :rade: , 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

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

Am inteles. Inca nu mi-a intrat in reflex sa pun acolade peste tot...ori uit sa le inchid, ori uit sa le deschid. :jytuiyu Mai am de scris vreo cateva milioane de randuri de cod pana sa fac totul calumea. :rade: 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

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

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

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

...

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

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 cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări