Përmbajtje:

Mikrokontrolluesi AVR. LEDs Flasher Duke përdorur Timer. Kohëmatësit ndërpret. Kohëmatësi Mënyra CTC: 6 hapa
Mikrokontrolluesi AVR. LEDs Flasher Duke përdorur Timer. Kohëmatësit ndërpret. Kohëmatësi Mënyra CTC: 6 hapa

Video: Mikrokontrolluesi AVR. LEDs Flasher Duke përdorur Timer. Kohëmatësit ndërpret. Kohëmatësi Mënyra CTC: 6 hapa

Video: Mikrokontrolluesi AVR. LEDs Flasher Duke përdorur Timer. Kohëmatësit ndërpret. Kohëmatësi Mënyra CTC: 6 hapa
Video: LDmicro 8: Intruder Alarm with Timers (Microcontroller PLC Ladder Programming with LDmicro) 2024, Korrik
Anonim
Image
Image

Pershendetje te gjitheve!

Kohëmatësit janë një koncept i rëndësishëm në fushën e elektronikës. Çdo komponent elektronik funksionon në një bazë kohore. Kjo bazë kohore ndihmon për të mbajtur të gjithë punën të sinkronizuar. Të gjithë mikrokontrolluesit punojnë me një frekuencë të paracaktuar të orës, të gjithë ata kanë një dispozitë për të vendosur kohëmatës. AVR mburret se ka një kohëmatës i cili është shumë i saktë, i saktë dhe i besueshëm. Ajo ofron shumë karakteristika në të, duke e bërë kështu një temë të gjerë. Pjesa më e mirë është se kohëmatësi është plotësisht i pavarur nga CPU. Kështu, funksionon paralelisht me CPU -në dhe nuk ka ndërhyrje të CPU -së, gjë që e bën kohëmatësin mjaft të saktë. Në këtë pjesë unë shpjegoj konceptet themelore të Kohëmatësve AVR. Unë jam duke shkruar një program të thjeshtë në kodin C për të kontrolluar ndezësin LED, duke përdorur kohëmatës.

Hapi 1: Përshkrimi

Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj
Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj

Në ATMega328 ekzistojnë tre lloje të kohëmatësve:

Kohëmatësi/Counter0 (TC0) - është një modul 8 -bitësh Timer/Counter me qëllim të përgjithshëm, me dy njësi të pavarura OutputCompare dhe mbështetje PWM;

Kohëmatësi/Counter1 (TC1) - Njësia Kohëmatësi/Counter 16 -bit lejon kohën e saktë të ekzekutimit të programit (menaxhimi i ngjarjeve), gjenerimin e valëve dhe matjen e kohës së sinjalit;

Kohëmatësi/Counter2 (TC2) -është një qëllim i përgjithshëm, kanal, modul kohëmatës 8 -bitësh/Counter me PWM dhe Funksionim Asinkron;

Hapi 2: Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj

Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj
Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj
Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj
Deklarata e problemit 1: Le të ndezim LED -in e parë (jeshile) çdo 50 Znj

Metodologjia:

- përdorimi i një parashkruesi Timer0 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur një ndërprerje sa herë që Timer0 mbinxeh;

Kohëmatësi0 (8 bit) numëron nga 0 në 255 pas kësaj, ato derdhen, kjo vlerë ndryshon në çdo puls të orës.

F_CPU = 16MHz: Periudha kohore e orës = 1000ms / 16000000Hz = 0.0000625ms

Numërimi i kohëmatësit = (Kërkohet vonesa / koha e orës) -1 = (50ms / 0.0000625ms) = 799999

Ora tashmë ka shënuar 799999 herë për të dhënë një vonesë prej vetëm 50 ms!

Ne mund të përdorim teknikën e ndarjes së frekuencës që quhet prescaling për të zvogëluar numrin e kohëmatësit. AVR na ofron vlerat e mëposhtme të para -shkallëzimit për të zgjedhur: 8, 64, 256 dhe 1024. Shihni tabelën përmbledh rezultatet e përdorimit të presaleve të ndryshëm.

Vlera e kundërsulmit duhet të jetë gjithmonë një numër i plotë. Le të zgjedhim një parashkrues 256!

Në shumicën e mikrokontrolluesve, ekziston diçka që quhet Interrupt. Kjo ndërprerje mund të shkarkohet sa herë që plotësohen disa kushte. Tani sa herë që ndërpritet një ndërprerje, AVR ndalon dhe kursen ekzekutimin e rutinës kryesore, merr pjesë në thirrjen e ndërprerjes (duke ekzekutuar një rutinë të veçantë, të quajtur Rutina e Shërbimit të Ndërprerjes, ISR) dhe pasi të bëhet me të, kthehet në rutina kryesore dhe vazhdon ta zbatojë atë.

Meqenëse vonesa e kërkuar (50ms) është më e madhe se vonesa maksimale e mundshme: 4, 096ms = 1000ms / 62500Hz * 256, padyshim që kohëmatësi do të vërshojë. Dhe sa herë që kohëmatësi mbushet, ndizet një ndërprerje.

Sa herë duhet të pushohet ndërprerja?

50ms / 4.096ms = 3125 /256 = 12.207 Nëse kohëmatësi ka fluturuar 12 herë, 12 * 4.096ms = 49.152ms do të kishin kaluar. Në përsëritjen e 13 -të, ne kemi nevojë për një vonesë prej 50ms - 49.152ms = 0.848ms.

Në një frekuencë prej 62500Hz (prescaler = 256), çdo shënim merr 0.016ms. Kështu për të arritur një vonesë prej 0.848ms, do të duhej 0.848ms / 0.016ms = 53 rriqra. Kështu, në përsëritjen e 13 -të, ne lejojmë që kohëmatësi të numërojë deri në 53, dhe pastaj ta rivendosim atë.

Filloni Timer0/Counter (shiko foton):

TCCR0B | = (1 << CS02] // konfiguroni kohëmatësin me prescaler = 256 TCNT0 = 0 // filloni numëruesin TIMSK0 | = (1 << TOIE0] // aktivizoni ndërprerjen e tejkalimit të sei () // aktivizoni ndërprerjet globale tot_overflow = 0 // fillimi i ndryshores së numëruesit të tejmbushjes

Hapi 3: Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s

Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s
Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s
Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s
Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s
Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s
Deklarata e problemit 2: Le të ndezim LED -in e dytë (blu) çdo 1s

Metodologjia:

- përdorimi i një parashkruesi Timer1 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur modalitetin Clear Timer on Compare (CTC);

- përdorimi i ndërprerjeve me modalitetin CTC;

Kohëmatësi1 (16 bit) numëron nga 0 në 65534 pas kësaj, ato tejmbushin. Kjo vlerë ndryshon në çdo puls të orës.

F_CPU = 16MHz: Periudha kohore e orës = 1000ms / 16000000Hz = 0.0000625ms Numërimi i kohëmatësit = (Kërkohet vonesa / periudha e kohës së orës) -1 = (1000ms / 0.0000625ms) = 15999999

Ora tashmë ka shënuar 15999999 herë për të dhënë një vonesë prej 1 sekondash!

Ne mund të përdorim teknikën e ndarjes së frekuencës që quhet prescaling për të zvogëluar numrin e kohëmatësit. AVR na ofron vlerat e mëposhtme të para -shkallëzimit për të zgjedhur: 8, 64, 256 dhe 1024. Shihni tabelën përmbledh rezultatet e përdorimit të presaleve të ndryshëm. Vlera e kundërsulmit duhet të jetë gjithmonë një numër i plotë. Le të zgjedhim një parashkrues 256!

Në modalitetin Clear timer on Compare (CTC), regjistri OCR1A ose ICR1 përdoret për të manipuluar rezolucionin e numëruesit. Në modalitetin CTC, numëruesi pastrohet në zero kur vlera e numëruesit (TCNT1) përputhet ose me OCR1A ose ICR1. OCR1A ose ICR1 përcaktojnë vlerën kryesore për sportelin, pra edhe zgjidhjen e tij. Kjo mënyrë lejon kontroll më të madh të frekuencës së daljes së krahasimit të krahasimit Gjithashtu thjeshton funksionimin e numërimit të ngjarjeve të jashtme. Ne duhet t'i themi AVR -së që të rivendosë Kohëmatësin/Numëruesin sapo vlera e tij të arrijë vlerën 62500, kështu që të arrihet një vonesë prej 1s.

Filloni Kohëmatësin 1/Counter (shiko foton):

TCCR1B | = (1 << WGM12] | (1 << CS12) // konfiguroni kohëmatësin me prescaler = 256 dhe modalitetin CTC TCNT1 = 0 // iniconi numëruesin TIMSK1 | = (1 << OCIE1A) // aktivizoni krahasimin e ndërprerjes OCR1A = 62500 // filloni vlerën e krahasimit

Hapi 4: Deklarata e problemit 3: Le të ndezim LED -in e tretë (të kuq) çdo 16ms

Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms
Deklarata e problemit 3: Le të ndezim LED -in e tretë (e kuqe) çdo 16ms

Metodologjia:

- përdorimi i një parashkruesi Timer2 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur modalitetin Clear Timer on Compare (CTC);

