Cuprins:
- Pasul 1: Numărarea frecvenței Old School
- Pasul 2: Calea reciprocă
- Pasul 3: Hardware și schema sa
- Pasul 4: Codul
- Pasul 5: Precizie și precizie
Video: Contor de frecvență de înaltă rezoluție: 5 pași (cu imagini)
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:41
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
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ă
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
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 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ț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:
Contor de frecvență cu Arduino: 8 pași (cu imagini)
Contor de frecvență cu Arduino: Acesta este un contor de frecvență bazat pe arduino simplu și ieftin, care costă mai puțin de 4 $, a fost foarte util să măsoare circuite mici
Cameră web de înaltă rezoluție: 9 pași (cu imagini)
Cameră web de înaltă rezoluție: De câțiva ani am folosit o cameră web bazată pe RPi (cu modulul PiCam). Imaginile produse erau în regulă, dar atunci a existat momentul în care nu am mai fost mulțumit de calitate. Am decis să fac o cameră web de înaltă rezoluție. Următoarele părți cu
OpenLogger: un înregistrator de date portabil de înaltă rezoluție, Wi-Fi, Open Source, portabil: 7 pași
OpenLogger: un înregistrator de date portabil, cu sursă deschisă, cu sursă deschisă, cu sursă deschisă: OpenLogger este un înregistrator de date portabil, cu sursă deschisă, cu cost redus, cu rezoluție ridicată, conceput pentru a oferi măsurători de înaltă calitate fără a necesita software scump sau software de scriere de la zero. Dacă sunteți inginer, om de știință sau entuziast care nu
Generare de semnal PWM de înaltă rezoluție pentru servere RC cu dispozitive STM32: 3 pași
Generare semnal PWM de înaltă rezoluție pentru servere RC cu dispozitive STM32: În prezent, construiesc un transmițător / receptor RC bazat pe cipul RF SX1280. Unul dintre obiectivele proiectului este acela că vreau o rezoluție servo de 12 biți de pe stick-uri până la servouri. În parte, pentru că servourile digitale moderne au o rezoluție de 12 biți
Cum să obțineți imagini de înaltă rezoluție din instructabile: 4 pași
Cum să obțineți imagini de înaltă rezoluție din instructabile: Ți-a plăcut cu adevărat acea imagine instructabilă și ai vrut să salvezi o copie de înaltă rezoluție a acesteia? Această caracteristică minunată este ușor de trecut cu vederea