Sari la conținut
ELFORUM - Forumul electronistilor

Putin ajutor cu Texas Instruments Lounchpad


adyyo

Postări Recomandate

Incepe sa ma depaseasca problema :jytuiyu Deci

Ca să ţii minte la ce coloană ai rămas cu afişarea, declară o variabilă de tip static în interiorul funcţiei de întrerupere.

Nu inteleg cum anume imi va arata variabila de tip static la ce coloana am ramas. Ar trebui de exemplu sa declar "static col;" iar in functia de intrerupere sa scriu "col++;" ?

Ca să ştii ce LED-uri trebuie aprinse, declari o matrice de numere. Fiecare număr va reprezenta o coloană. Ultimii biţi din fiecare număr al matriciei vor reprezenta starea unui LED, fiecare LED cu bitul lui.

De exemplu vreau sa scriu A si presupunem ca am legat 5 LED-uri pe bitii de la 0 la 4. Matricea va trebui sa arate astfel?
int A[5]={0xf,0x14,0x14,0x14,0xf};
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

Doar pare complicat, dar nu este. Le luăm pe rând.

Şi întreruperile păreau complicate, dar până la urmă le-ai descurcat singur.

 

...#define RST  BIT5#define CLK  BIT4...char display_buffer[5]; //câte un byte (1 char = 1 byte = 8 biţi = 8 LED-uri) pentru fiecare coloanăconst LITERA_A[5] = {0x3C,    //00111100                     0x42,    //01000010                     0x7E,    //01111110                     0x42,    //01000010                     0x42};   //01000010const LITERA_B[5] = ... ;...void main(void) {...   for(;;) { //buclă infinită main      //scrie un A      for (i = 0; i < 5 ; i++)         display_buffer[i] = LITERA_A[i];  //încarcă litera în bufferul care va fi afişat pe LED-uri      _delay_cycles(1000000); //pauză 1 secundă (am lăsat ceasul implicit, la 1 MHz)      for (n = 0; n < 8ş n++) { //pentru fiecare bit din coloană         //roteşte biţii din bufferul de afişare         for (i = 0; i < 5 ; i++) //pentru fiecare rând            display_buffer[i] << 1; //roteşte      }      _delay_cycles(200000); pauză 0.2 secunde înainte de a roti cu încă un pas   }}void pulseP2(int bit) {   P2OUT |= bit;   P2OUT &= ~bit;}#pragma vector = WDT_VECTOR__interrupt void Watchdog_Timer(void)//------------------------------------------------------------------------------// Watchdog Timer interrupt service routine//------------------------------------------------------------------------------{   static int col;   //trece la coloana următoare   col++;   if (col > COL_MAXIMA) {      col = 0;      pulseP2(RST); //P2 pentru că m-am luat după schemă, am văzut în codul tău că foloseşti P1   }   else {      pulseP2(CLK);   }   //afişează pe LED-uri coloana desenată în buffer   P1OUT = display_buffer[col]; //am presupus că toate coloanele sunt legate la rând pe portul P1, tu le-ai legat altfel în schemă}
Calificativul static se foloseşte ca funcţia să nu uite la ce coloană rămăsese cu afişarea.

La fel de bine poţi folosi o variabilă globală, adică declari variabila col înainte de main().

 

Pentru compilator, static înseamnă de fapt o variabilă globală. Singura diferenţă este că variabila globală este accesibilă de oriunde din program, pe când cea de tip static este accesibilă doar în blocul unde a fost declarată, adică în interiorul funcţiei de tratare a întreruperii.

Link spre comentariu

Perfect, vezi ce-ţi iese.P.S.Am modificat programul de mai sus. Acum scrie litera şi apoi o roteşte spre stânga. Nu am avut cum să-l testez, ar putea avea greşeli, dar ideea generală trebuie să meargă.

Link spre comentariu