- përdorimi i modalitetit CTC të pajisjeve pa ndërprerje;

Timer2 (8 bit) ajo numëron nga 0 në 255 pas kësaj, ato vërshojnë. Kjo vlerë ndryshon në çdo puls të orës.

F_CPU = 16MHz: Periudha kohore e orës = 1000ms / 16000000Hz = 0.0000625ms

Numërimi i kohëmatësit = (Kërkohet vonesa / koha e orës) -1 = (16ms / 0.0000625ms) = 255999

Ora tashmë ka shënuar 255999 herë për të dhënë një vonesë prej 16 ms!

Shihni tabelën përmbledh rezultatet e përdorimit të parashkruesve të ndryshëm. Vlera e numëruesit duhet të jetë gjithmonë një numër i plotë. Le të zgjedhim një prescaler 1024!

Në modalitetin CTC, numëruesi pastrohet në zero kur vlera e numëruesit (TCNT2) përputhet ose me OCR2A ose ICR2. Pin PB3 është gjithashtu kunja e Krahasimit të Daljeve të TIMER2 - OC2A (shih diagramin).

Kohëmatësi/Regjistri i Kontrollit Counter2 A - TCCR2A Bit 7: 6 - COM2A1: 0 - Krahasoni Modalitetin e Daljes për Krahasimin e Njësisë A. Meqenëse na duhet të kalojmë LED, ne zgjedhim opsionin: Toggle OC2A on Compare Match Sa herë që ndodh një ndeshje krahasimi, Kodi OC2A ndryshohet automatikisht. Nuk ka nevojë të kontrolloni ndonjë copë flamuri, nuk ka nevojë të kujdeseni për ndonjë ndërprerje.

Filloni Timer2/Counter

TCCR2A | = (1 << COM2A0] | (1 << WGM21) // vendosni timonin OC2A pin në modalitetin e kalimit dhe modalitetin CTC TCCR2B | = (1 << CS22] | (1 << CS21) | (1 << CS20) // vendosni kohëmatësin me prescaler = 1024 TCNT2 = 0 // inicializoni numëruesin OCR2A = 250 // filloni vlerën e krahasimit

Hapi 5: Shkrimi i kodit për një program në C. Ngarkimi i skedarit HEX në Flash Memory të Mikrokontrolluesit

Shkrimi i kodit për një program në C. Ngarkimi i skedarit HEX në Flash Memory të Mikrokontrolluesit
Shkrimi i kodit për një program në C. Ngarkimi i skedarit HEX në Flash Memory të Mikrokontrolluesit
Shkrimi i kodit për një program në C. Ngarkimi i skedarit HEX në Flash Memory të Mikrokontrolluesit
Shkrimi i kodit për një program në C. Ngarkimi i skedarit HEX në Flash Memory të Mikrokontrolluesit

Shkrimi dhe ndërtimi i aplikacionit të mikrokontrolluesit AVR në C Code duke përdorur Platformën e Zhvillimit të Integruar - Atmel Studio.

F_CPU përcakton frekuencën e orës në Hertz dhe është e zakonshme në programet që përdorin bibliotekën avr-libc. Në këtë rast përdoret nga rutinat e vonesës për të përcaktuar mënyrën e llogaritjes së vonesave kohore.

#ifndef F_CPU

#define F_CPU 16000000UL // tregues i frekuencës kristalore të kontrolluesit (16 MHz AVR ATMega328P) #endif

#include // header për të mundësuar kontrollin e rrjedhës së të dhënave mbi kunjat. Përcakton kunjat, portet, etj.

Skedari i parë i përfshirë është pjesë e avr-libc dhe do të përdoret në pothuajse çdo projekt AVR në të cilin punoni. io.h do të përcaktojë CPU që po përdorni (kjo është arsyeja pse ju specifikoni pjesën kur përpiloni) dhe nga ana tjetër do të përfshijë titullin e duhur të definicionit IO për çipin që ne po përdorim. Thjesht përcakton konstantet për të gjitha kunjat, portet, regjistrat tuaj të veçantë, etj.

#include // header për të mundësuar ndërprerjen

i paqëndrueshëm uint8_t tot_overflow; // ndryshore globale për të numëruar numrin e tejmbushjeve

Metodologjia e Deklaratës së Problemit: LED e parë e ndezur (jeshile) çdo 50 ms

- përdorimi i një parashkruesi Timer0 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur një ndërprerje sa herë që Timer0 mbinxeh;

void timer0_init () // inicio timer0, interrupt dhe variable

{TCCR0B | = (1 << CS02); // vendosni kohëmatësin me prescaler = 256 TCNT0 = 0; // inicoj numëruesin TIMSK0 | = (1 << TOIE0]; // aktivizoni tejkalimin e ndërprerjes sei (); // aktivizoni ndërprerjet globale tot_overflow = 0; // fillimi i ndryshores së numëruesit të tejmbushjes}

Metodologjia e Deklaratës së Problemit: Blici i dytë LED (blu) çdo 1s

- përdorimi i një parashkruesi Timer1 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur modalitetin Clear Timer on Compare (CTC);

- përdorimi i ndërprerjeve me modalitetin CTC;

void timer1_init () // inicio timer1, interrupt dhe variable {TCCR1B | = (1 << WGM12] | (1 << CS12); // vendosni kohëmatësin me prescaler = 256 dhe modalitetin CTC TCNT1 = 0; // inicoj numëruesin OCR1A = 62500; // inicializoni vlerën e krahasimit TIMSK1 | = (1 << OCIE1A); // aktivizo krahasimin e ndërprerjes}

Metodologjia e Deklaratës së Problemit: Blici i tretë LED (i kuq) çdo 16ms

- përdorimi i një parashkruesi Timer2 për të zvogëluar një sinjal elektrik me frekuencë të lartë në një frekuencë më të ulët me ndarjen e numrave të plotë;

- duke përdorur modalitetin Clear Timer on Compare (CTC);

- përdorimi i modalitetit CTC të pajisjeve pa ndërprerje;

void timer2_init () // inicio timer2 {TCCR2A | = (1 << COM2A0] | (1 << WGM21); // vendosni kunjin OC2A të kohëmatësit në modalitetin e kalimit dhe modalitetin CTC TCCR2B | = (1 << CS22] | (1 << CS21] | (1 << CS20); // vendosni kohëmatësin me prescaler = 1024 TCNT2 = 0; // inicoj numëruesin OCR2A = 250; // fillimi i vlerës së krahasimit}

Rutina e shërbimit të ndërprerjes së tejmbushjes TIMER0 e thirrur sa herë që TCNT0 tejkalon:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // mbani gjurmët e numrit të tejmbushjeve}

Ky ISR shkarkohet sa herë që ndodh një ndeshje, kaloni drejtuar këtu vetë:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // kaloni drejtuar këtu}

int kryesore (e pavlefshme)

{DDRB | = (1 << 0]; // lidhni 1 (jeshile) të çuar në pin PB0 DDRC | = (1 << 1); // lidhni 2 (blu) të çuar në pin PC1 DDRB | = (1 << 3); // lidheni 3 (e kuqe) led në pin PB3 (OC2A) timer0_init (); // inicio timer0 timer1_init (); // inicio timer1 timer2_init (); // inicio timer2 ndërsa (1) // loop përgjithmonë {

Nëse Timer0 ka fluturuar 12 herë, 12 * 4.096ms = 49.152ms do të kishin kaluar. Në përsëritjen e 13 -të, ne kemi nevojë për një vonesë prej 50ms - 49.152ms = 0.848ms. Kështu, në përsëritjen e 13 -të, ne lejojmë që kohëmatësi të numërojë deri në 53, dhe pastaj ta rivendosim atë.

nëse (tot_overflow> = 12) // kontrolloni nëse jo. e tejmbushjeve = 12 SHENIM: '> =' përdoret

{if (TCNT0> = 53) // kontrolloni nëse numri i kohëmatësit arrin 53 {PORTB ^= (1 << 0); // ndryshon led TCNT0 = 0; // rivendos numëruesin tot_overflow = 0; // rivendos numëruesin e tejmbushjes}}}}

Ngarkimi i skedarit HEX në kujtesën flash të mikrokontrolluesit:

shkruani në dritaren e shpejtë të DOS komandën:

avrdude –c [emri i programuesit] –p m328p –u –U flash: w: [emri i skedarit tuaj gjashtëkëndor] Në rastin tim është: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Kjo komandë shkruan skedar gjashtëkëndësh në kujtesën e mikrokontrolluesit. Shikoni videon me një përshkrim të hollësishëm të djegies së kujtesës flash të mikrokontrolluesit:

Memoria flash e mikrokontrolluesit po digjet…

Ne rregull! Tani, mikrokontrolluesi punon në përputhje me udhëzimet e programit tonë. Le ta kontrollojmë!

Hapi 6: Krijimi i qarkut elektrik

Bërja e qarkut elektrik
Bërja e qarkut elektrik
Bërja e qarkut elektrik
Bërja e qarkut elektrik
Bërja e qarkut elektrik
Bërja e qarkut elektrik

Lidhni komponentët në përputhje me diagramin skematik.

Recommended: