Սկիզբ » Ուսումնական նյութեր » Ծրագրավորում » Ծրագրավորման լեզուներ » C և C++ » Ապարատային PWM՝ լայնույթահաճախային մոդուլյաիցա, atmega8 միկրոկոնտրոլերի թայմերների ծրագրավորման միջոցով։

Ապարատային PWM՝ լայնույթահաճախային մոդուլյաիցա, atmega8 միկրոկոնտրոլերի թայմերների ծրագրավորման միջոցով։

| Փետրվար 10, 2013 | 5 Մեկնաբանություններ |

PWM կամ լայնույթահաճախային մոդուլյացիա – բեռի վրա լարման միջին արժեքի կառավարում ազդանշանի լայնույթահաճախային պարամետրերի կարգաբերման միջոցով։ Լարման կարգաբերման այս եղանակը, ի տարբերություն լարման բաժանարարի և տրանզիստորային սխեմաների հարմար է նրանով, որ ունի բավական բարձր օգգ և ցածր ջերմանջատում։ Միկրոկոնտրոլերի միջոցով pwm ազդանշան կարելի է ստանալ 2 հակադիր ճանապարհներով՝ ապարատային և ծրագրային։ Ապարատային pwm ազդանշանի ստացման համար պրոցեսորային ռեսուրսներ գրեթե չի օգտագործվում և բնականաբար դա թույլ է տալիս պրոցեսորային ռեսուրսները ծախսել այլ՝ ավելի կարևոր հաշվարկների համար։ Ինչպես հասկանալի է ծրագրային pwm-ը ի տարբերություն ապարատայինի ծախսում է պրոցեսորային ռեսուրսներ և հետևաբար դրա կիրառումը այդքան էլ նպատակահարմար չէ։

Այս հոդվածում մենք կգեներացնենք pwm ազդանշան atmega8 միկրոկոնտրոլերի միջոցով, բեռի՝ ասենք լուսադիոդի պայծառության կառավարման համար։ Pwm ազդանշանի դեպքում մուտքում ստացված ազդանշանը ելքում կերպափոխվում է ուղանկյունաձև ազդանշանների:

pwm2

Սկզբում ծանոթանանք pwm -ի գեներացման ռեգիստրներին․ atmega8 միկրոկոնտրոլերի համար դրանք հետևյալն են TCCR1A, TCCR1B, OCR1A, OCR1B, ICR1, TCNT1:Screenshot from 2013-02-10 10:54:03

 

 

 

7:6 բիթեր – COM1A1 կառավարում են OC1A ելքը, եթե COM1A1:0 բիթերից, որևիցե մեկը կամ երկուսն էլ միասին դրված են մեկ, ապա OC1A ելքը դադարում է սովորական ելք լինելուց և վերածվում է pwm ելքի,

5:4 բիթեր – COM1B1 կառավարում են OC1B ելքը, եթե COM1B1:0 բիթերից, որևիցե մեկը կամ երկուսն էլ միասին դրված են մեկ, ապա OC1B ելքը դադարում է սովորական ելք լինելուց և վերածվում է pwm ելքի,

2։1 բիթեր – WGM11, WGM10 բիթերի միջոցով TC1 թայմերի ռեժիմը բերվում է pwm -ի ռեժիմի։

Screenshot from 2013-02-10 10:54:58


Screenshot from 2013-02-10 10:53:07

Screenshot from 2013-02-10 10:55:37

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 մասերը։

Screenshot from 2013-02-10 10:55:43

Հիմա, երբ արդեն TCCR1B ռեգիստրում ընտրել ենք pwm հաճախությունը, թայմերի հաշվիչը սկսում է կարդալ և գրել հաշվիչի արժեքը TCNT1H  և TCNT1L ռեգիստրների մեջ, որոնք հաշվիչի ռեգիստրի կրտսեր և ավագ մասերն են։ Երբ հաշվիչը հաշվելով հասնում է 216 թվին, հաշվիչը նորից բերվում է զրոյական վիճակի և նորից սկսվում է հաշվարկը։ Այս ռեգիստրի մեջ կարող ենք գրել նաև ցանկացած այլ արժեք, որից հաշվիչը կարող է սկսել հաշվել։
TCCR1A ռեգիստրի միջոցով OC1A և OC1B ելքերը տալուց հետո, հաշվիչի ռեգիստրի արժեքը ամեն անգամ համեմատվում է OCR1A և OCR1B համեմատման ռեգիստրների արժեքի հետ։ OCR1A և OCR1B ռեգիստրներից յուրաքանչյուրը կազմված է 8 բիթանի կրտսեր և ավագ մասերից՝  OCR1AH և OCR1AL, OCR1BH և OCR1BL։ PWM ազդանշանի ցանկալի մեծությունը պետք է գրել հենց այս ռեգիստրներում։ Դրանցում անհրաժեշտ արժեքը գրելուց հետո, ամեն անգամ, երբ հաշվիչի ռեգիստրի արժեքը կհամընկնի համեմատման ռեգիստրների արժեքի հետ, OC1A և OC1B ելքերում կստանանք անհրաժեշտ փոփոխությունները։ ICR1 (ICR1H, ICR1L) ռեգիստրը ծառայում է, մուտքում որևէ փոփոխության դեպքում  ICP1 մուտքի գրավման համար, ըստ TCNT1 թայմերի։
Այս օրինակում մենք կստանանք 10 բիթանի, երկուղի, արագ pwm ազդանշան կամ ՝ Fast Pwm, 10 bit: Նայում ենք վերը բերված աղյուսակում 16-4՝ Fast Pwm, 10 bit և WGM13 բիթը 0-է, WGM12՝ 1, WGM11՝ 1, WGM10՝ 1։  Տալիս ենք TCCR1A ռեգիստրի արժեքը։ Նայում ենք  այս ռեգիստրի՝ վերը նկարագրված բիթերին։ Քանի որ pwm -ը երկուղի է մենք կունենանք 2 pwm ազդանշան՝ համապատասխանաբար PB1 կամ որ նույնն է OC1A և PB2 կամ որ նույնն է  OC1B ոտքերի վրա, հետևաբար TCCR1A ռեգիստրի 7, 5 բիթերը կլինեն 1։ 1 կլինեն նաև  WGM11 և WGM10 բիթերը, ինչպես և վերը նշել էինք։ Հետևաբար TCCR1A ռեգիստրը կունենա հետևյալ տեսքը՝
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-ական ներկայացմամբ։

Ենթադրենք մեզ պետք է ստանալ մուտքային ազդանշանի հզորության 70% -ի չափով ելքային մոդուլացված ազդանշան։ Դրա համար կատարում ենք հետևյալ հաշվարկները․

(1023/100)*70=716  և 716 (10-ական համակարգ) = 02D0 (16- ական համակարգ)։ Այժմ այս թիվը գրումե ենք  OCR1A և OCR1B ռեգիստրներում։ Հիշենք, որ OCR1A = OCR1AH & OCR1AL,  OCR1B = OCR1BH & OCR1BL և հետևաբար՝

OCR1AH = 0x02;
OCR1AL = 0xD0;

Նմանապես՝

OCR1BH = 0x02;
OCR1BL = 0xD0;
Այժմ ներկայացնենք ամբողջական firmware- ը որով պետք է ծրագրավորենք մեր միկրոկոնտրոլերը․
#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 ազդանշան ․

oscioloscop

Կարող էք փորձել, ռեալ աշխատող և բազմիցս փորձարկված է կոդ է բերված։

 

․P.S Ընդանհրապես ճիշտ կլիներ, որ համալսարաններում ծրագրավորողների պատրաստումն սկսեին միկրոկոնտրոլերների ուսումնասիրմամբ, ընդորում աչքաթող չանելով նաև ռեալ ժեշտի հետ շփման պրոցեսը։ Իմ կարծիքով ընդանհրապես ցանկացած իրեն հարգող ծրագրավորող պետք է բավարար մակարդակով գլուխ հանի էլեկտրոնիկայից (հա հա նույն դիոդներից ու դիֆերենցիալ ուժեղարարներից :) ) և իր կյանքում գոնե մեկ անգամ պետք է աշխատած լինի լրիվ մերկ ժեշտ հետ, անմիջականորեն դրա թայմերների, ընդհատումների և այլ նմանատիպ «վախենալու» բաների հետ ՝ առանց այլ և այլ միջնորդների՝ հանձինս տարբեր օպերացիոն համակարգերի։ Դրանից հետո ՀԱՍՏԱՏ չի մնա մեկը, որ վախենա ինչ-որ C/C++ ցուցիչներից (pointer) :), իսկ assembler -ի դասաժամերը և «վախենալու» անուններով տարբեր գրքերը կթվան հով եղանակին թեթև զբոսանք։

Ապարատային PWM՝ լայնույթահաճախային մոդուլյաիցա, atmega8 միկրոկոնտրոլերի թայմերների ծրագրավորման միջոցով։, 10.0 out of 10 based on 21 ratings

Նշագրեր: , , ,

Բաժին: C և C++, Ժեշտ, Ծրագրավորում

Կիսվել , տարածել , պահպանել

VN:F [1.9.20_1166]
Rating: 10.0/10 (21 votes cast)

Մեկնաբանություններ (5)

Թրեքբեք հղում | Մեկնաբանությունների RSS ժապավեն

  1. Խիստ ողջունելի է տեսնել միկրոկոնտրոլլերնեի մասին հոդված հայերեն:Ապրեք:
    իսկ հնարավոր է նմանատիպ հոդված գրեք ՊԻԿ երի մասին :
    և վերջապես մի հարց եվս : որ ծր. լեզվով եք նախընտրում գրել եվ ինչու հենց դրանով (ցանկանում եմ վերջնականապես կողմնորոշվել լեզվի և կոմպիլյատորի ընտրության հարցում)
    եվ վերջապես ինչով է <>-ն առավել <> միկրոկոնտրոլլերների ծրագրեր գրելու համար չհաշված մի քանի 10նյակով ավելի կրճատ կօդի գեներացիան
    Նախապես շնորհակալություն

  2. ուղղում
    եվ վերջապես ինչով է սի -ն առավել բեյսիկից միկրոկոնտրոլլերների ծրագրեր գրելու համար չհաշված մի քանի 10նյակով ավելի կրճատ կօդի գեներացիան

  3. Vardan_Grigoryan

    Նախ շնորհակալություն ձեզ նյութը կարդալու համար: 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 կոմպիլյատորով տեքստային ռեժիմում՝ տերմինալով աշխատելիս:

  4. Շնորհակալություն սպառիչ պատասխանի համար:
    Ավելացնեմ որ հարցս ձեզ ուղղելու պահին ես սկսւմ էի ուսւմնասիրել սի-ն ,ավելի ճիշտ
    Mikroelektronika ընկերության mikroC for PIC կոմպիլյատորը և միայն նրա համար որ համացանցում գրեթե բոլորը դրան էին անցնւմ : Չնայած իմ սկզբնական անհասկանալի պահերին այնուամենայնիվ ինձ հաջողվեց գրել պարզագույն սարքի ծրագիր որը հաջողությամբ փորձարկվեց Proteus ում: երեվի մոտ օրերս հոդված կգրեմ դրա մասին:

  5. Vardan_Grigoryan

    Շատ ողջունելի է: Նամանավանդ Proteus -ի օգտագործումը: Ընդանհրապես Proteus -ը բավական ռեալիստիկ սիմուլացման համակարգ է ու շատ որակյալ: Կան նաև multisim-ը, նույնպես շատ որակյալ ծրագրային միջավայր է, գործիքների բազմազանության տեսակետից նույնիսկ գերազանցում է Proteus -ին, բայց զիջում է Proteus -ին տարբեր տեսակի միկրոկոնտրոլերներ սիմուլացնելու ունակությամբ: Ընդ որում Multisim -ի առավելություններից մեկը, դա անալոգային էլէկտրոնիկայի շատ լավ ու ռեալիստիկ սումուլյացիան է, որտեղ Proteus -ը ակնհայտ զիջում է, փոխարենը Proteus -ի առավելությունը թվային և կոմբինացված սխեմաների շատ ռեալիստիկ սիմուլացման մեջ է:
    Շատ ուրախալի է, որ գնալով միկրոկոնտրոլերների, էլէկտրոնիկայի և ծրագրավոևրման մասին հոդվածները շատանում են: Վերջապես մենք դուրս ենք գալիս, մի վիճակից, երբ նյութեր էին գրվում միայն ծրագրավորման մասին, այնպիսի նյութեր, որոնց արժեքը հիմնականում տեսական բնույթ էր կրում: Միկրոկոնտրոլերների գործածումը ծրագրավորման գործընթացում, սխեմաների ինքնուրույն պատրաստումը միս ու արյուն է հաղորդում ծրագրավորմանը: Մի խոսքով ես շատ կողջունեմ և շատ ուրախ կլինեմ,եթե դուք էլ նմանատիպ թեմաներով հոդվածներ գրեք:

Մեկնաբանեք

179