ovy_pas Postat August 26, 2011 Autor Partajează Postat August 26, 2011 void interrupt() {if (T0IF_bit) {cnt++; // increment counterT0IF_bit = 0; // clear TMR0IFTMR0 = 96;} //}void main() {if (cnt>=400) RC7_Bit = RC0_Bit; //Daca introduc acest cod aici functia delay 500ms influienteaza executia programului?Delay_ms(500);} Link spre comentariu
Liviu M Postat August 26, 2011 Partajează Postat August 26, 2011 Explica mai bine ce te astepti/ai vrea sa se intample si incercam impreuna sa vedem daca are sanse sa mearga sau nu. Pentru ca una e sa ai un timing strans si sa vrei sa detectezi exact cnt==400 si alta sa ai un timing lejer si sa te intereseze o actiune candva dupa ce cnt depaseste 400 (pentru ca eu as zice ca prima varianta e mai greu de facut, la a doua nefiind nici o problema).Si da si ceva mai multe detalii (ce fel de variabila e cnt, ce frecventa de ceas folosesti, eventuala bucla infinita din main...) Link spre comentariu
ovy_pas Postat Decembrie 7, 2011 Autor Partajează Postat Decembrie 7, 2011 De exemplu vreau sa fac un Sinusoidal PWM, frecventa PWM 5kHz, frecventa sinusoidei 50Hz, lucrez cu 16f870 quartz 20Mhz, in C, folosesc intreruperi.Sunt dezamagit de performantele microcontrolerului ii trebuie aproape 2ms sa calculeze cu functia sinus (la adunari si inmultiri se misca mai binisor) cand ar trebui calculata o data la 1/5kHz = 0.2ms depaseste cu mult.Am zis sa creez un array de int [100] in care sa introduc valorile gata calculate ale functiei sin in 100 puncte ca sa nu-l obosesc cu calculele numai sa ii fac o atribuire care nu ia mult timp, dar ce credeti ... RAM INSUFICIENT , 6 int, 3biti, si un array int[100] si nu mai poate saracul. De afisat pe LCD nici macar 2 cuvinte intregi nu poate i se termina RAM-ulIn data sheet scrie ca are 128 x 8 byte, si in program imi arata RAM maxim 112 byte adica 112 x 8 biti nu byteVa rog daca imi puteti recomanda metode pentru optimizare cod pentru marire viteza de calcul daca exista. Se poate creste quartz ul poate lucra la frecvente mai mari? Sau alt microprocesor cu RAM si viteza de calcul, chiar si avr. Link spre comentariu
Liviu M Postat Decembrie 8, 2011 Partajează Postat Decembrie 8, 2011 Daca lucrezi ci compilatorul de la hitech/usoft, variabilele int sunt pe 16 biti (cel putin asa tin eu minte). Asta inseamna ca tu umpli RAMul numai cu arrayul ala cu 100 de variabile int. Chiar ai nevoie de int? Eu as incerca cu unsigned char. Da, de obicei la nivelul asta de "putere de calcul" se folosesc tabele cu valorile , nu se calculeaza "real time", ca ai vazut si singur ce iese. Iar aia 128x8 bytes cred ca sunt 128 de bytes "salvati" pe cate 8 biti (asta daca vrei cumva sa-i adresezi direct). Da' asta e numai o banuiala. Si ca sa evit remarcile binevoitoare ale lui picolo, mentionez ca prin cei 8 biti de mai sus ma refer la structura interna a memoriei (care poate avea registri mai lungi sau mai scurti), nu la faptul ca octetii aia au mai mult de 8 biti. Link spre comentariu
Elef Postat Decembrie 8, 2011 Partajează Postat Decembrie 8, 2011 Am zis sa creez un array de int [100] in care sa introduc valorile gata calculate ale functiei sin in 100 puncte ca sa nu-l obosesc cu calculele numai sa ii fac o atribuire care nu ia mult timp, dar ce credeti ... RAM INSUFICIENT , 6 int, 3biti, si un array int[100] si nu mai poate saracul. De afisat pe LCD nici macar 2 cuvinte intregi nu poate i se termina RAM-ulIn data sheet scrie ca are 128 x 8 byte, si in program imi arata RAM maxim 112 byte adica 112 x 8 biti nu bytePrimo un byte are intotdeauna 8 biti.Hai sa facem un mic calcul: zici un array de 100 int asta inseamna 200 byte ( am presupus ca int-ul e reprezentat de pe 2 bytes) plus inca 6 int adica 12 bytes plus inca 1 byte de la cele 3 variabile pe 1 bit.Asta ar veni cam 213 bytes.Are saracu dreptate sa planga ca nu are memorie.In privinta faptului ca vezi mai putin RAM decat scrie in datasheet as zice ca compilatorul de C deja a alocat o parte din ei( de exemplu salvarea stack-ului si pc-ului la intrarea in intrerupere ). Link spre comentariu
Elef Postat Decembrie 8, 2011 Partajează Postat Decembrie 8, 2011 Revin cu niste mici lamuri(n-am apucat de la munca):In catalog specifica si lungimea word-ului sau byte-ului.Astfel o instructiune este codata pe un word de 14 biti, iar ram-ul este pe 8 biti adica un byte.Din nefericire 16f870 are doar 128bytes RAM. As zice ca ai putea sa faci un pas inainte trecand la 18f( RAM mai mult, flash mai mare plus cateva instructiuni in plus- chiar si o inmultir pe byte) Link spre comentariu
ovy_pas Postat Decembrie 8, 2011 Autor Partajează Postat Decembrie 8, 2011 L-am pacalit ii pap din memoria ROM am declarat o constanta de tip aray [100] in loc de variabila int [100], si ca sa fie economia si mai mare cum zicea Liviu o declar unsigned short [100] (care are 8biti nu 16 ca int)Multumesc Elef, calculele tale sunt corecte, asa este.Daca se creste quartz-ul, poate lucra la frecvente mai mari de 20Mhz pentru a obtine viteze mai mari de calcul? Am citit pe net cum ca AVR ar fi mai rapide la acelasi quartz de 20Mhz. 18f are aceasi viteza ca si 16f asa este?Nu imi place sa fac risipa de resurse dar nici sa intind codul la limita si sa inceapa sa planga cum fac o mica adunare in plus, sau vreau sa mai afisez o litera , e frustrant. Cred ca tre sa fac un pasul spre 18f.A si inca o un fenomen la redeschidere nu raman intodeauna valorile remanente, trebuie sa le readuc la valorile de dinainte, ar putea fi de la alimentarea uC? Link spre comentariu
Liviu M Postat Decembrie 9, 2011 Partajează Postat Decembrie 9, 2011 Am mai auzit si eu de overclocking la PICuri/Atmeluri. E ca la PC-uri uneori merge, da' nu e garantat.N-am incercat niciodata, da' seria 18F are un mod PLL (parca) in care din frecventa de max 10MHz a oscilatorului extern genereaza frecventa de ceas de pana la 40MHz. Scrie in DataSheeturi mai multe N-am inteles faza cu redeschiderea. Redeschiderea cui? Link spre comentariu
Elef Postat Decembrie 9, 2011 Partajează Postat Decembrie 9, 2011 N-am incercat niciodata, da' seria 18F are un mod PLL (parca) in care din frecventa de max 10MHz a oscilatorului extern genereaza frecventa de ceas de pana la 40MHz.Chiar asa este.Am folosit un 18f4620 la vreo 33MHz in felul asta. Link spre comentariu
ovy_pas Postat Decembrie 10, 2011 Autor Partajează Postat Decembrie 10, 2011 "N-am inteles faza cu redeschiderea. Redeschiderea cui? "Dupa ce deconectez si realimentez aplicatia . Alimentare realizata cu transformator, redresare, filtrare, si stabilizator 5V (7805). Deconectarea o fac din buton de la 220 inainte de transformator.Am cativa parametrii care doresc sa ramana memorati si sa nu trebuiasca sa ii reintroduc din nou la fiecare deschidere a aplicatiei. La redeschidere acesti parametrii uneori raman, ... alteori aleatoriu isi pierd valorile anterioare, si pic-ul isi atribuie niste valori ciudate dupa cum vrea el. Restul parametriilor ii initializez inainte de bucla infinita. Link spre comentariu
Liviu M Postat Decembrie 10, 2011 Partajează Postat Decembrie 10, 2011 Eu zic ca daca astepti suficient sa se descarce eventualii condensatori din circuit, variabilele tale vor fi tot timpul ciudat initializate. Ca sa le "regasesti" at trebui sa le salvezi in EEPROM cand le modifici (cred ca ar merge si in memoria FLASH, da' eu nu am folosit-o niciodata, nu stiu exact cum functioneaza) si sa le reincarci la initializare. Pun in continuare niste bucati de cod cu care scriu/citesc in/din EEPROM. Sunt intr-o varianta mai veche de picc (parca picc foloseai si tu), sper sa mearga in continuare. La inceput "definesc" zonele de memorie folosite si le initializez ca sa nu primesc ciudatenii la prima punere in functiune. __EEPROM_DATA(2, 190, 2, 186, I2C_ADDR, 9, 0, 4); /*40..43 - pH limits, 44 - adresa senzorului conectat pe i2c, 45= ora La initializare, citesc datele respective in variabilele "de lucru": ucComBuf[8] = eeprom_read(ucEePhAddress); // = nivel sus pH Byte H; De cate ori modific valoarea respectiva, o salvez in EEPROM ucComBuf[8] = (usPhTinta + 2) / 256; /* /256 == deplasare la dreapta cu 8 pozitii (256=2^8)*/eeprom_write(ucEePhAddress,ucComBuf[8]); /*salveaza tinta de pH in EEPROM si refoloseste-o dupa reset*/ Link spre comentariu
ovy_pas Postat Decembrie 13, 2011 Autor Partajează Postat Decembrie 13, 2011 "Da, de obicei la nivelul asta de "putere de calcul" se folosesc tabele cu valorile , nu se calculeaza "real time", ca ai vazut si singur ce iese."nu se poate calcula cu nici un pic in timp real? cu tabele de valori scriu o groaza de cod si nu asta ar fi problema dar ma limiteaza ca nu pot varia mult frecventa sinusoidei sau mai deloc deoarece imi iau valorile din tabel.Pic 32 am vazut ca lureaza la 80 Mhz poate mi ar fi de folos. Link spre comentariu
Liviu M Postat Decembrie 13, 2011 Partajează Postat Decembrie 13, 2011 Ba eu as fi zis ca frecventa se modifica daca modifici "viteza cu care citesti valorile".Nu stiu exact cum faci tu, iar eu doar am vazut la un coleg o "demonstratie", da' el reusea sa schimbe si frecventa modificand mai repede sau mai lent valoarea PWM-ului. Link spre comentariu
ovy_pas Postat Decembrie 15, 2011 Autor Partajează Postat Decembrie 15, 2011 Perioada intreruperii = 4*Precaler*(256 - TMR0) / Fosc;daca modific TMR0 se modifica frecventa intreruperilor deci si viteza cu care citesc valorile.Dar si asa, imi ia 30us sa preiau valorile si sa le compar.O intrerupere trebuie realizata la cel putin 60us ca sa pot sa rulez si ceva cod din menu.un esantion are 20 de intreruperi , la fiecare intrerupere incrementeaza un cnt 0-2060us x 20 =1200us =1.2msla 10 esantioane am perioada sinusoidei: 1.2ms x10 =12 msfrecventa maxima a sinusoidei 1/12ms =83.33 HzAm o rezolutie proasta la PWM (0-20 in loc de 100 cat doream) si 10 esantoane (in loc de 100 cat doream) .Doar atat se poate? Sau nu folosesc cea mai buna modalitate de a programa? Link spre comentariu
Liviu M Postat Decembrie 15, 2011 Partajează Postat Decembrie 15, 2011 Sorry, nu reusesc sa-ti urmaresc prea bine rationamentul (cred ca-s cam obosit, poate ar fi bine sa nu mai scriu, da' n-ar avea farmec), asa ca incerc sa-ti povestesc cum vdeam eu rezolvarea, pornind de la sinusoida in 100 de puncte si cei 50 Hz ai tai. Perioada semnalului e 20ms => 20 000 us.La un ceas de 20MHz, asta inseaman 20 000 instructiuni. Impartind cele 20 ms = 20 000 us la 100 de puncte ale sinusoidei, => ai nevoie de un timer care sa genereze intreruperi la fiecare 200 us (TMR0 "incarcat" cu ~56). La fiecare intrerupere, iei valoarea urmatoare din memorie si o incarci in modului PWM.Daca vrei sa variezi frecventa (in jos e simplu, da' nu vad de ce ai face-o), faci timerul mai rapid. Tu zici ca 60us intre 2 intreruperi ti-ar ajunge. Asta inseamna o frecventa cam de 3 ori mai mare decat cei 50Hz (deci cam 150Hz). Hm, cam putin, trebuie sa-mi trag colegul de limba, sa vad cum a facut, ca el parca se juca cu ceva mai multi herzi. 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