Nu reusesc sa scap de 2 erori. Am scris si rescris programul si l-am verificat, dar tot nu reusesc sa imi dau seama de unde vin erorile. In dreptul #pragma vector imi apare.

//-----Matrice LED 5x8, v1.2-----#include "msp430g2553.h"#define UART_RXD   BIT2            // RxD is on P1.2#define RST  BIT5#define CLK  BIT4int i;int n;int COL_MAX;char display_buffer[5]; //---Tabelele de caractere---const int LITERA_A[5] = {0x1F,					 	 0x24,					 	 0x24,					 	 0x24,					 	 0x1F};void main(void){   WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer   WDTCTL = WDT_MDLY_32; // Start Watchdog Timer (interval is ~30ms)   IE1 |= WDTIE; // Enable WDT+ interrupts   P2DIR = 0x3F; // setez toti biti lui P2 ca iesiri   P1DIR = RST | CLK;   __enable_interrupt();  // Enable interrupts (global)   for(;;)   {      for (i = 0; i < 5 ; i++)         {    	  display_buffer[i] = LITERA_A[i];  //încarca litera in bufferul care va fi afisat pe LED-uri         _delay_cycles(1000000);           for (n = 0 ; n < 6 ; n++) //pentru fiecare bit din coloana roteste bitii din bufferul de afisare           	   {        	     for (i = 0; i < 5 ; i++) //pentru fiecare rand                 display_buffer[i] << 1; //roteste biti           	   } //for (n = 0 ; n < 6 ; n++)           _delay_cycles(200000);         } //for (i = 0; i < 5 ; i++)   } //for(;;)} //main#pragma vector = WDT_VECTOR__interrupt void Watchdog_Timer(void){   static int col;   col++;   COL_MAX = 5;   if (col > COL_MAX)   {      col = 0;      P1OUT |= RST;      P1OUT &= ~RST;   } //if (col > COL_MAX)   else   {	   P1OUT |= CLK;	   P1OUT &= ~CLK;   } //else   //afiseaza pe LED-uri coloana desenata in buffer   P2OUT = display_buffer[col];} //interrupt
Link spre comentariu

Cand ai erori, incearca sa citesti cu atentie mesajele si sa te prinzi ce vor de la tine. In cazul de fata, al doilea zicea ceva legat de acolade inchise, asa ca le-am verificat pe astea si am gasit eroarea imediat.

Link spre comentariu

N-am vrut să te plictisesc prea mult cu sfaturi, dar există unele practici pe care, dacă le respecţi, vei avea spor la programat.

 

1. Nu programa noaptea, sau când eşti nedormit. Fă-o ziua, când ai mintea limpede. Nu-mi spune că tu lucrezi mai bine noaptea, cunosc textul. Şi eu pretindeam la fel la începuturi. Nu este adevărat. Dacă vrei performanţă, noaptea dormi, iar ziua lucrezi. Dacă insişti să programezi noaptea, treaba ta, dar vei fi ineficient.

 

2. Nu sări direct la tastatură. Înainte să butonezi, fă programul pe o foaie de hârtie, cu algoritmul schiţat, apoi cu linii de cod, cu ştersături sau adăugiri (nu contează să fie impecabil pe hârtie). Uneori e util să mai desenezi celule de memorie, structuri, grafice sau alte prostii. Pe urmă copiezi codul în calculator. Iarăşi, sunt excluse orice scuze de genul "era simplu" sau "eu pot direct pe calculator". Toată lumea poate, doar că o face cu o eficienţă mai mică, neprofesional. Atunci când scrii pe hârtie, angajezi mai mulţi centri nervoşi în acţiunea pe care o faci. Cu timpul, asta te transformă în bine, deprinzi un alt fel de a gândi. Când copiezi în calculator algoritmul de pe foaie, mai treci fără să vrei prin ce ai făcut şi cu ocazia asta, observi eventualele greşeli sau modalităţi de optimizare.

 

