adyyo Postat Iunie 9, 2012 Autor Partajează Postat Iunie 9, 2012 Incepe sa ma depaseasca problema 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
Vizitator Postat Iunie 9, 2012 Partajează Postat Iunie 9, 2012 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
adyyo Postat Iunie 9, 2012 Autor Partajează Postat Iunie 9, 2012 Cred ca am prins ideea de ansamblu. Sa vad daca reusesc sa scriu ceva in noaptea asta. Revin cu un filmulet. Multumesc pentru exemplu. Link spre comentariu
Vizitator Postat Iunie 9, 2012 Partajează Postat Iunie 9, 2012 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
adyyo Postat Iunie 10, 2012 Autor Partajează Postat Iunie 10, 2012 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
Liviu M Postat Iunie 10, 2012 Partajează Postat Iunie 10, 2012 Iti lipseste o acolada (}) pentru for(;;). De-aia e bine sa le comentezi, sa stii cui apartin. In cazul asta } // for(;;) Link spre comentariu
adyyo Postat Iunie 10, 2012 Autor Partajează Postat Iunie 10, 2012 Am vazut-o! Tui mama ei de acolada. Multumesc de ajutor. Link spre comentariu
Liviu M Postat Iunie 10, 2012 Partajează Postat Iunie 10, 2012 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
Vizitator Postat Iunie 10, 2012 Partajează Postat Iunie 10, 2012 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 binePe 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 întrerupereTe 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
adyyo Postat Iunie 10, 2012 Autor Partajează Postat Iunie 10, 2012 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
adyyo Postat Iunie 10, 2012 Autor Partajează Postat Iunie 10, 2012 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... Link spre comentariu
adyyo Postat Iunie 11, 2012 Autor Partajează Postat Iunie 11, 2012 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 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
picolo Postat Iunie 11, 2012 Partajează Postat Iunie 11, 2012 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
Liviu M Postat Iunie 11, 2012 Partajează Postat Iunie 11, 2012 He, he, picolo strikes again (posturi pline de "substanta" da' fara nici o utilitate). 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
Vizitator Postat Iunie 11, 2012 Partajează Postat Iunie 11, 2012 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
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