Sari la conținut
ELFORUM - Forumul electronistilor

Variabila contor vs Timer


mircang9

Postări Recomandate

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

Top autori în acest subiect

  • mircang9

    22

  • 10vid

    5

  • puiu

    3

  • Liviu M

    2

Top autori în acest subiect

Imagini postate

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

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 ?????

 

:dans:

Link spre comentariu

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.

 

:jytuiyu

Link spre comentariu

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.

 

:jytuiyu

Link spre comentariu

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

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.

 

:rade:

Link spre comentariu

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 ?

post-23035-13982939307_thumb.jpg

Link spre comentariu

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

Link spre comentariu

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

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!

post-879-139829394081_thumb.png

Link spre comentariu

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 ***

 

:dans:

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