Au fost mai multe studii psihologice care au demonstrat asta. Chiar aşa e, nu te împotrivi. Nu are rost să înoţi împotriva curentului, pentru că oboseşti degeaba.

 

3. Ca să nu uiţi acoladele, cel mai bine e să fii ordonat, să-ţi alegi un anumit stil şi să te ţii de el. Oricum ai face tot vor mai fi scăpări. Ca să le depanezi, te ajută editorul:

- Dacă dai click lângă o paranteză sau o acoladă, editorul îţi desenează automat un chenar la perechea ei.

- Dacă dai dublu click lângă o paranteză sau acoladă, editorul selectează automat tot blocul până la perechea ei.Asta e foarte util pentru împerecherea corectă a acoladelor şi/sau a parantezelor.

 

P.S. Sunt în viteză, nu m-am uitat atent peste programul tău. Mi-a sărit în ochi un

int COL_MAX; //declaraţie de _variabilă_ globală care nu se modifică, asta nu e bine
Pe urmă, o iniţializezi la fiecare intrare în funcţia de tratare a întreruperii

COL_MAX = 5; //faci risipă de cicli de execuţie şi de RAM
Nu are rost să o iniţializezi mereu, pentru că nu se schimbă niciodată.

 

 

Normal se face aşa:

#define COL_MAX  5 //Asta înseamnă că ai definit o constantă, nu consumi RAM, nici nu pierzi timp să o iniţializezi la fiecare întrerupere
Te rog să nu te superi că mă iau de toate amănuntele, dar e important să-ţi faci deprinderi corecte încă de la început.

Să scrie cod, poate oricine. Să scrie bine, mai puţini.

 

Încă ceva şi gata. Întreruperile trebuie să fie cît mai scurte, pentru că în timpul lor procesorul nu mai face altceva. Am observat că ai renunţat la funcţia pulseP2(). Aici e de discutat. Dacă compilatorul e mai slab în materie de optimizări, e bine cum ai făcut tu, cu cele două instrucţiuni în loc de pulseP2(). Dacă ai un compilator bun, care ştie să bage funcţii inline în loc să le apeleze cu call, atunci folosirea lui pulseP2() face programul mai uşor de citit şi de înţeles. Nu am verificat dacă la optimizare, CSS (de fapt compilatorul este GCC) ştie să insereze inline funcţiile simple (ca pe macro-uri).

 

Lăsând deoparte toate comentariile, n-am înţeles, pănă la urmă a mers programul?

Link spre comentariu

Sub nici o forma nu ma supar. Avand in vedere ca sunt incepator si vreau sa invat cat mai bine, nu pentru a castiga ceva material din asta, ci doar pentru simplul fapt ca imi place enorm sa vad functionand un lucru facut de mana mea, in cazul de fata scris, accept orice indicatie, sfat sau mustrare atunci cand gresesc. Doar asa se poate invata. Buna ideea legata de schema pe foaie. Am sa incep sa o aplic si eu, chiar simt uneori ca pierd randul programului si uit acoladele. Desigur, incerc sa nu programez noaptea, dar inca sunt cuprins de nerabdarea si de elanul de inceput si nu am rabdare. Acum legat de program, in principiu merge. Imi afiseaza litera A. Problema e ca nu invarte bitii. Aztazi nu am mai apucat, dar maine vreau sa analizez mai bine si sa vad exact care e problema. Am o banuiala da vreau intai sa verific, sa nu plictisesc cu intrbarile de novice. Ca o concluzie, nu ma supar daca ma "plictisesti" cu indicatii si explicatii detaliate, chiar te rog sa faci asta ori de cate ori ai timp si chef sa ma ajuti. A si inca un mic detaliu, sper ca nu te deranjeaja ca ma exprim la pertu. Stiu ca e diferenta mare de varsta intre noi si de aceea daca te deranjeaza, te rog sa mentionezi.

Link spre comentariu

Si ca o dovada ca nu e rentabil si eficient sa programezi noaptea... Aseara la ora 3, dupa vreo doua beri savurate mai devreme, nu reuseam sa imi dau seama de ce nu mi se aprindea nici un LED... Azi dimineata, dupa ce am trecut odata prin program, am observat ca gresisem codul hexa pentru setarea bitilor ca iesiri pe P2... :sparge:

Link spre comentariu

Am impresia ca placuta asta isi bate joc de mine... Deci...in primul rand am scos jumperii de pe TxD si RxD, placuta fiind nealimentata. Am alimentat, am pornit CCS, am dat debug...si imi afiseaza A. Nu, vrea sa schimbe btii. Bon...am deconectat tot, am pus inapoi cei doi jumperi si cand alimentez, surpriza, LED-urile se aprindeau haotic. Deconectez din nou, scot iar jumperii, la reconectare nici o schimbare, tot haotic se aprind. In tot timpul asta, in dreptul instructiunii "display_buffer << 1;" compilatorul zice ca instruction has no effect, dar e doar avertizare...Ma scoate la pensie programul asta :sparge:

Pe de alta parte, ce face RxD si TxD si de ce s-a schimbat ceea ce afiseaza in momentul in care am pus inapoi jumperii?

 

//-----Matrice LED 5x8, v1.2-----#include "msp430g2553.h"#define UART_RXD   BIT2            // RxD is on P1.2#define RST  BIT5#define CLK  BIT4#define COL_MAX  5int i;int n;char display_buffer[5]; //---Tabelele de caractere---const int LITERA_A[5] = {0x1C,                    	 0x22,                    	 0x3E,                    	 0x22,                    	 0x22};void pulseP1(int bit){   P1OUT |= bit;   P1OUT &= ~bit;}void main(void){   WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer   WDTCTL = WDT_MDLY_0_5; // Start Watchdog Timer (interval is ~0.5ms)   IE1 |= WDTIE; // Enable WDT+ interrupts   P2DIR = 0x3F; // setez toti biti lui P2 ca iesiri   P1DIR = RST | CLK;   __enable_interrupt();  // Enable interrupts (global)   for(;;)   {      for (i = 0; i < 5 ; i++)         {         display_buffer[i] = LITERA_A[i];  //încarca litera in bufferul care va fi afisat pe LED-uri        _delay_cycles(1000000);        	 for (n = 0; n < 6 ; n++) //pentru fiecare bit din coloana roteste bitii        	 	  {        	 	  for (i = 0 ; i < 5 ; i++) //pentru fiecare rand        	 	  display_buffer[i] << 1; //roteste                  } //for (n = 0 ; n < 5 ; n++)          } //for (n = 0 ; n < 5 ; n++)   } //for(;;)} //main#pragma vector = WDT_VECTOR__interrupt void Watchdog_Timer(void){   static int col;   col++;   if (col > COL_MAX)   {      col = 0;      pulseP1(RST);   } //if (col > COL_MAX)   else   {	   pulseP1(CLK);   } //else   //afiseaza pe LED-uri coloana desenata in buffer   P2OUT = display_buffer[col];} //interrupt
Link spre comentariu
N-am vrut să te plictisesc prea mult cu sfaturi, dar există unele practici pe care, dacă le respecţi, vei avea spor la programat.

 

1. Nu programa noaptea, sau când eşti nedormit. Fă-o ziua, când ai mintea limpede. Nu-mi spune că tu lucrezi mai bine noaptea, cunosc textul. Şi eu pretindeam la fel la începuturi. Nu este adevărat. Dacă vrei performanţă, noaptea dormi, iar ziua lucrezi. Dacă insişti să programezi noaptea, treaba ta, dar vei fi ineficient.

 

2. Nu sări direct la tastatură. Înainte să butonezi, fă programul pe o foaie de hârtie, cu algoritmul schiţat, apoi cu linii de cod, cu ştersături sau adăugiri (nu contează să fie impecabil pe hârtie). Uneori e util să mai desenezi celule de memorie, structuri, grafice sau alte prostii. Pe urmă copiezi codul în calculator. Iarăşi, sunt excluse orice scuze de genul "era simplu" sau "eu pot direct pe calculator". Toată lumea poate, doar că o face cu o eficienţă mai mică, neprofesional. Atunci când scrii pe hârtie, angajezi mai mulţi centri nervoşi în acţiunea pe care o faci. Cu timpul, asta te transformă în bine, deprinzi un alt fel de a gândi. Când copiezi în calculator algoritmul de pe foaie, mai treci fără să vrei prin ce ai făcut şi cu ocazia asta, observi eventualele greşeli sau modalităţi de optimizare.

 

Au fost mai multe studii psihologice care au demonstrat asta. Chiar aşa e, nu te împotrivi. Nu are rost să înoţi împotriva curentului, pentru că oboseşti degeaba.

 

3. Ca să nu uiţi acoladele, cel mai bine e să fii ordonat, să-ţi alegi un anumit stil şi să te ţii de el. Oricum ai face tot vor mai fi scăpări. Ca să le depanezi, te ajută editorul:

- Dacă dai click lângă o paranteză sau o acoladă, editorul îţi desenează automat un chenar la perechea ei.

- Dacă dai dublu click lângă o paranteză sau acoladă, editorul selectează automat tot blocul până la perechea ei.Asta e foarte util pentru împerecherea corectă a acoladelor şi/sau a parantezelor.

 

 

Ai scris cele trei puncte ca si cum ar forma un fel de biblie a programatorului.

Daca adaugai ca este doar parerea ta, nu ma apucam sa scriu ca ceeace ai afirmat

la pct.1 si 2 este fals ca si sfat.

 

Nu stiu ce "studii psihologice" ai parcurs, dar eu zic ca trebuie lasat

creierul sa dicteze cand vrea sa se joace de-a programarea.

 

Ce am scris mai sus se aplica in cazul in care nu esti angajat sa programezi

pentru a avea bani de tigari, bere sau femei.

 

Va urez eficienta la programare.

Link spre comentariu

He, he, picolo strikes again (posturi pline de "substanta" da' fara nici o utilitate). :rade:

 

Nu reusesc sa scap de 2 erori.

1. Operatia de shiftare n-are efect pentru ca nu "salvezi" rezultatul nicaieri (lipseste =):

 

                 display_buffer[i] <<= 1; //roteste biti /*******  aici iti lipseste = ****/
2. Nu sunt sigur ca 2 for-uri unul in altul folosind acelasi index (i) functioneaza corect.
Link spre comentariu

Iar dau rasol, că e târziu. Promit să revin. Acum am citit doar "pe diagonală".

 

Din ce ştiu eu, pe Internet nu se obişnuieşte folosirea pronumelui personal de politeţe, nici adresarea la plural. Ar fi chiar deplasat să ne "domnim" pe ElForum. Aici, altul e scopul discuţiilor.

 

Cele 3 puncte numerotate cu roşu sunt recomandări, nimic altceva. Fiecare face cum vrea.

 

Într-adevăr, rotirea nu salva rezultatul pentru că am mâncat egalul. Vroiam să rotesc tot buffer-ul, adică pentru fiecare i

display_buffer = display_buffer << 1;

sau, scris prescurtat,

display_buffer <<= 1;

 

După cum zicea şi compilatorul,

display_buffer << 1;

Nu e bun al nimic.

Mea culpa. Cred că am şi spus că am scris după ureche, direct pe ElForum şi netestat.

 

Două bucle una în alta (adică imbricate) şi care folosesc aceeaşi variabilă "i", sigur nu merg cum trebuie, ca şi cum ar avea variabile diferite în loc de acelaşi "i".

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