mircang9 Postat Februarie 27, 2012 Autor Partajează Postat Februarie 27, 2012 Buna treaba !!! Eu lucrez cu 16 MHz quartz extern. Cred ca un quartz de 4 MHz e mai recomandatpentru ca ofera cred o stabilitate mai mare. Nu mai trebuie prescalat.Vorbesc de PIC18F cu care lucrez. Dar vad ce mai pot face. Mi-a iesitmodularea si sinusoida e cu 21 valori pe perioada.Tabelul folosit este: const int sintable[21] = {0,14,28,56,99,141,196,225,241,255,255,241,225,196,141,99,56,28,14,0,0};O sa mai periez empiric aceste valori cu Excel si cu foaia de matematica pentrua iesi sinusoida cat mai frumoasa. Maine o sa pun esantionarea la 16 KHz.Tabela de mai sus e la 8 KHz. Link spre comentariu
mircang9 Postat Februarie 27, 2012 Autor Partajează Postat Februarie 27, 2012 Am gasit formula de care ziceam si acum nu mai e nevoie de calcule empirice.Formula este: 128*sin(x)+128. Se calculeaza portiunea functiei sin(x)intre 3*pi/2 si 5*pi/2. Diferenta este pi = 3.14. Se impartea frecventa de esantionare dorita. De exemplu pentru canal 1 cu Fc = 420 Hz, F1 = 390 Hz,F2 = 450 Hz se imparte frecventa de esantionare Fs/Fc adica 8 KHz/420 Hz = 19.Fs/F1 = 20. Fs/F2 = 17. Se ia N = 20 esantioane pentru o perioada.Se imparte 3,14/(N/2) si se incrementeaza la 3*pi/2 = 4.71 pana la N/2 = 10 valori.Portiunea calculata este pentru o semiperioada adica N/2 = 10.Atasez fisierul excel. Asa se poate extinde si la frecvente de esantionare mai mari.Din fisierul excel se deduce tabelul:const int sintable[19] = {0,6,24,52,88,128,167,203,231,250,250,231,203,167,128,88,52,24,6};A doua jumatate adica semiperioada a 2-a este oglindita fata de prima semiperioada. Link spre comentariu
10vid Postat Februarie 27, 2012 Partajează Postat Februarie 27, 2012 Empiric cum? Adica dupa ochi? Uite aici un calculator online pentru tabel SIN: http://stereoping.com/sineValues2.swf Link spre comentariu
mircang9 Postat Februarie 28, 2012 Autor Partajează Postat Februarie 28, 2012 E tare tare !!!! As mai vrea o formula de conversie din decibeli dB in mV pentru semnale. Am un osciloscop pe laptop care arata doar decibeli la amplitudinea semnalului. La o comparatie dintre nivelul citit cu osciloscopul portabil si cel din laptop ar veni cam -6 dB = 70 mV. Dar, stiti cum e, empiric si fara formule e cam aiurea. Impedanta liniei telefonice este 600 ohm. Am gasit un convertor din dB in mV la: http://www.mogami.com/e/cad/db.html Mai e la: http://www.naval.com/help/db-x.htm http://www.jneuhaus.com/volts_to_dBm.html http://www.bcae1.com/decibel.htm Din aceste linkuri => ca: -6dB = 501.2 micro Voltzi ( uV ). Totusi am dubii. Cati mV reprezinta -6 dB la o impedanta de 600 ohm ????? Link spre comentariu
mircang9 Postat Februarie 28, 2012 Autor Partajează Postat Februarie 28, 2012 Cum fac sa compar doi registrii de 8 biti ca unul de 16 biti adica sa-i unesc ? Asa ? void tempo(){ while(TMR1H:TMR1L < 0x02AC) { nop(); } TMR1H:TMR1L = 0x0000;}Timer1 genereaza intrerupere abia dupa ce TMR1L sau/si TMR1H:TMR1L a ajuns la valoarea maxima. Prin functia de mai sus vreau sa fac o temporizare mai fina decat cu intrerupere. Link spre comentariu
mircang9 Postat Februarie 28, 2012 Autor Partajează Postat Februarie 28, 2012 Am pus quartz extern de 8 MHz. C1,2 = 20 pF. Am inteles ca Rs se pune doar rar si trebuie sa fie pana la 40 K. Rfext ajuta la pornirea oscilatorului si trebe sa fie intre 1-5 Mohm dar se foloseste mai mult la rezonatoare ceramice. N-am reusit sa setez o intarziere mai mica de 1us citita pe osciloscop. Am incercat cu intrerupere la Timer1, am incercat cu Timer1 ca si numarator, cu variabila contor dar mai mica de 1us n-am reusit s-o obtin. Nu stiu de ce. Intern am facut sa fie Fosc = 48 MHz. Ar trebui sa obtin cea mai mica intarziere la 0.083us. Iata codul: #include <htc.h>#pragma config PLLDIV = 2 // Fosc extern = 8 MHz. Fosc CPU = 48 MHz. #pragma config CPUDIV = OSC1_PLL2 #pragma config FOSC = HSPLL_HS#pragma config WDT = OFF#pragma config MCLRE = OFF#pragma config PWRT = ON#define nop() asm("nop") int temporizare;int index_sine;void tempo_F1() // temporizare cu variabila contor{ for(temporizare=0;temporizare<1;temporizare++) // 1.6 us lungimea de 1 la RD1 { nop(); }}void tempo() // temporizare cu Timer1 ca numarator{ while(TMR1L<0x01) // 1.080 us lungimea de 1 la RD1 { nop(); } TMR1H = 0x00; TMR1L = 0x00;}void tempo() // temporizare cu intrerupere la Timer1{ temporizare = 0; while(temporizare<5) { while(PIR1bits.TMR1IF==0) { nop(); } PIR1bits.TMR1IF=0; temporizare++; }}void main(){ ADCON1bits.PCFG0 = 1; ADCON1bits.PCFG1 = 1; ADCON1bits.PCFG2 = 1; ADCON1bits.PCFG3 = 1; TRISAbits.TRISA3 = 1; // intrare in CPU din DTM TRISD = 0x00; // iesire din CPU pentru reteaua de rezistente R-2R T1CONbits.RD16 = 0; T1CONbits.T1CKPS1 = 0; T1CONbits.T1CKPS0 = 0; //INTCONbits.GIE = 1; PIE1bits.TMR1IE = 1; PIR1bits.TMR1IF = 0; TMR1H = 0x00; TMR1L = 0x00; T1CONbits.TMR1CS = 0; T1CONbits.TMR1ON = 1; const int sine[90]= {128,137,146,155,164,172,180,188,196,204,211,217,224,229,234,239,243,247,250,252,254,255,255,255,255,253,251,248,245,241,237,232,226,221,214,207,200,192,184,176,168,159,150,141,132,124,115,106,97,88,80,72,64,56,49,42,35,30,24,19,15,11,8,5,3,1,1,1,1,2,4,6,9,13,17,22,27,32,39,45,52,60,68,76,84,92,101,110,119,128}; while(1) { /*for(index_sine=0;index_sine<90;index_sine++) { PORTD = sine[index_sine]; tempo(); }*/ // citire temporizare pe osciloscop la RD1 PORTDbits.RD1 = 0; tempo(); PORTDbits.RD1 = 1; // lungimea de 1 la RD1 ( temporizarea pe osciloscop ) tempo(); } // sfarsit while(1)} // sfarsit main() Astept indicatii. Link spre comentariu
Liviu M Postat Februarie 28, 2012 Partajează Postat Februarie 28, 2012 Hm, nu m-am prins unde apar si cum tratezi tu intreruperile. Nu stiu prea bine cum e cu alte compilatoare, da' picc de la HiTech are o functie speciala pentru tratarea intreruperile, functie care contine interrupt in nume: void interrupt numeFunctie(void){ //tratare intreruperi} Dupa aceea, in functie trebuie pus codul de tratare a intreruperilor in functie de sursa de intreruperi. Timerele genereaza intreruperile la overflow - cand se umplu si trec in 0. Asta inseamna ca pentru a obtine cea mai mica perioada, trebuie sa incarci TMR1H&L sa-ti dea repede pe dinafara. In cazul tau, pentru TMR1 mie.mi iese ceva de genul //undeva ca variabila globala volatile bit bTmr1Int;void main (void){ //tot felul de initializari bTmr1Int = 0; while (1) { if(bTmr1Int) //ce te intereseaza cand ai o intrerupere. { bTmr1Int = 0; } }}void interrupt numeFunctie(void){ if( PIE1bits.TMR1IE && PIR1bits.TMR1IF) //daca intreruperea e activa si flagul corespunzator e 1 (a venit intreruperea) { TMR1H=0xFF; TMR1L=0xFE; // numara doar o data bTmr1Int = 1; PIR1bits.TMR1IF = 0; //"sterge" flagul pentru urmatoarea intrerupere }} Numai ca, asa cum vezi, tratarea intreruperilor nu e chiar fara consum de timp. Daca n-ai prea multe de facut, poti face toate operatiile in functia interrupt. Daca te intereseaza cea mai mica temporizare - foloseste nop. PS Cred ca nu ti-ar strica sa rasfoiesti manualul lui picc (F11 in mplab). Link spre comentariu
mircang9 Postat Februarie 28, 2012 Autor Partajează Postat Februarie 28, 2012 Mersi mult Liviu. Defapt eu cand am zis intrerupere n-am folosit intrerupere. Am folosit doar flagul TMR1IF care semnalizeaza momentul cand registrul la Timer1 a ajuns la 0xFF sau 0xFFFF si am vrut ca in program NU intreruperea sa fie trigger pentru temporizare ci programul prin apel la functia tempo() cand vreau eu in program si nu cand apare intreruperea pe care eu s-o detectez in program. Am nevoie de doua temporizari: una pentru generarea sinusoidei corespunzatoare frecventei F1 si cealalta pentru generarea sinusoidei corespunzatoare frecventei F2. O sa renunt cred la functii si o sa scriu in main() si temporizarile. Asa castig un ciclu de instructiune care ar fi ocupat de instructia CALL de apel subrutina ( functie ) de temporizare. O sa ma uit si pe manual - nu-mi strica. Pe lana utilizarea directa a instructiunii nop() mi s-a parut interesanta comparatia folosita de tine in sens invers adica setez registrul Timer1 in sensul numararii crescatoare si asa elimin instructiunea if(TMR1H== xxxx) si astfel pot face o temporizare mai mica in acest mod. Adica in loc de: void tempo(){ while(TMR1L<0x05) // lungimea de 1 = 1.080 us la RD1 { nop(); } TMR1H = 0x00; TMR1L = 0x00;} pun: void tempo(){ TMR1H = 0xFF; TMR1L = 0xFA; while(PIR1bits.TMR1IF==0) { nop(); } PIR1bits.TMR1IF=0;} Astfel grabesc setarea bitului TMR1IF la overflow. Si cum ai zis tu cu nop() pot genera functia sinus cu frecventa cea mai mare pentru o marime de look-up table aleasa la marimea 90: for(index_sine=0;index_sine<90;index_sine++){ PORTD = sine[index_sine]; nop(); // temporizarea cea mai scurta} Iar ca sa-mi testez daca Fosc intern este chiar de 48 MHz pot citi pe osciloscop la RD1 cu urmatorul cod: while(1){ PORTDbits.RD1 = 0; nop(); PORTDbits.RD1 = 1; nop();} si daca Fosc este chiar 48 MHz de la PLL atunci semiperioada semnalului dreptunghiular la pinul RD1 trebuie sa fie 1/(Fosc/4) adica 1/(12 MHz) = 0.083 us. Asa cred ca pot vedea si cat de stabil este Fosc sau oscilatorul extern cu quartz si C1, C2. Ca daca ma pun cu sonda osciloscopului direct pe pinul OSC2 (pin14) introduc capacitatea sondei iar C2 devine in loc de 20 pF, 20pF + 25pF(capacitatea sondei) si citirea stabilitatii oscilatorului n-ar fi prea corecta. Link spre comentariu
mircang9 Postat Februarie 29, 2012 Autor Partajează Postat Februarie 29, 2012 Prin cele doua tranzistoare BC107 doresc sa fac adaptare de impedanta la 600 Ohm impedantaliniei telefonice. Dar in gol semnalul la iesirea BC107 final este distorsionat. Iesirea din R-2R este o sinusoida de 5V Vf-Vf si 390 Hz si este curata. Cand cuplez iesireadin reteaua de rezistente R-2R semnalul este translatat in sus cu aproximativ 1Vsi apare distorsiunea la iesirea finalului BC107. Nu inteleg de ce se intampla asa.Potentiometrul 4K7 il folosesc pentru amplificare. Primul BC107 trebuie sa realizeze adaptarea de impedanta ( montaj cu repetor pe emitor ).Cand cuplez etajul cu cele doua BC107 prin condensatorul de 2.2 uF sinusoidain baza primului BC107 scade in amplitudine pana la 3V Vf-Vf si este translatata in sus cu 1 V deasupra axei orizontale. La osciloscop sunt pe DC si nu pe AC. Mai exact: in punctul A semnalul de 3V Vf-Vf este translatat in sus cu 1V. in punctul B semnalul este translatat in sus cu 6V !!! in punctul C semnalul este translatat in sus cu 15V !!! si este deformat ( dar fara zgomot )Am incercat si fara condensatorul de 2.2 uF si semnalul in punctul B este translatat in sus cu 3V adica iesirea din R-2R legata direct in baza primului BC107 !!! Am incercat sa pun in loc de condensatorul de 2.2 uF o rezistenta de 3 Mohm si la fel se intampla. Care poate sa fie cauza ? Trebuie sa mai reduc din amplitudinea de 3V Vf-Vf printr-orezistenta de ordinul megohmilor sau un divizor rezistiv ? Link spre comentariu
mircang9 Postat Februarie 29, 2012 Autor Partajează Postat Februarie 29, 2012 Probabil translatarea apare si datorita rezistentelor de polarizare inegale din bazele celordoua tranzistoare BC107 ( 56K cu 30K, respectiv 86K cu 40K ). Schema de adaptare amcules-o nemodificata de undeva. Maine incerc sa pun rezistentele de polarizare egale:56K cu 56K si 40K cu 40K sa vad ce iese. Astept si alte idei, va rog. Link spre comentariu
mircang9 Postat Februarie 29, 2012 Autor Partajează Postat Februarie 29, 2012 Astept raspuns la ultima schema Link spre comentariu
mircang9 Postat Februarie 29, 2012 Autor Partajează Postat Februarie 29, 2012 Cred ca trebe sa fac astfel: sa folosesc un divizor rezistiv de tensiune pentru a limita semnalul de 5V Vf-Vf la sub 1V Vf-Vf si sa pun in loc de rezistentele de 36K si 30K doua rezistente de 100K egale sau sa mai micsorez din rezistenta catre masa si asaaduc valoarea minima la masa si nu la 1V cum e acum. La fel si cu rezistentelede 86K si 40K le pun egale. Cred ca asa o sa mearga. Condensatorul de 2.2 uFil las pentru ca elimina componenta continua a semnalului de la iesirea din reteauade rezistente R-2R. Eventual mai pun si un condensator la primul BC107 ( care realizeaza adaptarea de impedanta ) intre emitor-masa pentru a evita strapungerea tranzistorului la variatii mari ale semnalului de la intrare. Al doilea BC107 (finalul)are rol de amplificator de semnal. Link spre comentariu
cirip Postat Martie 2, 2012 Partajează Postat Martie 2, 2012 Salut,Incearca schema asta. Nu pune cond intre reteaua R-2R si amplificator ptr ca reteaua contribuie la polarizare. Poti sa pui orice tranzistor cu siliciu, incl. BC107,8,9.De curiozitate, ai facut curs de DCE?Spor! Link spre comentariu
mircang9 Postat Martie 3, 2012 Autor Partajează Postat Martie 3, 2012 Salut Cirip * Am facut curs de DCE dar profu ala ne inebunea cu PSF la tranzistor. Si mai mult avea un stil de predare foarte sofisticat "la nivel foarte inalt", iar pentru incepator ca mine era limba straina: "mase virtuale", PSF in alternativ, PSF in continuu, schema de semnal mic ( era si este cea mai ciudata pentru mine ), formule pentru schema de semnal mic, "mnemotechnic", etc. In fine de acum ma gandesc ca odata cu practica sa inteleg o parte din ceea ce tine de DCE. Mersi mult pentru raspuns. Am renuntat la schema de mai sus de adaptare. Orice rezistenta puneam chiar si egale sau cea fata de masa de valoare mai mica dar tot degeaba. Am legat direct iesirea din reteaua R-2R la intrare in demodulatorul FM cu PIC care masoara perioadele si decodifica inapoi semnalul digital si functioneaza. Ma gandisem sa pun pentru adaptare in loc de tranzistoarele din schema de mai sus un amplificator operational de exemplu LM339 folosit ca amplificator neinversor. Cica daca impedanta de intrare la capatul liniei la receptor este mare, problema adaptarii "se rezolva" marind amplitudinea semnalului de la emitator. Am rasfoit manualul de PICC-18 si am dat de functia _delay(1) care face o intarziere cu durata unui ciclu de instructiune. Am folosit si NOP(). Am reusit sa fac o intarziere pe care o citesc cu osciloscopul la un pin de iesire. Astfel: while(1){ PORTDbits.RD2=1; NOP(); // _delay(1); PORTDbits.RD2=0; NOP(); // _delay(1);} Astfel am vazut pe osciloscop un tact de 2MHz stabil adica cu perioada de 500 ns. Am reusit sa fac o perioada si de 300 ns dar lungimea de 1 este mai mica decat lungimea de 0 logic din acel tact desi este stabil. Fosc = 48 MHz. Teoretic ar fi trebuit sa obtin o perioada de 83ns. Probabil daca as fi programat in limbaj de asamblare as fi reusit. BC107 accepta pana la 40V intre C-E. Pe cand BC108,BC109 accepta maxim 20V intre C-E. Acum ca mi-ai dat aceasta schema o s-o incerc. Multumesc mult Cirip *** Link spre comentariu
picolo Postat Martie 3, 2012 Partajează Postat Martie 3, 2012 while(1){ PORTDbits.RD2=1; NOP(); // _delay(1); PORTDbits.RD2=0; NOP(); // _delay(1);} de ce folosesti while(1) ? eu cred ca while(14) este corect in contextul dat. 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