Cuprins:

Contor de frecvență de înaltă rezoluție: 5 pași (cu imagini)
Contor de frecvență de înaltă rezoluție: 5 pași (cu imagini)

Video: Contor de frecvență de înaltă rezoluție: 5 pași (cu imagini)

Video: Contor de frecvență de înaltă rezoluție: 5 pași (cu imagini)
Video: Trucul care garantează orgasmul femeii în timpul actului sexual 2024, Noiembrie
Anonim

Acest instructable arată un contor de frecvență reciproc capabil să măsoare frecvențe rapid și cu o precizie rezonabilă. Este realizat cu componente standard și poate fi realizat într-un weekend (mi-a luat ceva mai mult:-))

EDIT: Codul este acum disponibil pe GitLab:

gitlab.com/WilkoL/high-resolution-frequency-counter

Pasul 1: Numărarea frecvenței Old School

Old School Frequency Counting
Old School Frequency Counting
Old School Frequency Counting
Old School Frequency Counting

Modul vechi de școală pentru a măsura frecvența unui semnal este de a utiliza o poartă AND logică, de a alimenta semnalul care urmează să fie măsurat într-un port și un semnal cu o durată mare de exact 1 secundă către celălalt port și să numere ieșirea. Acest lucru funcționează destul de bine pentru semnale de câțiva kHz până în GHz. Dar dacă doriți să măsurați un semnal de joasă frecvență cu o rezoluție bună? Spuneți că doriți să măsurați frecvența rețelei (aici 50 Hz). Cu metoda vechii școli, veți vedea o constantă 50 pe ecran dacă aveți noroc, dar mai probabil veți vedea comutatorul afișajului de la 49 la 50 sau 50 la 51. Rezoluția este de 1 Hz, și atât. Nu veți vedea niciodată 50,002 Hz, cu excepția cazului în care sunteți dispus să măriți timpul de poartă la 1000 de secunde. Asta înseamnă mai mult de 16 minute, pentru o singură măsurare!

O modalitate mai bună de a măsura semnalele de joasă frecvență este de a măsura perioada acestuia. Luând din nou rețeaua ca exemplu, are o perioadă de 20 de milisecunde. Luați aceeași logică AND-gate, alimentați-o cu, să zicem 10 MHz (0,1 impulsuri americane) și semnalul dvs. de pe celălalt port și ies 200000 de impulsuri, deci perioada de timp este 20000,0 uS și asta se traduce înapoi la 50Hz. Când măsurați doar 199650 impulsuri, frecvența este de 50,087 Hz, este mult mai bună și este în doar o secundă de măsurare. Din păcate, acest lucru nu funcționează bine cu frecvențe mai mari. Luați de exemplu, acum vrem să măsurăm 40 kHz. Cu aceeași frecvență de intrare de 10 MHz ca referință, măsurăm acum doar 250 de impulsuri. Când numărăm doar 249 impulsuri, calculul dă 40161 Hz, iar cu 251 rezultatul este 39840 Hz. Aceasta nu este o rezoluție acceptabilă. Desigur, creșterea frecvenței de referință îmbunătățește rezultatele, dar există o limită la ceea ce puteți utiliza într-un microcontroler.

Pasul 2: Calea reciprocă

Calea reciprocă
Calea reciprocă
Calea reciprocă
Calea reciprocă

O soluție care funcționează atât pentru frecvențe joase, cât și pentru frecvențe mai mari este un contor de frecvență reciproc. Voi încerca să-i explic principiul. Începeți cu un timp de măsurare care este de aproximativ 1 secundă, nu trebuie să fie foarte precis, dar este un timp rezonabil pentru o măsurare. Introduceți acest semnal de 1 Hz într-un flipflop D de pe intrarea D. Nimic nu se întâmplă încă pe ieșire. Conectați semnalul pe care doriți să îl măsurați la intrarea CLOCK a D-flipflop-ului.

De îndată ce acest semnal trece de la LOW la HIGH, ieșirea D-flipflop transferă starea intrării D la ieșirea (Q). Acest semnal RISING merge este utilizat pentru a începe numărarea semnalului de intrare, precum și a unui semnal de ceas de referință.

Deci, numărați DOUĂ semnale în același timp, semnalul pe care doriți să îl măsurați și un ceas de referință. Acest ceas de referință trebuie să aibă o valoare precisă și să fie stabil, un oscilator de cristal normal este bine. Valoarea nu este foarte importantă atâta timp cât este o frecvență înaltă și valoarea ei este bine cunoscută.

După ceva timp, spuneți câteva milisecunde, faceți din nou intrarea D a flipflopului D. La următoarea intrare CLOCK, ieșirea Q urmează starea intrării, dar nimic altceva nu se întâmplă deoarece microcontrolerul este setat să reacționeze doar la un semnal RISING. Apoi, după terminarea timpului de măsurare (aproximativ 1 secundă), faceți intrarea D HIGH.

Din nou la următoarea intrare CLOCK urmează ieșirea Q și acest semnal RISING declanșează microcontrolerul, de data aceasta pentru a încheia numărarea ambelor contoare.

Rezultatul este două numere. Primul număr este numărul de impulsuri numărate de la referință. Pe măsură ce cunoaștem frecvența de referință, știm și timpul necesar pentru a număra acele impulsuri.

În al doilea rând numărul este numărul de impulsuri de la semnalul de intrare pe care îl măsurăm. Pe măsură ce am început exact pe marginile RISING ale acestui semnal, suntem foarte încrezători cu privire la numărul de impulsuri ale acestui semnal de intrare.

Acum este doar un calcul pentru a determina frecvența semnalului de intrare.

Un exemplu, să spunem că avem aceste semnale și vrem să măsurăm intrarea f. Referința este de 10 MHz, generată de un oscilator cu cristale de cuarț. f_input = 31.416 Hz f_reference = 10000000 Hz (10 MHz), timpul de măsurare este de aprox. 1 secunda

În acest timp am numărat 32 de impulsuri. Acum, o perioadă a acestui semnal durează 1 / 31.416 = 31830.9 uS. Deci 32 de perioade ne-au luat 1.0185892 secunde, ceea ce înseamnă puțin peste 1 secundă.

În această secundă de 1,0186, de asemenea, vom fi numărat 10185892 impulsuri ale semnalului de referință.

Aceasta ne oferă următoarele informații: input_count = 32 reference_count = 10185892 f_reference = 10000000 Hz

Formula pentru a calcula frecvența rezultată este următoarea: freq = (input_count * f_reference) / ref_count

În exemplul nostru, acesta este: f-input = (32 * 10000000) / 10185892 = 31.416 Hz

Și acest lucru funcționează bine atât pentru frecvențe joase, cât și pentru frecvențe înalte, numai atunci când semnalul de intrare se apropie (sau chiar mai mare decât) de frecvența de referință, este mai bine să folosiți modul standard de „măsurare”. Dar atunci am putea adăuga pur și simplu un divizor de frecvență la semnalul de intrare, deoarece această metodă reciprocă are aceeași rezoluție pentru orice frecvență (până la referință din nou). Deci, indiferent dacă măsurați 100 kHz direct sau împărțiți cu un divizor extern de 1000x, rezoluția este aceeași.

Pasul 3: Hardware și schema sa

Hardware și schema sa
Hardware și schema sa
Hardware și schema sa
Hardware și schema sa

