PWM կամ լայնույթահաճախային մոդուլյացիա – բեռի վրա լարման միջին արժեքի կառավարում ազդանշանի լայնույթահաճախային պարամետրերի կարգաբերման միջոցով։ Լարման կարգաբերման այս եղանակը, ի տարբերություն լարման բաժանարարի և տրանզիստորային սխեմաների հարմար է նրանով, որ ունի բավական բարձր օգգ և ցածր ջերմանջատում։ Միկրոկոնտրոլերի միջոցով pwm ազդանշան կարելի է ստանալ 2 հակադիր ճանապարհներով՝ ապարատային և ծրագրային։ Ապարատային pwm ազդանշանի ստացման համար պրոցեսորային ռեսուրսներ գրեթե չի օգտագործվում և բնականաբար դա թույլ է տալիս պրոցեսորային ռեսուրսները ծախսել այլ՝ ավելի կարևոր հաշվարկների համար։ Ինչպես հասկանալի է ծրագրային pwm-ը ի տարբերություն ապարատայինի ծախսում է պրոցեսորային ռեսուրսներ և հետևաբար դրա կիրառումը այդքան էլ նպատակահարմար չէ։
Այս հոդվածում մենք կգեներացնենք pwm ազդանշան atmega8 միկրոկոնտրոլերի միջոցով, բեռի՝ ասենք լուսադիոդի պայծառության կառավարման համար։ Pwm ազդանշանի դեպքում մուտքում ստացված ազդանշանը ելքում կերպափոխվում է ուղանկյունաձև ազդանշանների:
Սկզբում ծանոթանանք pwm -ի գեներացման ռեգիստրներին․ atmega8 միկրոկոնտրոլերի համար դրանք հետևյալն են TCCR1A, TCCR1B, OCR1A, OCR1B, ICR1, TCNT1:
7:6 բիթեր – COM1A1 կառավարում են OC1A ելքը, եթե COM1A1:0 բիթերից, որևիցե մեկը կամ երկուսն էլ միասին դրված են մեկ, ապա OC1A ելքը դադարում է սովորական ելք լինելուց և վերածվում է pwm ելքի,
5:4 բիթեր – COM1B1 կառավարում են OC1B ելքը, եթե COM1B1:0 բիթերից, որևիցե մեկը կամ երկուսն էլ միասին դրված են մեկ, ապա OC1B ելքը դադարում է սովորական ելք լինելուց և վերածվում է pwm ելքի,
2։1 բիթեր – WGM11, WGM10 բիթերի միջոցով TC1 թայմերի ռեժիմը բերվում է pwm -ի ռեժիմի։
7 բիթ – ICP1 ելքում ազդանշանի ցատկերի ճնշում։ Երբ այս բիթը դրված է 1, ապա ICP1 ելքում ազդանշանը տրվում է 4 մեքենայական տակտ ուշացումով,
6 բիթ – ICES1 ընդհատումների ակտիվացում, ըստ ազդանշանի ճակատի։ Եթե դրված է մեկ, ապա ընդհատում է լինում ազդանշանի աճման ճակատի դեպքում, 0՝ հակառակ դեպքում,
4:3 բիթեր – WGM1 3:2 բիթերի միջոցով՝ հաշվի առնելով նաև TCCR1A ռեգիստրի WGM1 1:0 բիթերը, թայմերի ռեժիմը բերվում է pwm -ի ռեժիմի,
2։0 բիթեր – CS12, CS11, CS10 տակտավորման ընտրություն, կախված այս բիթերից, pwm ազդանշանի հաճախությունը կարող է կազմել տակտային գեներատորի ազդանշանի հաճախության 1, 1/8, 1/64, 1/256 և 1/1024 մասերը։
TCCR1A = 0b10100011 // 0xA3;
Նմանապես տալիս ենք նաև TCCR1B ռեգիստրի արժեքը․ նայում ենք դրա 7, 6, 5 բիթերը չենք օգտագործում հետևաբար դրանց տեղում կգրենք 0։ WGM13 և WGM12 բիթերը ինչպես վերը նայել էինք աղյուսակից Fast Pwm, 10 bit ռեժիմի համար համապատասխանաբար 0 և 1 են՝ WGM13 = 1 և WGM12 = 1: Այժմ պետք է ընտրենք հաշվարկենք հաճախության գործակիցը, դրա համար օգտվում ենք հետևյալ բանաձևից՝
N = F/(2*TOP*f), որտեղ F -ը միկրոկոնտրոլերի տակտավորման հաճախությունն է, մեր դեպքում 16 Mghz կամ 16000000 հց, f -ը OCR1A (OCR1B) -ի արժեքը (տես ստորև OCR1A և OCR1B ռեգիստրների հաշվարկը), մեր դեպքում 02D0 կամ 720, TOP -ի արժեքը վերցնում ենք 16-4 աղյուսակից fast pwm, 10 bit ռեծիմի համար, այն հավասար է 03FF -ի կամ 1023:
Հետևաբար կստանանք՝
N = 16000000/(2*1023*720) = 10.86 և վերցնում ենք դրան ամենամոտ թիվը՝ 8։
Վերցնում ենք 16-5 աղյուսակում N=8 բաժանարարով տողում գրված CS12, CS11, CS10 բիթերի արժեքները և գրում TCCR1B ռեգիստրի համապատասխանաբար 2, 1 և 0 բիթերում՝ 0, 1, 0։
Այսպիսով TCCR1B ռեգիստրը կունենա հետևյալ տեսքը՝ 00001010 ( սկզբից 3 հատ 0՝ 000 + WGM13=0, WGM12=1, CS12 = 0, CS11 = 1, CS10 = 0)․
TCCR1B = 0b00001010; // 0xA;
Ինչպես նշեցինք pwm ազդանշանի մեծությունը տալու համար պետք է գրել OCR1A և OCR1B ռեգիստրներում։ Դրա համար 0-1023 միջակայքից վերցնում ենք մեզ անհրաժեշտ թիվը և գրում ենք OCR1A և OCR1B ռեգիստրներում՝ 16-ական ներկայացմամբ։
(1023/100)*70=716 և 716 (10-ական համակարգ) = 02D0 (16- ական համակարգ)։ Այժմ այս թիվը գրումե ենք OCR1A և OCR1B ռեգիստրներում։ Հիշենք, որ OCR1A = OCR1AH & OCR1AL, OCR1B = OCR1BH & OCR1BL և հետևաբար՝
OCR1AH = 0x02; OCR1AL = 0xD0;
Նմանապես՝
OCR1BH = 0x02; OCR1BL = 0xD0;
#include <avr/io.h> #include <util/delay.h> void main(void) { DDRB=0b00000110 // PB1 և PB2 պորտերի ուղղությունը դնում ենք ելքային TCCR1B = 0x00 // նախնական ինիցիալիզացիա ICR1H = 0x01; ICR1L = 0xFF; TCCR1A = 0xA3; TCCR1B = 0b00001010; OCR1AH = 0x02; OCR1AL = 0xD0; OCR1BH = 0x02; OCR1BL = 0xD0; while(1) { OCR1AH = 0x02; OCR1AL = 0xD0; OCR1BH = 0x02; OCR1BL = 0xD0; } }
Կամ կոդի դուբլիկացիայից խուսափելու համար կարող ենք գրել հետևյալ կերպ․
#include <avr/io.h> #include <util/delay.h> void main(void) { DDRB=0b00000110; TCCR1B = 0x00; ICR1H = 0x01; ICR1L = 0xFF; TCCR1A = 0xA3; // 10100011 TCCR1B = 0b00001010; OCR1AH = 0x02; OCR1AL = 0xD0; OCR1BH = 0x02; OCR1BL = 0xD0; while(1) {} }
Արդյունքում միկրոկոնտրոլերի PB1 (OC1A) և PB2 (OC1B) ելքերից կստանանք 2 հատ 10 բիթանի արագ pwm ազդանշան ․
Կարող էք փորձել, ռեալ աշխատող և բազմիցս փորձարկված է կոդ է բերված։
․P.S Ընդանհրապես ճիշտ կլիներ, որ համալսարաններում ծրագրավորողների պատրաստումն սկսեին միկրոկոնտրոլերների ուսումնասիրմամբ, ընդորում աչքաթող չանելով նաև ռեալ ժեշտի հետ շփման պրոցեսը։ Իմ կարծիքով ընդանհրապես ցանկացած իրեն հարգող ծրագրավորող պետք է բավարար մակարդակով գլուխ հանի էլեկտրոնիկայից (հա հա նույն դիոդներից ու դիֆերենցիալ ուժեղարարներից 🙂 ) և իր կյանքում գոնե մեկ անգամ պետք է աշխատած լինի լրիվ մերկ ժեշտ հետ, անմիջականորեն դրա թայմերների, ընդհատումների և այլ նմանատիպ «վախենալու» բաների հետ ՝ առանց այլ և այլ միջնորդների՝ հանձինս տարբեր օպերացիոն համակարգերի։ Դրանից հետո ՀԱՍՏԱՏ չի մնա մեկը, որ վախենա ինչ-որ C/C++ ցուցիչներից (pointer) :), իսկ assembler -ի դասաժամերը և «վախենալու» անուններով տարբեր գրքերը կթվան հով եղանակին թեթև զբոսանք։
Խիստ ողջունելի է տեսնել միկրոկոնտրոլլերնեի մասին հոդված հայերեն:Ապրեք: իսկ հնարավոր է նմանատիպ հոդված գրեք ՊԻԿ երի մասին : և վերջապես մի հարց եվս : որ ծր. լեզվով եք նախընտրում գրել եվ ինչու հենց դրանով (ցանկանում եմ վերջնականապես կողմնորոշվել լեզվի և կոմպիլյատորի ընտրության հարցում) եվ վերջապես ինչով է <>-ն առավել <> միկրոկոնտրոլլերների ծրագրեր գրելու համար չհաշված մի քանի 10նյակով ավելի կրճատ կօդի գեներացիան Նախապես շնորհակալություն
ուղղում եվ վերջապես ինչով է սի -ն առավել բեյսիկից միկրոկոնտրոլլերների ծրագրեր գրելու համար չհաշված մի քանի 10նյակով ավելի կրճատ կօդի գեներացիան
Նախ շնորհակալություն ձեզ նյութը կարդալու համար: PIC միկրոկոնտրոլերներին ծանոթ չեմ, բայց կարծում եմ, որ ճարտարապետության հավանական տարբերություններից բացի (չեք կարող միևնույն asembler ով դրանք ծրագրավորել, այդպիսի assember չկա և դրա համար էլ այն assembler է կոչվում :) ), զուտ ծրագրավորման տեխնոլոգիայի տեսակետից (մասնավորոպես c-ով կամ basic-ով) շատ մեծ և առանցքային տարբերություններ չեն լինի PIC և Avr միկրոկոնտրոլերների միջև (չհաշված գրադարանների, ֆունկցիաների անունների և այլ տարբերությունները): Լեզվի և կոմպիլյատորի ընտրության մասին ասեմ հետրյալը: Լեզուն, որով գրում եմ firmware -ները, մաքուր C-ն է:Կոմպիլյատորները տարբեր են: Երբ նոր էի սկսում (անգամ հիմա, երբեմն) օգտագործում էի CvAvr -ը (CodeVisionAvr) windows -ի տակ: CvAvr -ը իրենից ներկայացնում է ANSI C կոմպիլյատոր և միաժամանակ նաև IDE: Ունի բազմաթիվ հաճելի հատկություններ հատկապես սկսնակների համար, այն է կոդի սկզբնական գեներացիան, պարզ ու հասկանալի ինտերֆեյսը: Հետո, երբ ավելի լուրջ սկսեցի զբաղվել միկրոկոնտրլերներով, անցում կատարեցի linux ՕՀ և սկսեցի օգտագործել gcc կոմպիյատորը, որը նորից C -ի կոմպիլյատոր է: Ինչով է C- ն ավելի լավը քան basic -ը ? :) : Ընդանհրապես, basic-ը ստեղծվել էր ուսումնական նպատակների համար, այն օգտագործում էին ոչ ծրագրավորողները հիմնականում փոքր ծրագրեր գրելու համար: Չնայած bacis -ի ժամանակակից տարբերակները լուրջ զարգացում են ապրել, բայց այնուամենայնիվ այդ լեզուն չի կարելի համեմատել այնպիսի գերհզոր լեզվի հետ ինչպիսին է C -ն մի քանի պատճառներով: Նախ basic ով դուք չեք կարող ուղղակիորեն հասանելիություն ունենալ հիշողությանը, ինչի հնարավորությունը տալիս են C-ական ցուցիչները (pointer), մեծ կախվածությունը օպերացիոն համակարգից. փաստացի basic-ը գործում է միայն windows և mac os-երի վրա (կան նաև linux օհ-ի վրա որոշ տարբերակներ, բայց ոչ մի լուրջ բան դրանք իրենից չեն ներկայացնում), C -ական անհամար, բազմաթիվ գրադարաններ կան այդ թվում նաև միկրոկոնտրոլերների համար, C-ով գրված ծրագրերը և C-ական կոմպիլյատորները անհամեմատ ավելի օպտիմալ են, մի խոսքով էլ չթվեմ :) : Basic -ը հիմնականում ոչ ծրագրավորողների համար է, փոքր ծրագրեր գրելու համար: Չնայած նրա դիալեկտներից մեկը՝ Visual Basic -ը բավական զարգացած է, դրանով են իրենց ծրագրեը գրում նաև մի քանի հայկական բավական հայտնի ընկերություններ, բայց այնուամենայնիվ Visual Basic-ի ամենաթույլ կողմը՝ runtime library -ի կիրառումն է ու դրա հետևանքով աշխատանքի արագության զգալի նվազումը: Իսկ կոնկրետ միկրոկոնտրոկլերների դեպքում, երբ հիշողության ծավալները անհամեմատ փոքր են, իսկ պայմանները գրեթե էքստրեմալ, օպտիմիզացիոն նպատակներով նույնպես չարժէ basic -ով գրել: Ինչ վերաբերվում է ձեր ասած մեծ ծավալով կոդի նախնական գեներացիային, ապա խնդրեմ, եթե դա չեք ուզում, կարող եք և ինքնրեդ գրել ողջ կոդը. համենայն դեպս չկա մի բան, որը կարող է ձեզ խանգարել, որպեսզի ձեր կոդը ամբողջությամբ գրեք դուք ինքներդ՝ առանց կոդի գեներացիայի: Եվ հետո հակադարձ հարցը. ինչու basic, եթե կա ամնեկարող C -ն :) ?: Մի խոսքով լավ կլինի, որ դուք կողմնորոշվեք դեպի C -ն և գրեք հենց այդ լեզվով (PIC կլինի, թե Avr կապ չունի): Pic-երի համար չեմ կարող ասել, բայց եթե աշխատում եք Atmel -ի միկրոկոնտրոլերների հետ windows -ում, կոմպիլյատորի առումով ամենահարմար տարբերակներն են CvAvr -ը, winavr-ը և AvrStudion-ն: Առաջինը, ինչպես արդեն ասացի, ունի իր սեփական ANSI C կոմպիլյատորը, իսկ վերջին երկուսը օգտագործում են GCC կոմպիլյատորը (ի դեպ եթե C-ով եք գրելու, ապա Pic ի համար էլ կարող էք օգտագործել gcc կոմպիլյատորը, ընդհանրապես gcc -ն ահավոր տարածված կոմպիլատոր է և դրանից պրծում չկա :) ): Եվ իմ խորհուրդը հետևյալն է՝ օգտագործեք GCC կոմպիլյատորի հիմքով միջավայրեր միկրոկոնտրոլերների ծրագրավորման համար: gcc -ն կպած չէ որևէ պլատֆորմի, այսինքն բազմապլատֆորմային է, դրանով դուք կարող էք ծրագրավորել նաև linux-ում (էլ չասեմ որ linux -ի հարազատ C կոմպիլյատորն է): Մյուս կողմից CvAvr-ը շատ հարմար է օգտագործել կոդի նախնական գեներացիայի առումով: Լավ կլինի երկու միջավայրերով էլ աշխատեք և AvrStudion-ով և CvAvr -ով:Linux-ի տակ կարող եք կոդը գրել ցանկացած տեքստային խմբագրիչի մեջ և կոմպիլացնել gcc կոմպիլյատորով տեքստային ռեժիմում՝ տերմինալով աշխատելիս:
Շնորհակալություն սպառիչ պատասխանի համար: Ավելացնեմ որ հարցս ձեզ ուղղելու պահին ես սկսւմ էի ուսւմնասիրել սի-ն ,ավելի ճիշտ Mikroelektronika ընկերության mikroC for PIC կոմպիլյատորը և միայն նրա համար որ համացանցում գրեթե բոլորը դրան էին անցնւմ : Չնայած իմ սկզբնական անհասկանալի պահերին այնուամենայնիվ ինձ հաջողվեց գրել պարզագույն սարքի ծրագիր որը հաջողությամբ փորձարկվեց Proteus ում: երեվի մոտ օրերս հոդված կգրեմ դրա մասին:
Շատ ողջունելի է: Նամանավանդ Proteus -ի օգտագործումը: Ընդանհրապես Proteus -ը բավական ռեալիստիկ սիմուլացման համակարգ է ու շատ որակյալ: Կան նաև multisim-ը, նույնպես շատ որակյալ ծրագրային միջավայր է, գործիքների բազմազանության տեսակետից նույնիսկ գերազանցում է Proteus -ին, բայց զիջում է Proteus -ին տարբեր տեսակի միկրոկոնտրոլերներ սիմուլացնելու ունակությամբ: Ընդ որում Multisim -ի առավելություններից մեկը, դա անալոգային էլէկտրոնիկայի շատ լավ ու ռեալիստիկ սումուլյացիան է, որտեղ Proteus -ը ակնհայտ զիջում է, փոխարենը Proteus -ի առավելությունը թվային և կոմբինացված սխեմաների շատ ռեալիստիկ սիմուլացման մեջ է: Շատ ուրախալի է, որ գնալով միկրոկոնտրոլերների, էլէկտրոնիկայի և ծրագրավոևրման մասին հոդվածները շատանում են: Վերջապես մենք դուրս ենք գալիս, մի վիճակից, երբ նյութեր էին գրվում միայն ծրագրավորման մասին, այնպիսի նյութեր, որոնց արժեքը հիմնականում տեսական բնույթ էր կրում: Միկրոկոնտրոլերների գործածումը ծրագրավորման գործընթացում, սխեմաների ինքնուրույն պատրաստումը միս ու արյուն է հաղորդում ծրագրավորմանը: Մի խոսքով ես շատ կողջունեմ և շատ ուրախ կլինեմ,եթե դուք էլ նմանատիպ թեմաներով հոդվածներ գրեք: