Sadržaj:

Brojač frekvencija visoke rezolucije: 5 koraka (sa slikama)
Brojač frekvencija visoke rezolucije: 5 koraka (sa slikama)

Video: Brojač frekvencija visoke rezolucije: 5 koraka (sa slikama)

Video: Brojač frekvencija visoke rezolucije: 5 koraka (sa slikama)
Video: Analog-to-Digital Converters (ADC) - Dual Slope and Charge-Balancing ADC 2024, Juli
Anonim

Ovo uputstvo prikazuje recipročni brojač frekvencija koji može mjeriti frekvencije brzo i sa razumnom preciznošću. Napravljen je sa standardnim komponentama i može se napraviti za vikend (trebalo mi je malo duže:-))

EDIT: Kod je sada dostupan na GitLabu:

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

Korak 1: Brojanje frekvencija stare škole

Brojanje frekvencija stare škole
Brojanje frekvencija stare škole
Brojanje frekvencija stare škole
Brojanje frekvencija stare škole

Stari način mjerenja frekvencije signala je korištenje logičkog AND-gate-a, dovod signala koji se mjeri u jedan port i signal sa tačno 1 sekundom maksimalnog vremena do drugog porta i prebrojavanje izlaza. Ovo radi prilično dobro za signale od nekoliko kHz do GHz. Ali šta ako želite mjeriti signal niske frekvencije s dobrom rezolucijom? Recimo da želite izmjeriti frekvenciju mreže (ovdje 50 Hz). Sa old school metodom, ako budete imali sreće, vidjet ćete konstantnih 50 na ekranu, ali vjerovatnije ćete vidjeti kako se ekran prebacuje sa 49 na 50 ili 50 na 51. Rezolucija je 1 Hz, i to je to. Nikada nećete vidjeti 50,002 Hz osim ako niste voljni povećati vrijeme prolaza na 1000 sekundi. To je više od 16 minuta, za jedno mjerenje!

Bolji način za mjerenje niskofrekventnih signala je mjerenje njihovog perioda. Ako opet uzmemo električnu mrežu, period ima 20 milisekundi. Uzmite istu logičku AND-kapiju, napajajte je sa, recimo 10 MHz (0,1 us impulsa), a vaš signal na drugom portu izlazi i izlazi 200 000 impulsa, tako da je vremensko razdoblje 20000,0 uS i to se prevodi na 50Hz. Kad izmjerite samo 199650 impulsa, frekvencija je 50.087 Hz, to je mnogo bolje i to je samo jedna sekunda vremena mjerenja. Nažalost, ovo ne funkcionira dobro s višim frekvencijama. Uzmimo za primjer, sada želimo izmjeriti 40 kHz. Sa istom ulaznom frekvencijom od 10 MHz kao referentnom, sada mjerimo samo 250 impulsa. Kada brojimo samo 249 impulsa, proračun daje 40161 Hz, a sa 251 rezultat je 39840 Hz. To nije prihvatljivo rješenje. Naravno, povećanje referentne frekvencije poboljšava rezultate, ali postoji ograničenje za ono što možete koristiti u mikro kontroleru.

Korak 2: Uzajamni način

Recipročni način
Recipročni način
Recipročni način
Recipročni način

Rješenje koje radi i na niskim i na višim frekvencijama je uzajamni brojač frekvencija. Pokušaću da objasnim njegov princip. Počinjete s vremenom mjerenja koje je otprilike 1 sekunda, ne mora biti vrlo precizno, ali je razumno vrijeme za mjerenje. Umetnite ovaj signal od 1 Hz u D-flipflop na D-ulazu. Ništa se još ne događa na izlazima. Spojite signal koji želite mjeriti na ulaz SAT na D-flipflopu.

Čim ovaj signal pređe s LOW na HIGH, izlaz D-flipflopa prenosi stanje D-ulaza na izlaz (Q). Ovaj RISING signal ide za početak brojanja ulaznog signala, kao i referentnog takta.

Dakle, brojite dva signala u isto vrijeme, signal koji želite mjeriti i referentni sat. Ovaj referentni sat mora imati preciznu vrijednost i biti stabilan, normalni kristalni oscilator je u redu. Vrijednost nije jako važna sve dok je visoka frekvencija i njena vrijednost je dobro poznata.

Nakon nekog vremena, recimo nekoliko milisekundi, ponovo ćete smanjiti D-ulaz D-flipflopa. Na sljedećem ulazu CLOCK izlaz Q prati stanje na ulazu, ali ništa se drugo ne događa jer je mikro kontroler postavljen da reagira samo na RISING signal. Zatim, nakon isteka vremena mjerenja (približno 1 sekunda), napravite D-ulaz HIGH.

Ponovo na sljedećem ulazu CLOCK slijedi Q izlaz i ovaj RISING signal pokreće mikrokontroler, ovaj put da završi odbrojavanje oba brojača.

Rezultat su dva broja. Prvi broj je broj impulsa odbrojan od reference. Kako znamo referentnu frekvenciju, znamo i vrijeme potrebno za brojanje tih impulsa.

Drugi broj je broj impulsa iz ulaznog signala koji mjerimo. Kako smo započeli upravo na RISING ivicama ovog signala, vrlo smo sigurni u broj impulsa ovog ulaznog signala.

Sada je samo proračun za utvrđivanje frekvencije ulaznog signala.

Na primjer, recimo da imamo te signale i želimo izmjeriti f-ulaz. Referentna vrijednost je 10 MHz, generirana oscilatorom od kvarcnog kristala. f_input = 31.416 Hz f_reference = 10000000 Hz (10 MHz), vrijeme mjerenja je cca. 1 sekunda

Za to vrijeme smo izbrojali 32 impulsa. Sada, jedan period ovog signala traje 1 / 31.416 = 31830.9 uS. Dakle, 32 perioda su nam oduzela 1,0185892 sekunde, što je nešto više od 1 sekunde.

U ovoj 1.0186 sekundi također ćemo izbrojati 10185892 impulsa referentnog signala.

To nam daje sljedeće informacije: input_count = 32 reference_count = 10185892 f_reference = 10000000 Hz

Formula za izračunavanje rezultirajuće frekvencije je sljedeća: freq = (input_count * f_reference) / ref_count

U našem primjeru to je: f-input = (32 * 10000000) / 10185892 = 31.416 Hz

I ovo dobro funkcionira za niske i visoke frekvencije, samo kada se ulazni signal približi (ili čak i više) referentnoj frekvenciji, bolje je koristiti standardni "gated" način mjerenja. Ali tada bismo mogli jednostavno dodati razdjelnik frekvencije ulaznom signalu jer ova recipročna metoda ima istu rezoluciju za bilo koju frekvenciju (opet do referentne). Dakle, bilo da mjerite 100 kHz direktno podijeljeno vanjskim razdjelnikom 1000x, rezolucija je ista.

Korak 3: Hardver i njegova shema

Hardver i njegova shema
Hardver i njegova shema
Hardver i njegova shema
Hardver i njegova shema

Napravio sam nekoliko ovakvih brojača frekvencija. Davno sam napravio jedan sa ATMEGA328 (isti kontroler kao i u Arduinu), kasnije sa ARM mikrokontrolerima iz ST. Najnoviji je napravljen sa STM32F407 taktom na 168 MHz. Ali sad sam se pitao šta ako učinim isto sa * mnogo * manjim. Odabrao sam ATTINY2313, koji ima samo 2 kB FLASH memorije i 128 bajtova RAM -a. Ekran koji imam je MAX7219 sa 8 ekrana sa sedam segmenata, ovi ekrani su dostupni na Ebayu za samo 2 eura. ATTINY2313 se može kupiti za oko 1,5 eura, a ostali dijelovi koje sam koristio koštaju samo cente po komadu. Najskuplja je vjerovatno bila plastična kutija za projekte. Kasnije sam odlučio omogućiti rad na litij-ionskoj bateriji pa sam morao dodati (LDO) 3.3V stabilizator napona, modul za punjenje baterije i samu bateriju. Ovo donekle povećava cijenu, ali pretpostavljam da se može graditi za manje od 20 eura.

Korak 4: Kôd

Kodeks
Kodeks
Kodeks
Kodeks

Kod je napisan na C jeziku sa Atmel (Microchip) Studio 7 i programiran u ATTINY2313 pomoću OLIMEX AVR_ISP (klon?). Otvorite (main.c) u zip datoteci ispod ako želite slijediti opis ovdje.

INICIJALIZACIJA

Prvo je ATTINY2313 podešen da koristi vanjski kristal jer je unutrašnji RC-oscilator beskoristan za mjerenje bilo čega. Koristim kristal od 10 MHz koji podešavam na ispravnu frekvenciju od 10 000 000 Hz s malim promjenjivim kondenzatorom. Inicijalizacija vodi računa o postavljanju portova na ulaze i izlaze, postavljanju tajmera i omogućavanju prekida i inicijalizaciji MAX7219. TIMER0 je podešen za brojanje vanjskog sata, TIMER1 za unutrašnji sat, a također i za snimanje vrijednosti brojača na rastućoj ivici ICP-a, koji dolazi iz D-flipflopa.

Posljednje ću raspravljati o glavnom programu, pa slijede rutine prekida.

TIMER0_OVF

Kako TIMER0 broji do 255 (8 bita), a zatim se prebacuje na 0, potreban nam je prekid za brojanje broja prelijevanja. To je sve što TIMER0_OVF radi, samo izbrojite broj prelijevanja. Kasnije se ovaj broj kombinira s vrijednošću samog brojača.

TIMER1_OVF

TIMER1 može brojati do 65536 (16 bita), tako da prekid TIMER1_OVF broji i broj prelijevanja. Ali čini više. Također se smanjuje sa 152 na 0 što traje oko 1 sekundu, a zatim postavlja izlazni pin, koji ide na D-ulaz flipflopa. I posljednja stvar koja se radi u ovoj rutini prekida je smanjenje brojača timeout-a, koji ide sa 765 na 0, što traje oko 5 sekundi.

TIMER1_CAPT

Ovo je prekid TIMER1_CAPT koji se aktivira svaki put kada mu D-flipflop pošalje signal, na rastućoj ivici ulaznog signala (kao što je gore objašnjeno). Logika hvatanja brine o spremanju vrijednosti brojača TIMER1 u trenutku hvatanja, ona se sprema kao i brojač preljeva. Nažalost, TIMER0 nema funkciju snimanja ulaza, pa se ovdje očitava njegova trenutna vrijednost i trenutna vrijednost brojača preljeva. Promjenjiva poruka je postavljena na jedan kako bi glavni program rekao da su to novi podaci.

Slijede dvije funkcije za upravljanje MAX7219

SPI

Iako je u čipu dostupno univerzalno serijsko sučelje (USI), odlučio sam ga ne koristiti. Zaslon MAX7219 treba kontrolirati putem SPI -ja, a to je moguće s USI -jem. Ali bitbanging SPI je tako jednostavan da nisam odvojio vrijeme za to s USI -jem.

MAX7219

Protokol za postavljanje MAX7219 također je prilično jednostavan nakon što pročitate njegov priručnik. Potrebna mu je 16 -bitna vrijednost za svaku znamenku koja se sastoji od 8 bita za cifreni broj (1 do 8), nakon čega slijedi 8 bita za broj koji treba prikazati.

GLAVNI PROG

Zadnja stvar je objasniti glavni program. Radi u beskonačnoj petlji (while (1)), ali zapravo čini nešto samo ako postoji poruka (1) iz rutine prekida ili kada se brojač vremena ograničenja spustio na nulu (nema ulaznog signala).

Prva stvar koju treba učiniti kada je poruka varijable postavljena na jedan je resetiranje brojača vremena čekanja, nakon svega što znamo da postoji signal. D-flipflop se resetira kako bi bio spreman za sljedeći okidač koji će doći nakon vremena mjerenja (čekanje-sekunda).

Brojevi registrirani u prekidu snimanja dodaju se kako bi dali referentni broj i ulazni frekvencijski broj. (moramo se pobrinuti da referenca nikada ne može biti nula jer ćemo je kasnije podijeliti)

Slijedi izračun stvarne frekvencije. Sigurno ne želim koristiti plutajuće brojeve na mikrokontroleru sa samo 2 KB flash i samo 128 bajtova rama. Koristim cijele brojeve. Ali frekvencije mogu biti poput 314,159 Hz, s nekoliko decimala. Stoga množim ulaznu frekvenciju ne samo s referentnom frekvencijom već i s množiteljem, a zatim dodajem broj tamo gdje bi decimalna točka trebala biti. Ovi brojevi će postati vrlo veliki ako to učinite. Npr. sa ulazom od 500 kHz, referencom od 10 MHz i množiteljem 100, ovo daje 5 x 10^14, to je zaista ogromno! Oni se neće uklopiti u 32 -bitni broj, pa koristim 64 -bitne brojeve koji će ići sve do 1,8 x 10^19 (to dobro funkcionira na ATTINY2313)

I posljednja stvar koju trebate učiniti je poslati rezultat na zaslon MAX7219.

Kod se kompilira u nekih 1600 bajtova, pa se uklapa u blic od 2048 bajtova dostupan u ATTINY2313.

Registri osigurača trebali bi glasiti ovako:

PRODUŽENO 0xFF

HIGH 0xDF

NISKA 0xBF

Korak 5: Tačnost i preciznost

Tačnost i preciznost
Tačnost i preciznost
Tačnost i preciznost
Tačnost i preciznost
Tačnost i preciznost
Tačnost i preciznost

Tačnost i preciznost su dve različite zveri. Ovdje je preciznost sedam znamenki, a stvarna preciznost ovisi o hardveru i kalibraciji. Kalibrirao sam 10 MHz (5 MHz na ispitnoj tački) s drugim brojačem frekvencija koji ima GPS disciplinirani oscilator.

I radi sasvim dobro, najniža frekvencija koju sam probao je 0,2 Hz, a najviša 2 MHz. Na mestu je. Iznad 2 MHz kontroler počinje gubiti prekide, što i ne čudi kada znate da na ulaznom signalu od 2 MHz TIMER0 generira preko 7800 prekida u sekundi. ATTINY2313 mora raditi i druge stvari, prekide iz TIMER-a1, pri dodatnih 150 prekida u sekundi i naravno raditi proračune, kontrolirajući zaslon i D-flipflop. Kad pogledate stvarni uređaj, vidjet ćete da koristim samo sedam od osam znamenki ekrana. To radim iz nekoliko razloga.

Prvo je to što je proračun ulazne frekvencije podjela, gotovo uvijek će imati ostatak, koji ne vidite jer se radi o cjelobrojnoj podjeli. Drugo je da oscilator kristala kvarca nije stabiliziran temperaturom.

Kondenzatori koji ga podešavaju na ispravnih 10 MHz su keramički, vrlo osjetljivi na promjene temperature. Tu je i činjenica da TIMER0 nema ugrađenu logiku hvatanja, a funkcijama prekida je potrebno neko vrijeme da obave svoj posao. Mislim da je sedam cifara ionako dovoljno dobro.

Preporučuje se: