տուն բազմամյա ծաղիկներ Ժամաչափ avr ստուդիայի օրինակներ. Ծրագրավորման միկրոկոնտրոլերներ AVR. OC0 ելքային հսկողություն

Ժամաչափ avr ստուդիայի օրինակներ. Ծրագրավորման միկրոկոնտրոլերներ AVR. OC0 ելքային հսկողություն

AT վերջին ժամանակներըԱվելի ու ավելի շատ սկսնակներ բախվում են ժմչփերի/հաշվիչների (այսուհետ՝ T/C) յուրացման խնդրի հետ միկրոկառավարիչների ուսուցման փուլում: Այս հոդվածում ես կփորձեմ փարատել այս մոդուլների վերաբերյալ վախերը և մատչելի կերպով բացատրել, թե ինչպես և ինչով են օգտագործվում հենց այդ T/S-ները:

Որպես հիմք մենք կվերցնենք մի գիրք, որը շատ տարածված է MK սարքերի մշակողների շրջանում, որը հեղինակել է A.V. Եվստիֆեև. Օգտագործելով հոդվածի վերջում գտնվող հղումները, կարող եք գտնել նախագիծը և նախագիծը: Այս հոդվածում մենք կվերլուծենք 8-բիթանոց T / C T2-ի աշխատանքը, որը T/C MK Atmega8-ի մի մասն է:

Այսպիսով, ինչ է ժմչփը/հաշվիչը: T/S-ը MK AVR մոդուլներից է, որով կարող եք չափել որոշակի ժամանակահատվածներ, կազմակերպել PWM և շատ այլ առաջադրանքներ։ Կախված MK-ի մոդելից, T/C-ի թիվը կարող է լինել 4 կամ ավելի: Դրա օրինակն է MK Atmega640x, 1280x/1281x, 2560x/2561x, որոնք իրենց տախտակի վրա պարունակում են 6 T/C՝ երկու 8-բիթանոց և չորս 16-բիթանոց: MK Atmega8-ը պարունակում է երեք T/C՝ T0 և T2՝ 8 բիթ հզորությամբ, T1՝ 16 բիթ:

Եկեք ավելի սերտ նայենք Atmega8 միկրոկառավարիչի T/C T2-ին:

Այս ժմչփը կարող է գործել մի քանի ռեժիմով՝ նորմալ, փուլային ճիշտ PWM, CTC (վերակայել համընկնման վրա), Արագ PWM: Դուք կարող եք ավելին կարդալ գրքում յուրաքանչյուր ռեժիմի մասին:

Այս T/C-ն բաղկացած է հսկիչ ռեգիստրից, հաշվիչ ռեգիստրից, համեմատական ​​ռեգիստրից, ասինխրոն ռեժիմի կարգավիճակի ռեգիստրից: T2-ի բլոկային դիագրամը ներկայացված է Նկար 1-ում

Եկեք տեսականորեն դիտարկենք, թե ինչպես է աշխատում այս մոդուլը: Որպեսզի ավելի պարզ լինի ձեզ համար, մենք չենք դիտարկի ժամանակաչափի բոլոր լրացուցիչ հարմարանքները և կդիտարկենք դրա ամենատարածված ռեժիմը` ՆՈՐՄԱԼ: Մենք ինքներս մեզ համար որոշում ենք, որ MK-ն ժամացույց է կատարում 1 ՄՀց հաճախականությամբ ներքին RC գեներատորից, և ժմչփը սահմանված է ՆՈՐՄԱԼ ռեժիմով աշխատելու համար:

Ժամացույցի իմպուլսները մուտքագրվում են clk i \ o և ընկնում են ժամանակաչափի նախնական սանդղակի մեջ: Prescaler-ը կարող է կազմաձևվել ըստ ձեր կարիքների՝ ժամացույցի իմպուլսները առաջ անցնելու կամ մուտքային իմպուլսները բաժանելու համար՝ անցնելով դրանց միայն որոշակի հատվածը: Դուք կարող եք մուտքային իմպուլսները բաժանել /8, /64, /256, /1024-ի: Քանի որ մեր T\C-ն կարող է աշխատել ասինխրոն ռեժիմով, երբ այն միացված է այս ռեժիմում, նախադիտողների թիվը զգալիորեն ավելանում է, բայց մենք դեռ չենք դիտարկի դրանք: Prescaler-ից ժամացույցի իմպուլսները մտնում են կառավարման միավոր և արդեն դրանից ընկնում են հաշվառման գրանցամատյան: Հաշվիչ ռեգիստրն իր հերթին աճում է յուրաքանչյուր մուտքային զարկերակի համար: Հաշվիչ ռեգիստրը T2 8-բիթանոց է, ուստի այն կարող է հաշվել միայն մինչև 255: Երբ հաշվիչ ռեգիստրը լցվում է, այն վերականգնվում է 0-ի և նորից սկսում է հաշվել նույն ցիկլում: Նաև հաշվիչ ռեգիստրի վարարման պահին սահմանվում է TIFR ռեգիստրի TOV2 դրոշը (հորդառատ ընդհատման դրոշ):

Հիմա, քանի որ մենք անդրադարձել ենք այնպիսի բառերի, ինչպիսին է ԳՐԱՆՑՎԵԼ, ժամանակն է ծանոթանալ դրանց։ Սկզբից մենք կանդրադառնանք միայն այն ռեգիստրներին, որոնց հետ ուղղակիորեն աշխատելու ենք, որպեսզի ուղեղը չխցանվի ավելորդ տեղեկություններով։

TCNT2-ը հաշվիչ ռեգիստր է, մենք արդեն խոսել ենք դրա աշխատանքի մասին։

TCCR2 - ժմչփի կառավարման ռեգիստր:

TIMSK - ընդհատման դիմակ ռեգիստր (Atmega8-ում այս ռեգիստրը միակն է բոլոր ժամանակաչափերի համար):

TIFR - ընդհատել դրոշի գրանցումը (Atmega8-ում այս ռեգիստրը եզակի է բոլոր ժամանակաչափերի համար):

Եվ հիմա յուրաքանչյուրի մասին մանրամասն.

Վերահսկիչ ռեգիստր TCCR2. Այս ռեգիստրի բովանդակությունը կարող եք տեսնել Նկ.2-ում:


նկ.2

0-2 բիթերը պատասխանատու են ժմչփի ժամացույցի համար: Այս բիթերում որոշակի համակցություններ սահմանելը սահմանում է այդ ժամանակաչափի նախնական սանդղակը: Եթե ​​բոլոր երեք բիթերը զրոյացված են, ժամանակաչափն անջատված է:

3,6 բիթերը պատասխանատու են ժմչփի շահագործման ռեժիմի համար:

4,5 բիթերը անհրաժեշտ են OSn-ի ելքի վարքագիծը կարգավորելու համար (այլ կերպ ասած՝ դրանք օգտագործվում են PWM-ը կարգավորելիս)

Եվ այս ռեգիստրի վերջին բիթը 7-րդ բիթն է: Դրանով մենք կարող ենք ուժով փոխել OSn-ի ելքի վիճակը:

Ընդհատման դիմակ ռեգիստրը TIMSK է: Մենք դա տեսնում ենք Նկար 3-ում:

Այս ռեգիստրից մեզ հետաքրքրում են միայն վերջին երկու բիթերը՝ 6-րդ և 7-րդ բիթերը: Այս բիթերով մենք միացնում ենք ընդհատումները:

6-րդ բիթը, եթե դրա վրա գրված է մեկը, հնարավորություն է տալիս ընդհատել «Overflow T \ C T2» իրադարձության վրա:

Բիթ 7, եթե դրան մեկ գրեսnitsa, հնարավորություն է տալիս ընդհատում «Հաշվող ռեգիստրի համընկնումը համեմատական ​​ռեգիստրի հետ» իրադարձության վրա:

Ընդհատել դրոշի գրանցամատյանը TIFR. Մենք դա տեսնում ենք Նկար 4-ում:

նկ.4

Այս ռեգիստրում մեզ հետաքրքրում են նաև վերջին երկու բիթերը՝ 6-րդ և 7-րդ բիթերը:

Բիթ 6 - դրոշակ, որը սահմանված է «Overflow T \ C T2» իրադարձության կողմից
Բիթ 7 - դրոշ, Տեղադրվել«Հաշվառական գրանցամատյանի համընկնումը համեմատական ​​գրանցամատյանի հետ» միջոցառման վերաբերյալ.

Այս բիթերը ինքնաբերաբար ջնջվում են, երբ ընդհատման կարգավորիչը դուրս է գալիս, բայց ապահով լինելու համար դրանք կարող եք մաքրել ինքներդ՝ վերակայելով այս բիթերը «0»-ի:

TIMSK և TIFR ռեգիստրների մնացած բիթերը օգտագործվում են T\C T0 և T1 կողմից: Ինչպես արդեն նկատել եք, նույնիսկ այս ռեգիստրների բիթերի անվանումները նույնն են, բացառությամբ անվան վերջում նշված թվի, որը ցույց է տալիս, թե որ ժամանակաչափի վրա է կիրառելի այս բիթը։

Մնում է դիտարկել երկու պարզ թիթեղներ, մասնավորապես՝ աղյուսակ, որը նկարագրում է ժամացույցի ազդանշանի կառավարումը (նկ. 6), և աղյուսակ, որը նկարագրում է, թե ինչպես ընդհանուր առմամբ կարգավորել ժամանակաչափը (նկ. 5):

Այն մասին, թե ինչ կա այս աղյուսակներում, ես գրել եմ վերևում, բայց դրանք բերում եմ ձեզ պարզության համար:

Այսպիսով, մենք ավարտեցինք տեսությունը, և ժամանակն է սկսել գործնական մասը: Անմիջապես վերապահում կանեմ։

ԺԱՄԱՑՈՄՆԵՐԸ, ՈՐՈՆՔ ԴՈՒՔ ՍՏԱՆՈՒՄ ԵՔ ԱՅՍ ՀՈԴՎԱԾԻ ՈՒՍՈՒՄՆԱՍԻՐՈՒԹՅԱՆ ԸՆԹԱՑՔՈՒՄ, ԲԱՐՁՐ ՃՇՇՏՈՒԹՅԱՆ ՉՈՒՆԵՆ։ ԱՅՍ ՀՈԴՎԱԾԸ ԿՈՂՄՆՈՐՈՇՎԱԾ Է ԺԱՄԱԽՈՍՆԵՐԻ ՀԵՏ ԱՇԽԱՏԱՆՔԻ ԸՆԴՀԱՆՈՒՐ ՍԿԶԲՈՒՆՔՆԵՐԻ ՎՐԱ:

Բացեք Studio 6-ը, ստեղծեք նախագիծ և ընտրեք Atmega8:

Հենց սկզբում մենք նշում ենք ժամացույցի հաճախականությունը և միացնում այն ​​գրադարանները, որոնք մեզ անհրաժեշտ են աշխատելու համար

< avr/io.h >#ներառում< avr/interrupt.h >

Առաջին տողում մենք նշում ենք հաճախականությունը: Սա անհրաժեշտ է, որպեսզի կոմպիլյատորը մեզ ավելի լավ հասկանա, եթե մենք հանկարծ ցանկանանք օգտագործել _delay_() ֆունկցիաները։

Կոդի երկրորդ տողում գրադարանը միացված է ընդհանուր նկարագրությունըմեր MK-ի գրանցամատյանները: Նաև դրանում ընթեռնելի անուններ են նշանակվում բոլոր ռեգիստրներին:

Երրորդ տողը միացնում է գրադարանը ընդհատումների վեկտորների հետ աշխատելու համար:

TIMSK |= (1< < TOIE2); TCCR2 |= (1< < CS22)|(1< < CS20); SREG |= (1< < 7);

Սա ավարտում է մեր ժամանակաչափի կարգավորումը: Եկեք ավելի սերտ նայենք կոդի վերջին երեք տողերին:

Առաջին տողում մենք միացրել ենք «T2 timer\counter overflow» իրադարձության ընդհատումները։

Եվ երրորդ տողում մենք գլոբալ կերպով միացրել ենք ընդհատումները: Կարելի էր նաև այսպես գրել.

Ասմ («սեյ»);

Մնում է ավելացնել ընդհատումների մշակիչը և մեր իրական ժամանակի ժամացույցի կոդը:

ISR (TIMER2_OVF_vect) ( takt++; if (takt>=4)(sek++; takt=0x00;) if (sek>=60) (min++; sek=0x00;) if (min>=60) (ժամ++; min=0x00;) ;) եթե (ժամ>=24) (ժամ=0x00);

Կոդում, որը գտնվում է ընդհատման կարգավորիչում, ձեզ համար ոչ մի բարդ և նոր բան չկա: Ուշադրություն դարձնենք միայն takt փոփոխականին և «4» կախարդական թվին։ Որտեղի՞ց այս թիվը: Եկեք մանրամասն նայենք այս կետին:

Մենք գիտենք, որ մեր MK-ն սնուցվում է 1 ՄՀց հաճախականությամբ ներքին գեներատորով, ժմչփը ժամացույց է կատարում նախասքանդերատորով \ 1024, մեր ժմչփը կարող է հաշվել մինչև 255: Իմանալով այս պարամետրերը, մենք կարող ենք հաշվարկել, թե քանի արտահոսք կկատարի այն: 1 վայրկյան

1 000 000 \ 1024 \ 256 = 3,814697.....

Դե, քանի որ մենք սովորում ենք աշխատել ժամանակաչափերով և նպատակ չենք դրել ստանալ գերճշգրիտ ժամացույցի արագություն, մենք կլորացնում ենք մեր արդյունքը և ստանում «4»: Նրանք. 1 վայրկյանում ժամանակաչափը կհեղեղի ~4 անգամ։

Ինչու՞ մենք բաժանեցինք 256-ի, եթե ժամանակաչափը հաշվում է մինչև 255: Որովհետև «0»-ը նույնպես թիվ է։ Կարծում եմ՝ այստեղ ամեն ինչ պարզ է։

Մի մոռացեք, որ բոլոր փոփոխականները պետք է հայտարարվեն որպես գլոբալ:

Ահա մեր ստացած ծրագրի ամբողջ ցանկը:

#սահմանել F_CPU 1000000UL #ներառել< avr/io.h >#ներառում< avr/interrupt.h >անստորագիր նիշ = 0; անստորագիր նիշ վրկ = 0; անստորագիր char min=0; անստորագիր char ժամ=0; ISR (TIMER2_OVF_vect) ( takt++; if (takt>=4)(sek++; takt=0x00;) if (sek>=60) (min++; sek=0x00;) if (min>=60) (ժամ++; min=0x00;) ;) եթե (ժամ>=24) (ժամ=0x00); ) հիմնական (անվավեր) (TIMSK |= (1)< < TOIE2); TCCR2 |= (1< < CS22)|(1< < CS20); SREG |= (1< < 7); while(1) { } }

Բայց ինչ վերաբերում է օգտագործողին տեղեկատվության ստացմանը: Եվ հետո ում դուր է գալիս: Դուք կարող եք օգտագործել յոթ հատվածի էկրաններ, գրաֆիկական կամ կերպարներ ստեղծող էկրաններ և այլն:

Արխիվում կգտնեք նախագիծ՝ էկրանի վրա տեղեկատվության ցուցադրմամբ nokia5110-ից, նախագիծ Proteus 7-ում և բոլորը: անհրաժեշտ ֆայլերև գրադարանների հետ աշխատելու համար:

Ձեր ուշադրությունն եմ հրավիրում այն ​​փաստի վրա, որ էկրանի հետ աշխատելու համար նախատեսված LCD_5110 գրադարանը գրվել է ֆորումի անդամի կողմից և տրամադրվել նրա թույլտվությամբ։

Այս ձեռնարկում մենք կխոսենք ժամանակաչափերի մասին:

Այս թեման ուղղակիորեն կապված է միկրոկոնտրոլերի ժամացույցի թեմայի հետ։ Ուստի խորհուրդ եմ տալիս այս դասը կարդալուց առաջ կարդալ նախորդը։

Այսպիսով, ինչու է մեզ անհրաժեշտ ժամանակաչափ:

Միկրոկարգավորիչների վրա նախագծեր կառուցելիս շատ հաճախ անհրաժեշտ է լինում ճշգրիտ ժամանակային միջակայքերը չափել: Օրինակ՝ LED-ը որոշակի հաճախականությամբ թարթելու կամ անհրաժեշտ ժամանակային ընդմիջումներով կոճակի վիճակը գնահատելու ցանկություն:

Ժամաչափերն են, որոնք օգնում են լուծել առաջադրանքները։ Բայց AVR միկրոկոնտրոլերների ժամանակաչափերը չգիտեն, թե ինչ է վայրկյանը, րոպեն, ժամը։ Այնուամենայնիվ, նրանք հիանալի գիտեն, թե ինչ է տակտը։ Նրանք աշխատում են հենց կարգավորիչի ժամացույցի առկայության շնորհիվ: Այսինքն, ժամանակաչափը հաշվում է վերահսկիչի ցիկլերի քանակը, դրանով իսկ չափելով ժամանակային ընդմիջումները: Ենթադրենք, կարգավորիչը աշխատում է 8 ՄՀց ժամացույցի հաճախականությամբ, այսինքն, երբ ժմչփը հաշվում է մինչև 8,000,000, կանցնի մեկ վայրկյան, հաշվելով մինչև 16,000,000, կանցնի 2 վայրկյան և այլն:

Այնուամենայնիվ, այստեղ գալիս է առաջին խոչընդոտը. Մենք ունենք 8-բիթանոց ռեգիստրներ, այսինքն՝ կարող ենք հաշվել առավելագույնը 255, իսկ 16-բիթանոց ժմչփ վերցնելով՝ առավելագույնը կհաշվենք մինչև 65535։ Այսինքն՝ մեկ վայրկյանում պետք է զրոյացնել ժմչփը։ մեծ գումարմեկ անգամ! Իհարկե, դուք կարող եք դա անել, եթե այլ բան չկա անելու: Բայց միայն հզոր միկրոկոնտրոլերի միջոցով ժամանակի չափումն ամենևին էլ հետաքրքիր չէ, ես ուզում եմ ավելին անել։ Այստեղ է, որ օգնության է հասնում նախասքալավորիչը: AT ընդհանուր տեսարանսա միջանկյալժամաչափի և կարգավորիչի ժամացույցի միջև: Prescaler-ը հեշտացնում է մեր խնդիրը՝ բաժանելով ժամացույցի հաճախականությունը որոշակի թիվնախքան այն ժամանակաչափին կերակրելը: Այսինքն՝ նախասքեյլերը դնելով 8-ի վրա, 1 վայրկյանում մեր ժմչփը 8 000 000-ի փոխարեն կհաշվի մինչև 1 000 000 (Իհարկե, 8 ՄՀց կարգավորիչի ժամացույցի հաճախականությամբ)։ Ավելի հետաքրքիր է, այնպես չէ՞: Եվ մենք կարող ենք բաժանել ոչ միայն 8-ի, այլև 64-ի և նույնիսկ 1024-ի։

Հիմա ժամանակն է հավաքել միացումը, կարգավորել մեր ժամանակաչափը, նախասքեյլերը և գոնե ինչ-որ օգտակար բան անել:

Եվ այսօր մենք կանենք «լույսեր» լուսադիոդներից: Այսինքն՝ հերթով կմիացնենք 3 լուսադիոդ՝ 0,75 վայրկյան ժամկետով (Այսինքն՝ մեկ LED-ի գործարկման ժամանակը 0,25 վայրկյան է)։ Եկեք միասին կազմենք հետևյալ դիագրամը.

Ինքներդ հաշվարկեք դիմադրության R 1-R 3 արժեքները:

Հաջորդը, հաշվի առեք ժամանակաչափերի աշխատանքի համար պատասխանատու ռեգիստրները: Ընդհանուր առմամբ AtMega 8-ը ներառում է 3 ժմչփ:Երկու 8-բիթանոց ժմչփ (Timer 0, Timer 2) և մեկ 16-bit ժմչփ (Timer 1):Մենք որպես օրինակ կդիտարկենք 16-bit timer 1-ը:

TCNT 1H և TCNT 1L 8-բիթանոց ռեգիստրները միասին կազմում են 16-բիթանոց TCNT 1 ռեգիստր: Այս ռեգիստրը բաց է ինչպես գրելու, այնպես էլ կարդալու համար: Երբ ժմչփ 1-ն աշխատում է, այս ռեգիստրի արժեքը փոխվում է մեկով յուրաքանչյուր հաշվարկով: Այսինքն, TCNT 1 ռեգիստրը պարունակում է ցիկլերի քանակը, որոնք հաշվել է ժամանակաչափը: Այստեղ կարող ենք գրել նաև ցանկացած թիվ 0-ից 2-ից մինչև 16-րդ աստիճանի միջակայքում։ Այս դեպքում ժամացույցի ցիկլերը կհաշվվեն ոչ թե 0-ից, այլ մեր գրանցած թվից։

TIMSK ռեգիստրը պատասխանատու է միկրոկոնտրոլերի ժամանակաչափերի աշխատանքի ընթացքում առաջացած ընդհատումների համար: Ընդհատում - կարգավորիչ հատուկ ազդանշանի համար, որը ստացվում է, երբ ինչ-որ բան փոխվում է. Միկրոկարգավորիչի ցանկացած ընդհատում կարելի է միացնել կամ անջատել: Երբ միացված ընդհատում է տեղի ունենում, հիմնական ծրագիրը ընդհատվում է, և ազդանշանը մշակվում է: Երբ անջատված ընդհատում է տեղի ունենում, ծրագրի հոսքը չի ընդհատվում, և ընդհատումն անտեսվում է: TOIE 1 բիթը (Timer 1 Overflow Interrupt Enable) պատասխանատու է ժմչփ 1-ի հաշվառման ռեգիստրի TCNT 1-ի արտահոսքի ընդհատումը միացնելու համար: Այս բիթում 1 գրելիս ընդհատումը միացված է, իսկ 0 գրելիս այն անջատված է: Այս ընդհատումը ստեղծվում է ժմչփ 1-ի կողմից, երբ առավելագույն արժեքըգրանցել TCNT 1. Ընդհատումների մասին ավելի շատ կխոսենք հաջորդ դասին:

Գրանցվել TCCR 1B-ը պատասխանատու է ժմչփ 1-ի կազմաձևման համար: այս դեպքը bits CS 10-CS 12 մենք սահմանում ենք նախնական սանդղակի արժեքը հետևյալ աղյուսակի համաձայն:

Մնացած հատվածները մեզ դեռ չեն հետաքրքրում։

Կա նաև TCCR 1A ռեգիստր, որը թույլ է տալիս կարգավորել ժամանակաչափի այլ ռեժիմներ, օրինակ՝ PWM, բայց դրանց մասին առանձին հոդվածում:

Եվ հիմա C կոդը.

#սահմանել F_CPU 16000000UL #ներառել #ներառում uint8_tnum=0; ISR(TIMER1_OVF_vect) (PORTD=(1<2) ( num=0; ) TCNT1=61630;//Ժամաչափի սկզբնական արժեքը) int main(void) (DDRD|=(1<

#սահմանել F_CPU 16000000UL

#ներառում

#ներառում

uint8_t num = ;

ISR (TIMER1_OVF_vect)

PORTD = (1<< num ) ;

թիվ ++;

եթե (թիվ > 2)

համարը = ;

TCNT1 = 61630; //ժմչփի սկզբնական արժեքը

int main (անվավեր)

DDRD |= (1<< PD0 ) | (1 << PD1 ) | (1 << PD2 ) ;

TCCR1B |= (1<< CS12 ) | (1 << CS10 ) ; //Prescaler = 1024

TIMSK |= (1<< TOIE1 ) ; //Միացնել ժմչփ 1-ի հորդառատ ընդհատումը

TCNT1 = 61630; //ժմչփի սկզբնական արժեքը

sei (); //Միացնել ընդհատումները

մինչդեռ (1)

// Ծրագրի հիմնական հանգույցը, այն դատարկ է, քանի որ ամբողջ աշխատանքը ընդհատման մեջ է

ASM կոդը:

Մոնտաժում (x86)

Ներառեք «m8def.inc» rjmp start .org OVF1addr rjmp TIM1_OVF մեկնարկ՝ ldi R16,LOW(RamEnd) դուրս SPL,R16 ldi R16,HIGH(RamEnd) դուրս SPH,R16 ldi R16,1 ldi R1010RDl դուրս, ldi R16,1 R17,0B00000101 Out TCCR1B, R17 LDI R17,0B11110000 OUT TCNT1H, R17 LDI R17,0B1011110 OUT TIMSK, R17 SEI MAIN_LOP: NOP RJMP MAIN_LOP. label_1 ldi R16,1 label_1. ldi R17,0b10111110 դուրս TCNT1L, R17 ldi R17,0b11110000 դուրս TCNT1H, R17 reti

Ներառեք «m8def.inc»

Rjmp սկիզբ

Org OVF 1addr

Rjmp TIM 1_OVF

սկիզբ:

Ldi R 16, LOW (RamEnd)

Դուրս SPL, R 16

Ldi R 16, HIGH (RamEnd)

Դուրս SPH, R 16

Ldi R 16, 1

Ldi R 17, 0b00000111

Դուրս DDRD, R 17

Ldi R 17, 0b00000101

Դուրս TCCR 1B, R 17

Ldi R 17, 0b11110000

Դուրս է գալիս TCNT 1H, R 17

Ldi R 17, 0b10111110

ATmega8 միկրոկոնտրոլերի առավելություններից է տարբեր ընդհատումների լայն շրջանակը:

Ընդհատելներկայացնում է իրադարձություն, որի առաջացման դեպքում հիմնական ծրագրի կատարումը կասեցվում է և կոչվում է ֆունկցիա, որը կարգավորում է որոշակի տեսակի ընդհատումը:

Ընդհատումները բաժանվում են ներքին և արտաքին: Ներքին ընդհատման աղբյուրները ներառում են ներկառուցված միկրոկառավարիչ մոդուլներ (ժմչփեր, USART հաղորդիչ և այլն): Արտաքին ընդհատումները տեղի են ունենում, երբ արտաքին ազդանշաններ են ստացվում միկրոկոնտրոլերի կապում (օրինակ, ազդանշաններ RESET և INT կապումներում): Ընդհատման առաջացմանը հանգեցնող ազդանշանների բնույթը սահմանվում է հսկիչ գրանցամատյանում MCUCR, մասնավորապես բիթերով - ISC00 (bit 0) և ISC01 (bit 1) INT 0 մուտքագրման համար; ISC10 (bit2) և ISC11 (bit3) INT1 մուտքագրման համար:

ATmega8 միկրոկոնտրոլերում յուրաքանչյուր ընդհատում ունի իր սեփականը ընդհատման վեկտոր(ծրագրի հիշողության տարածքի սկզբում գտնվող հասցեն, որը պահպանում է նշված ընդհատումների սպասարկման ռեժիմին անցնելու հրամանը): Mega8-ում բոլոր ընդհատումներն ունեն նույն առաջնահերթությունը: Մի քանի ընդհատումների միաժամանակյա առաջացման դեպքում նախ կմշակվի ստորին վեկտորային թվով ընդհատումը:

Ընդհատումների վեկտորները Atmega8-ում

Հասցե Ընդհատման աղբյուրը Նկարագրություն
0x0000 ՎԵՐԱԿԱՆԱՑՆԵԼ Վերականգնման ազդանշան
0x0001 INT0 Արտաքին ընդհատման հարցում INT0 մուտքագրման վրա
0x0002 INT1 Արտաքին ընդհատման հարցում INT1 մուտքագրման վրա
0x0003 T/C1 T/C1 ժմչփի գրավում
0x0004 T/C1 Համեմատեք T/C1 ժմչփի A ռեգիստրի հետ
0x0005 T/C1 Համեմատեք T/C1 ժամանակաչափի B ռեգիստրի հետ
0x0006 T/C1 Հաշվիչ արտահոսք T/C1
0x0007 T/C0 Հաշվիչ արտահոսք T/C0
0x0008 SPI SPI հաղորդակցությունն ավարտված է
0x0009 UART UART հաղորդիչի կողմից տվյալների ընդունումն ավարտված է
0x000A UART UART տվյալների ռեգիստրը դատարկ է
0x000B UART UART հաղորդիչն ավարտեց տվյալների փոխանցումը
0x000C ANA_COMP Անալոգային համեմատիչի ընդհատում

Ընդհատման հսկողություն

ATmega8-ում ընդհատումները կառավարելու համար պատասխանատու են 4 ռեգիստր.

GIMSK(aka GICR) - անջատել / միացնել ազդանշանների ընդհատումները INT0, INT1 մուտքերում

GIFR- բոլոր արտաքին ընդհատումների կառավարում

TIMSK, TIFR- ընդհատել կառավարումը ժամանակաչափերից/հաշվիչներից

Գրանցվել GIMSK (GICR)

INTFx=1. INTx մուտքագրում տեղի է ունեցել ընդհատում: Ընդհատումների ծառայության ռեժիմը մտնելուց հետո INTFx-ը ավտոմատ կերպով վերականգնվում է գրանցամատյանի վիճակին: 0

Գրանցվել TIMSK

7 6 5 4 3 2 1 0
TOIE1
OCIE1A
OCIE1B
-
TICIE
-
TOIE0
-

TOIE1=1 T/C1 արտահոսքի ընդհատումը միացված է

OCIE1A=1ընդհատում, երբ համեմատական ​​ռեգիստրը համապատասխանում է T/C1 հաշվիչի բովանդակությանը, միացված է

OCIE1B=1ընդհատում, երբ B ռեգիստրը համընկնում է միացված T/C1 հաշվիչի բովանդակությանը

TICIE=1թույլատրվում է ընդհատել, երբ գրավման պայմանը բավարարված է

TOIE0=1 T/C0 արտահոսքի ընդհատումը միացված է

Գրանցվել TIFR

7 6 5 4 3 2 1 0
TOV1
OCF1A
OCF1B
-
ICF1
-
TOV0
-

TOV1=1տեղի է ունեցել T/C1 արտահոսք

OCF1A=1Համեմատության ռեգիստր A-ը համապատասխանում է թույլատրված T/C1 հաշվիչի բովանդակությանը

OCF1B=1Համեմատության գրանցամատյան B համապատասխանեցված հաշվիչը T/C1 թույլատրվում է

ICF=1գրավման պայմանը պահպանված է

TOV0=1տեղի է ունեցել T/C0 արտահոսք

Ընդհատումների սպասարկման ռեժիմը մտնելուց հետո TIFR ռեգիստրում համապատասխան ընդհատման դրոշը ավտոմատ կերպով վերականգնվում է գրանցամատյանի վիճակի: 0

Ընդհատումները գործում են միայն այն դեպքում, երբ ընդհանուր ընդհատումները միացված են SREG կարգավիճակի ռեգիստրում (բիթ 7 = 1): Եթե ​​ընդհատում է տեղի ունենում, այս բիթն ինքնաբերաբար վերականգնվում է 0-ի՝ արգելափակելով հետագա ընդհատումների կատարումը:

Այս օրինակում INT0 փին միացված է pull-up մուտքագրման ռեժիմում: Երբ կոճակի միջոցով ելքը փակվում է գետնին, դրա վրա դրվում է log.0 (ազդանշանի եզրը սնուցման լարումից իջնում ​​է 0-ի), և ընդհատման կարգավորիչը գործարկվում է՝ միացնելով B պորտի զրոյական ելքին միացված լույսը։

void lampON()
{
PORTB.0=1;
DDRB.0=1;
}

ընդհատում void ext_int0_isr(անվավեր)
{
լամպON ();
}

DDRD.2=0;
PORTD.2=1;

SREG|= (1 իսկ (1) (

Վերոնշյալ օրինակը նաև ցույց է տալիս, թե ինչպես են ընդհատման վեկտորները սահմանվում Code Vision AVR-ում (interrupt void ext_int0_isr(void)): Ընդհատումների վեկտորները սահմանվում են նույն կերպ այլ դեպքերի համար.

EXT_INT0 2
EXT_INT1 3
TIM2_COMP 4
TIM2_OVF 5
TIM1_CAPT 6
TIM1_COMPA 7
TIM1_COMPB 8
TIM1_OVF 9
TIM0_OVF 10
SPI_STC 11
USART_RXC 12
USART_DRE 13
USART_TXC 14
AD_INT 15
EE_RDY 16
ANA_COMP 17
TWI 18
SPM_READY 19

Իրականում, միկրոկոնտրոլերի ժամանակաչափը թվային հաշվիչ է, միայն «շքեղ»: Հաշվիչի մուտքի վրա կիրառվում է ժամացույցի ազդանշան, որի հիման վրա հաշվիչը մեծացնում է իր արժեքը: Երբ տեղի են ունենում իրադարձություններ՝ հաշվիչի արտահոսք կամ դրա արժեքի համընկնում տվյալ մեկի հետ, առաջանում է ընդհատման հարցում:

Տեսնենք, թե ինչպես օգտագործել T0 ժմչփը Normal ռեժիմում: Այս ռեժիմում ժմչփը հաշվում է հաշվիչ ռեգիստրի որոշ սկզբնական արժեքից մինչև առավելագույն հնարավոր արժեքը (մինչև 255 կամ 0xFF): Երբ T0 ժմչփը հաշվում է առավելագույնը, ապա ժմչփի հաջորդ ցիկլում TCNT0 հաշվիչ ռեգիստրը հորդում է. այն զրոյացվում է և TOV0 դրոշակը դրվում է: Եթե ​​ծրագրում գլոբալ կերպով միացված են ընդհատումները (SREG ռեգիստրի դրոշ I) և ժմչփի T0 ընդհատումը գերհոսքի ժամանակ (դրոշակը՝ TIMSK ռեգիստրի TOIE0), ապա միկրոկառավարիչը կկանչի համապատասխան կարգավորիչին: Եթե ​​հաշվիչ ռեգիստրի արժեքը համընկնում է OCR0 համեմատական ​​ռեգիստրի հետ, ապա OCF0 դրոշը կսահմանվի, և եթե համընկնման իրադարձության ընդհատումը միացված է, դրա մշակիչը կգործարկվի:

Ժմչփ T0 նորմալ ռեժիմում

Դիտարկենք գործնական առաջադրանք. մենք պետք է կոճակը քվեարկենք յուրաքանչյուր 20 ms-ում: Միկրոկոնտրոլերի հաճախականությունը 8 ՄՀց, ATmega16 միկրոկոնտրոլեր:

Առաջին բանը, որ պետք է անել, դա ժամանակաչափի նախնական սանդղակի գործոնի ընտրությունն է և TCNT0 հաշվիչ ռեգիստրի սկզբնական արժեքը հաշվարկելը:

T0 ժմչփը կարող է հաշվվել միկրոկառավարիչի ներքին ժամացույցի ազդանշանից կամ արտաքինից, որը սնվում է T0 փին: Ներքին ժամացույցի ազդանշանից աշխատելիս օգտվողը կարող է ընտրել այս ազդանշանի հաճախականության բաժանման գործակիցները: T0 ժմչփն ունի հինգ հնարավոր նախածավալիչ գործոն՝ 1, 8, 64, 256, 1024:

Խնդիրը լուծելու համար ես վիճում եմ հետևյալ կերպ. Եթե ​​T0 ժմչփի մեկ ցիկլը ունենար 1 ms ժամանակաշրջան, ապա դա ինձ կհամապատասխանի: 20 ցիկլը տալիս է 20 ms: Ո՞րն է ժամանակաչափի նախնական սանդղակի հարաբերակցությունը 1 ms ժամացույցի ժամանակաշրջանին մոտենալու համար: Դուք կարող եք հաշվել.

Միկրոկարգավորիչի ժամացույցի հաճախականությունը Fcpu = 8000000 Հց
Միկրոկարգավորիչի ժամացույցի ժամանակահատվածը Tcpu = 1/Fcpu
Ժամաչափի ժամացույցի ժամանակահատվածը T0 է Tt0 = (1/Fcpu)/k = k/Fcpu

k = 1024-ով, ժամանակաչափի ժամացույցի ժամանակահատվածը T0 հավասար կլինի Tt0 = 1024/8000000 = 0,128 ms

Սա ժմչփի ժամացույցի առավելագույն ժամանակահատվածն է, որը մենք կարող ենք ստանալ մեր պայմաններում (Fcpu = 8 ՄՀց): Ավելի փոքր գործակիցների դեպքում ժամկետն էլ ավելի կարճ կլինի։

Լավ, ենթադրենք մեկ ժմչփ ցիկլը 0,128 մվ է, հաշվիչ ռեգիստրը կունենա՞ բավարար հզորություն այս ժամանակային միջակայքը հաշվելու համար և քանի՞ ցիկլ կպահանջվի: Պահանջվող ժամանակային միջակայքը (20 ms) բաժանում ենք ժմչփի մեկ ցիկլի տեւողության վրա եւ ստանում պատասխանը։

n = t/Tto = 20 ms/ 0,128 ms = 156,25

Կլորացնելով մի ամբողջություն՝ մենք ստանում ենք 156 ցիկլ: Սա 255-ից պակաս է (հաշվիչ ռեգիստրի առավելագույն արժեքը), ուստի TCNT0 հաշվիչ ռեգիստրի հզորությունը բավարար է:

TCNT0 հաշվիչ ռեգիստրի սկզբնական արժեքը հաշվարկվում է որպես T0 ժմչփ ցիկլերի առավելագույն քանակի և պահանջվողի միջև տարբերություն, այսինքն՝ 256 - 156 = 100: (256-ը ցանկացած 8-բիթանոց ժմչփի առավելագույն քանակն է: կարող է հաշվել)

Կարծում եմ, հիմա պարզ է, թե ինչպես կարելի է հաշվարկել TCNT0-ի սկզբնական արժեքը Normal ռեժիմի համար:

Հաշվարկել մեկ ժամանակաչափ ցիկլի ժամանակաշրջանը Tt0 = k/Fcpu,
- հաշվարկել անհրաժեշտ թվով ցիկլեր տվյալ ինտերվալի համար n = t/Tto,
- հաշվարկել TCNT0 հաշվառման ռեգիստրի սկզբնական արժեքը = 256 - n:

Դուք կարող եք ավտոմատացնել այս ընթացակարգը՝ օգտագործելով մակրոները: Օրինակ, այսպես.

#սահմանել F_CPU 8000000UL
#define TIME_MS(ժամանակ, k) (256L - ((ժամանակ)*(F_CPU))/(1000L*(k)))

Բայց նման մակրոյով դուք պետք է զգոն լինեք, ժամանակի և k-ի որոշակի արժեքների համար կարող են սխալներ առաջանալ:

Հիմա եկեք անցնենք ծածկագրին: T0 ժմչփ օգտագործելու համար (և ցանկացած այլ նույնպես), դուք պետք է կազմաձևեք (նախնականացնել) այն և նկարագրեք ընդհատման կարգավորիչը (եթե դրանք օգտագործվում են):

Ժամաչափի սկզբնավորումը բաղկացած է հետևյալ քայլերից.

կանգառի ժամանակաչափ,
- Նորմալ ռեժիմը դնելով TCCR0 առանց սկսելու,
- սահմանելով TCNT0-ի սկզբնական արժեքը,
- վերակայել դրոշները TIFR ռեգիստրում,
- միացնել արտահոսքի ընդհատումը TIMSK-ում,
- նախածավալիչը դնելով TCCR0-ին, այսինքն՝ ժամանակաչափի մեկնարկին

Այս հաջորդականությունը ենթակա է փոփոխության:

Մեր առաջադրանքի համար սկզբնականացման կոդը այսպիսի տեսք կունենա.


/*հաշվառման ռեգիստրի արժեք*/
#սահմանել T_POLL 100

TCCR0 = 0;
TCCR0 = (0<TCNT0=T_POLL;
TIFR = (1<TIMSK |= (1<TCCR0 |= (1<

Նախաստորագրման երկրորդ տողը, ըստ էության, անօգուտ է, այն ավելացված է պարզության համար: Հստակ տեսնելու համար, թե որ ժամաչափի ռեժիմն է կարգավորվում:

TIFR ռեգիստրում ընդհատման դրոշակները ջնջվում են՝ համապատասխան բիթում 1 գրելով:Այս գործողությունը պետք է կատարվի հենց ռեգիստրը վերաշարադրելու միջոցով, այլ ոչ թե օգտագործելով բիթային OR: Եվ ահա թե ինչու։

Ենթադրենք, TIFR ռեգիստրն ունի երկու ընդհատման դրոշակ՝ TOV1 և TOV0, սահմանված: TOV0 մենք պետք է վերակայենք: Պահանջվող բիթը OR-ով սահմանելիստեղի է ունենում հետևյալը.


//TIFR-ը 0b00000101 է
// դրոշների հավաքածու TOV1 և TOV0
//կոդը կատարվում է TIFR |= (1<
//TIFR-ը պատճենված է R16-ում
IN R16, 0x38

//R16 բիթում TOV0-ը սահմանված է
// չնայած այն արդեն տեղադրված է
ORI R16, 0x02

//R16, որը հավասար է 0b00000101-ին, գրված է TIFR ռեգիստրում
OUT 0x38, R16

Արդյունքում երկու դրոշներն էլ զրոյացված են, և մենք ուզում էինք վերակայել մեկը:

Մենք շարունակում ենք.

Ընդհատումների մշակիչները նկարագրելու շարահյուսությունը մի փոքր տարբերվում է տարբեր կոմպիլյատորների համար: IAR-ի համար T0 ժմչփի ընդհատման կարգավորիչը հորդառատ իրադարձության համար կունենա հետևյալ տեսքը.



{
TCNT0=T_POLL;

/*button հարցումը պետք է լինի այստեղ*/

TIMER0_OVF_vect-ը հորդառատ իրադարձության ընդհատման վեկտորի հասցեն է: Այն վերցված է միկրոկառավարիչի վերնագրի ֆայլերից: Այս դեպքում ես այն վերցրել եմ iom16.h ֆայլից։

Վերահսկիչի առաջին տողը (TCNT0 = T_POLL;) վերագրում է հաշվիչ ռեգիստրը, այնուհետև սահմանում է դրա սկզբնական արժեքը: Եթե ​​դա չկատարվի, ժմչփը կշարունակի հաշվել 0-ից: Հաշվիչ ռեգիստրի վերագրումը պետք է կատարվի ընդհատման կարգավորիչի սկզբում:

Մեր առաջադրանքի ամբողջ ծածկագիրը նման տեսք կունենա. (Կոդը նախատեսված է IAR-ի համար: Այլ կոմպիլյատորների համար դուք պետք է փոխեք վերնագրի ֆայլերը և ընդհատումների մշակիչը):

#ներառում
#ներառում
#ներառում

#սահմանել T_POLL 100

int main (անվավեր)
{
/*ժմչփի սկզբնավորում*/

TCCR0 = 0;
TCCR0 = (0<TCNT0=T_POLL;
TIFR |= (1<TIMSK |= (1<TCCR0 |= (1<

/*մնացած ծայրամասային սարքերի սկզբնավորում*/
DDRB |= (1<

enable_interrupt();
while (1);

/* ընդհատման կարգավորիչ T0
արտահոսքի իրադարձություն*/
#պրագմա վեկտոր = TIMER0_OVF_vect
__interrupt void TimerT0Ovf(անվավեր)
{
/*վերագրել հաշվառման գրանցամատյանը*/
TCNT0=T_POLL;

/*կոճակի հարցում*/

/*invert PB0 վրիպազերծման համար*/
PORTB ^= (1<

OC0 ելքային հսկողություն

Նորմալ ռեժիմում T0 ժմչփը կարող է փոխել OC0 փին-ի վիճակը, երբ հաշվառման գրանցամատյանը և համեմատական ​​ռեգիստրը համընկնում են: Եվ նույնիսկ առանց ընդհատումների: Կառավարման տարբերակները սահմանվում են TCCR0 ռեգիստրի COM01 և COM00 բիթերով:

Ահա մի ծրագրի օրինակ, որը ստեղծում է քառակուսի ալիք OC0-ի վրա:

#ներառում
#ներառում

int main (անվավեր)
{
/*նախաձեռնել ժամանակաչափ T0*/

TCCR0 = 0;
TCCR0 = (0<TCNT0 = 0;
OCR0 = 0;
TIMSK = 0;
TCCR0 |= (1<

/*նախաձեռնել OC0*/
DDRB |= (1<

Մինչդեռ (1);
վերադարձ 0;
}

Ելքային OS0-ն իր վիճակը կփոխի հակառակը հաշվիչ ռեգիստրի զրոյական արժեքով:

Մի քանի կետ ժմչփի օգտագործման մասին

Ժամաչափի ընդհատման կարգավորիչը (և ցանկացած այլ ծայրամասային սարք) պետք է հնարավորինս կարճ լինի:

Եթե ​​հաշվիչ ռեգիստրի (կամ համեմատական ​​ռեգիստրի) համար հաշվարկված արժեքը կլորացվում է, ապա ժամանակի միջակայքը կհաշվվի ժամանակաչափի կողմից սխալմամբ:

Եվ վերջինը. Կարող է պատահել, որ ժմչփի ընդհատման մշակումը հետաձգվի (օրինակ՝ մեկ այլ կառավարչի մեղքով) և TCNT0 ռեգիստրն արդեն մի քանի ցիկլ է հաշվել։ Եթե ​​դուք պարզապես վերագրեք TCNT0-ի արժեքը, ապա հաջորդ ընդհատումը կկանչվի ավելի ուշ, քան անհրաժեշտ է: Ստացվում է, որ նախորդ (հետաձգված) և նոր ընդհատումները չեն դիմանա պահանջվող միջակայքին:

Այս իրավիճակը կարելի է հարթել՝ հաշվիչ ռեգիստրը վերագրելով այսպես.

TCNT0 = TCNT0 + startValue;

Հաշվիչ ռեգիստրի ընթացիկ արժեքը սկզբնականացված ռեգիստրին ավելացնելով՝ հաշվի կառնվեն այս լրացուցիչ ցիկլերը:Ճիշտ է, կա մեկ ԲԱՅՑ! StartValue-ի մեծ արժեքների դեպքում ավելացման գործողությունը կարող է հանգեցնել հաշվիչի ռեգիստրի վարարման:

Օրինակ, startValue = 250, իսկ ժամանակաչափը հասցրել է հաշվել մինչև 10: Այնուհետև գումարման գործողությունը կհանգեցնի հետևյալ արդյունքին.

10 + 250 = 260

260-ից վերցնում ենք 8 բիթ, ստանում ենք 4: TCNT0-ին կգրվի 4-ը:


AVR միկրոկարգավորիչների ժմչփաչափեր (իրական ժամանակի ժամացույց): AVR Դաս 7

Երբ դեռ սկսում էի ուսումնասիրել միկրոկոնտրոլերները, ուզում էի պատրաստել. Անկեղծ ասած, ես ուզում էի փորձել հեռուստացույցը միացնել միայն 7-ից 8 ժամ, իսկ մնացած ժամանակ այն պետք է անջատվեր։ Ես սարքել եմ, բայց չեմ օգտագործել այն...

Բոլոր AVR միկրոկառավարիչներն ունեն մի քանի ներկառուցված ժամաչափ: Նրանք կարող են նաև բաժանվել ընդհանուր նշանակության ժամանակաչափերի և հսկիչ ժմչփի, որը նախատեսված է MK-ն վերագործարկելու համար, երբ այն սառչում է:

Ընդհանուր նշանակության ժամանակաչափերը կարող են.

  • Ժամացույցը արտաքին ժամացույցի քվարցից 32768 հերց հաճախականությամբ
  • Հաշվեք տարբեր ժամանակային ընդմիջումներ
  • Հաշվեք արտաքին իմպուլսները հաշվիչ ռեժիմում
  • Ստեղծեք PWM ազդանշան MK-ի որոշակի կապում
  • Ստեղծեք ընդհատումներ ինչ-որ իրադարձության վրա, օրինակ՝ հորդառատ ժամանակ

Ժամաչափերի հաշվիչները կարող են հաշվվել ներքին ժամացույցի գեներատորից և հաշվիչի մուտքագրումից: Եկեք նայենք atmega8 միկրոկոնտրոլերում ժմչփ-հաշվիչ 1-ի ֆունկցիոնալությունը: Մենք գործարկում ենք CodeVision AVR-ն, ստեղծում ենք նոր նախագիծ և համաձայնում ենք Code WizardAVR-ի գործարկման առաջարկին

Եկեք օգտագործենք timer2-ի օրինակը՝ իրական ժամանակի ժամացույցը իրականացնելու համար, որը թողարկվում է LCD էկրանին, դրա համար մենք սահմանում ենք ժամանակաչափը, ինչպես ցույց է տրված սքրինշոթում:

այստեղ դրված է ժմչփի արտաքին ժամացույցի աղբյուրը, որպես արտաքին աղբյուր կօգտագործենք ժամացույցի քվարցը 32768 հերց հաճախականությամբ, այնուհետև նախասքեյլերը կդնենք 128, այսինքն՝ ժամանակաչափը կաշխատի 32768/128=256 հաճախականությամբ, իսկ հաշվող ռեգիստրը 8 բիթանոց է (առավելագույն թիվը 255), պարզվում է, որ վայրկյանը մեկ կհեղեղի, հետո նշում ենք Overflow interrupt-ի կողքի վանդակը և սեղմում ենք. ֆայլ-> Ստեղծել, պահպանել և դուրս գալ:

Code Wizard-ը ստեղծել է այս կոդը

#ներառում // Timer2-ի արտահոսքի ընդհատման ծառայության սովորական ընդհատում void timer2_ovf_isr(void) ( ) void main(void) ( // Մուտքի/Ելքի նավահանգիստների սկզբնավորում // B պորտի սկզբնավորում PORTB=0x00; DDRB=0x00; // Port C սկզբնավորում PORTC=0x00; DDRC=0x00; // Դ պորտի սկզբնավորում PORTD=0x00; DDRD=0x00; // Ժամաչափ/Հաշվիչ 0 սկզբնավորում // Ժամացույցի աղբյուր՝ Համակարգի Ժամացույց // Ժամացույցի արժեքը՝ Ժամաչափ 0 Դադարեցված TCCR0=0x00; TCNT0=0x00; // Ժամաչափ /Հաշվիչի 1 սկզբնավորում // Ժամացույցի աղբյուր՝ Համակարգի Ժամացույց // Ժամացույցի արժեքը՝ 125,000 կՀց // Ռեժիմ՝ Արագ PWM top=00FFh // OC1A ելք՝ Discon. // OC1B ելք՝ Discon. // Noise Canceler՝ Off // Մուտք Նկարում ընկնող եզրին // Ժամաչափ 1 հորդառատ ընդհատում. Անջատված // Ներածման նկարահանման ընդհատում. անջատված ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Ժամաչափ/Հաշվիչ 2 սկզբնավորում // Ժամացույցի աղբյուր՝ TOSC1 փին // Ժամացույցի արժեքը՝ PCK2/1: Նորմալ վերև = FFh // OC2 ելք՝ Անջատված ASSR=0x08; TCCR2=0x05; TCNT2=0x00; OCR2=0x00; // Արտաքին ընդհատում(ներ)ի սկզբնավորում // INT0: Off // INT1: Off MCUCR=0x00; // Ժամաչափ(ներ)/Հաշվիչ(ներ) Ընդհատում(ներ)ի սկզբնավորում TIMSK=0x40; // Անալոգային համեմատիչի սկզբնավորում // Անալոգային համեմատիչ՝ անջատված // Անալոգային համեմատիչի մուտքագրում ժամանակաչափով/հաշվիչով 1՝ անջատված ACSR=0x80; SFIOR=0x00; // Global enable ընդհատում է #asm("sei") while (1) ( ); )

#ներառում #ներառում // Ալֆան-թվային LCD մոդուլի գործառույթները #asm .equ __lcd_port=0x12 ;PORTD #endasm #include անստորագիր char second=0; //փոփոխական՝ վայրկյանների անստորագիր char minute=0 պահելու համար; //փոփոխական րոպեները պահելու համար անստորագիր char ժամ=0; //փոփոխական՝ ժամերի պահպանման համար char lcd_buffer; // փոփոխական բուֆեր էկրանին ելքի համար // Timer2-ի արտահոսքի ընդհատման սպասարկման ռեժիմի ընդհատում void timer2_ovf_isr(void) (եթե (++second==59) // ավելացրեք վայրկյանների քանակը 1-ով և ստուգեք հավասարությունը 59 (երկրորդ = 0): ; եթե (+ +րոպե==59) (րոպե = 0; եթե (++ժամ==59) (ժամ = 0; ) ) ) lcd_clear(); // մաքրել ցուցադրումը նախքան lcd_gotoxy (0,0) ցուցադրելը; / /սահմանել կուրսորը x=0 y=0 sprintf(lcd_buffer,"%i:%i:%i",hour,minute,second); // ձևավորել ելքային տողը lcd_puts(lcd_buffer); // ցուցադրել տողը ) void main( void) ( // Ժամաչափ/Հաշվիչ 2 սկզբնավորում // Ժամացույցի աղբյուր՝ TOSC1 փին // Ժամացույցի արժեքը՝ PCK2/128 // Ռեժիմ՝ Նորմալ վերև=FFh // OC2 ելք՝ Անջատված ASSR=0x08; TCCR2=0x05; TCNT2=0x00; OCR2=0x00; // Ժամաչափ(ներ)/Հաշվիչ(ներ) Ընդհատում(ներ)ի սկզբնավորում TIMSK=0x40; // LCD մոդուլի սկզբնավորում lcd_init(16); // Համաշխարհային ակտիվացման ընդհատումներ #asm("sei") մինչդեռ (1) ();)

Ծրագիրը պատրաստ է, հիմա Պրոտեուսում գծենք դիագրամ

Նոր տեղում

>

Ամենահայտնի