Am făcut câteva din acest tip de contoare de frecvență. Cu mult timp în urmă am făcut unul cu un ATMEGA328 (același controler ca și într-un Arduino), ulterior cu micro-controlere ARM de la ST. Cel mai recent a fost realizat cu un STM32F407 tactat la 168 MHz. Dar acum m-am întrebat dacă fac același lucru cu unul * mult mai mic. Am ales un ATTINY2313, care are doar 2kbyte de memorie FLASH și 128 de octeți de RAM. Afișajul pe care îl am este un MAX7219 cu 8 afișaje de șapte segmente pe acesta, aceste afișaje sunt disponibile pe Ebay la doar 2 euro. Un ATTINY2313 poate fi cumpărat cu aproximativ 1,5 euro, restul pieselor pe care le-am folosit costă doar cenți pe bucată. Cel mai scump a fost probabil cutia de proiectare din plastic. Mai târziu am decis să-l fac să funcționeze pe o baterie litiu-ion, așa că trebuia să adaug un stabilizator de tensiune (LDO) de 3,3 V, un modul de încărcare a bateriei și bateria în sine. Acest lucru crește oarecum prețul, dar cred că poate fi construit pentru mai puțin de 20 de euro.

Pasul 4: Codul

Codul
Codul
Codul
Codul

Codul a fost scris în C cu Atmel (Microchip) Studio 7 și programat în ATTINY2313 folosind un OLIMEX AVR_ISP (clonă?). Deschideți (main.c) în fișierul zip de mai jos dacă doriți să urmați descrierea aici.

INIȚIALIZARE

Mai întâi, ATTINY2313 a fost setat să utilizeze un cristal extern, deoarece oscilatorul RC intern este inutil pentru măsurarea a ceva. Folosesc un cristal de 10 MHz pe care îl reglez la frecvența corectă de 10 000 000 Hz cu un condensator variabil mic. Inițializarea se ocupă de setarea porturilor la intrări și ieșiri, configurarea cronometrelor și activarea întreruperilor și inițializarea MAX7219. TIMER0 este configurat pentru a număra un ceas extern, TIMER1 ceasul intern și, de asemenea, pentru a captura valoarea contorului la marginea ascendentă a ICP, provenind de la D-flipflop.

Voi discuta ultimul program principal, așa că urmează rutinele de întrerupere.

TIMER0_OVF

Deoarece TIMER0 numără până la 255 (8 biți) și apoi trece la 0 avem nevoie de o întrerupere pentru a număra numărul de revărsări. Asta este tot ceea ce face TIMER0_OVF, numărați doar numărul de revărsare. Mai târziu, acest număr este combinat cu valoarea contorului în sine.

TIMER1_OVF

TIMER1 poate număra până la 65536 (16 biți), deci întreruperea TIMER1_OVF numără și numărul de revărsări. Dar face mai mult. De asemenea, scade de la 152 la 0, care durează aproximativ 1 secundă și apoi setează un pin de ieșire, mergând la intrarea D a flipflop-ului. Și ultimul lucru care se face în această rutină de întrerupere este de a scădea contorul de expirare, trecând de la 765 la 0, care durează aproximativ 5 secunde.

TIMER1_CAPT

Aceasta este întreruperea TIMER1_CAPT care este declanșată de fiecare dată când D-flipflop îi trimite un semnal, la marginea ascendentă a semnalului de intrare (așa cum s-a explicat mai sus). Logica de captare se ocupă de salvarea valorii contorului TIMER1 în momentul captării, se salvează la fel ca și contorul de revărsare. Din păcate, TIMER0 nu are o funcție de captură de intrare, deci aici se citește valoarea sa curentă și valoarea curentă a contorului de revărsare. O variabilă de mesaj este setată la una pentru ca programul principal să-i spună că acestea sunt date noi.

Următoarele sunt două funcții pentru a controla MAX7219

SPI

Deși există o interfață serială universală (USI) disponibilă în cip, am ales să nu o folosesc. Afișajul MAX7219 trebuie controlat prin SPI și acest lucru este posibil cu USI. Dar SPI-ul bitbanging este atât de simplu încât nu mi-am luat timp să-l fac cu USI.

MAX7219

Protocolul pentru configurarea MAX7219 este, de asemenea, destul de simplu odată ce ați citit manualul acestuia. Are nevoie de o valoare de 16 biți pentru fiecare cifră care constă din 8 biți pentru numărul cifrei (1 până la 8) urmat de 8 biți pentru numărul pe care trebuie să îl afișeze.

MAIN-PROG

Ultimul lucru este să explici programul principal. Se execută într-o buclă infinită (în timp ce (1)), dar face de fapt doar ceva atunci când există un mesaj (1) din rutina de întrerupere sau când contorul de timeout a scăzut la zero (fără semnal de intrare).

Primul lucru de făcut atunci când mesajul variabil este setat la unul, este resetarea contorului de timeout, la urma urmei știm că există un semnal prezent. Flipflop-ul D este resetat pentru a-l pregăti pentru următorul declanșator care va veni după timpul de măsurare (așteptați o secundă).

Numerele înregistrate în întreruperea capturii sunt adăugate pentru a da numărul de referință și numărul de frecvență de intrare. (trebuie să ne asigurăm că referința nu poate fi niciodată zero, deoarece vom împărți la aceasta mai târziu)

Următorul este calculul frecvenței reale. Cu siguranță nu vreau să folosesc numere flotante pe un microcontroler cu doar 2 kbyte de bliț și doar 128 de octeți de ram folosesc numere întregi. Dar frecvențele pot fi ca 314,159 Hz, cu mai multe zecimale. Prin urmare, înmulțesc frecvența de intrare nu numai cu frecvența de referință, ci și cu un multiplicator și apoi adaug un număr unde trebuie să meargă punctul zecimal. Aceste cifre vor deveni foarte foarte mari atunci când faceți acest lucru. De exemplu. cu o intrare de 500 kHz, o referință de 10 MHz și un multiplicator de 100, acest lucru dă 5 x 10 ^ 14, asta este cu adevărat imens! Acestea nu se vor încadra într-un număr de 32 de biți, așa că folosesc numere de 64 de biți care vor merge până la 1,8 x 10 ^ 19 (care funcționează bine pe un ATTINY2313)

Și ultimul lucru de făcut este să trimiteți rezultatul pe afișajul MAX7219.

Codul se compilează în aproximativ 1600 de octeți, deci se potrivește cu blițul de 2048 de octeți disponibil în ATTINY2313.

Registrele de siguranțe ar trebui să citească astfel:

PRELUNGIT 0xFF

ÎNALT 0xDF

LOW 0xBF

Pasul 5: Precizie și precizie

Acuratețe și precizie
Acuratețe și precizie
Acuratețe și precizie
Acuratețe și precizie
Acuratețe și precizie
Acuratețe și precizie

Acuratețea și precizia sunt două fiare separate. Precizia de aici este de șapte cifre, care este precizia reală depinde de hardware și calibrare. Am calibrat 10 MHz (5 MHz pe punctul de test) cu un alt contor de frecvență care are un oscilator disciplinat de GPS.

Și funcționează destul de bine, cea mai mică frecvență pe care am încercat-o este de 0,2 Hz, cea mai mare 2 MHz. Este la fața locului. Peste 2 MHz, controlerul începe să piardă întreruperile, ceea ce nu este surprinzător când știți că la 2 MHz semnalul de intrare TIMER0 generează peste 7800 de întreruperi pe secundă. Și ATTINY2313 trebuie să facă și alte lucruri, întreruperile de la TIMER1, la alte 150 de întreruperi pe secundă și, desigur, fac calculele, controlând afișajul și D-flipflop. Când vă uitați la dispozitivul real, veți vedea că folosesc doar șapte din cele opt cifre ale afișajului. Fac asta din mai multe motive.

În primul rând, calculul frecvenței de intrare este o diviziune, va avea aproape întotdeauna un rest, pe care nu îl vedeți, deoarece este o divizare întreagă. În al doilea rând, oscilatorul cu cristale de cuarț nu este stabilizat la temperatură.

Condensatorii care îl reglează la 10 MHz corecți sunt ceramici, foarte sensibili la schimbările de temperatură. Apoi, există faptul că TIMER0 nu are logică de captare și toate funcțiile de întrerupere necesită un timp pentru a-și face treaba. Cred că șapte cifre sunt oricum destul de bune.

Recomandat: