- Čo je to signál PWM?
- Programovanie PIC na generovanie PWM na pinoch GPIO
- Schéma zapojenia
- Simulácia
- Hardvérové nastavenie pre riadenie servomotora pomocou mikrokontroléra PIC
Generovanie signálu PWM je dôležitým nástrojom v každom arzenáli zabudovaných inžinierov. Sú veľmi užitočné pre mnoho aplikácií, ako je riadenie polohy servomotora, prepínanie niekoľkých výkonových elektronických integrovaných obvodov v prevodníkoch / invertoroch a dokonca aj pre jednoduché riadenie jasu LED. V mikrokontroléroch PIC je možné generovať signály PWM pomocou modulov Porovnať, Zachytiť a PWM (CCP) nastavením požadovaných Registrov, ako sme to dosiahli, sme sa už naučili v návode PIC PWM. Táto metóda však má jednu značnú nevýhodu.
PIC16F877A môže generovať PWM signál iba na pinoch RC1 a RC2, ak budeme používať moduly CCP. Ale môžeme sa stretnúť so situáciami, keď potrebujeme viac pinov, aby sme mali funkčnosť PWM. Napríklad v mojom prípade chcem ovládať 6 RC servomotorov pre môj projekt robotického ramena, pre ktoré je CCP modul beznádejný. V týchto scenároch môžeme naprogramovať piny GPIO na produkciu signálov PWM pomocou časovacích modulov. Týmto spôsobom môžeme generovať toľko PWM signálov s akýmkoľvek požadovaným pinom. Existujú aj ďalšie hardvérové hacky, ako napríklad použitie multiplexora IC, ale prečo investovať do hardvéru, keď to isté možno dosiahnuť programovaním. V tomto výučbe sa teda naučíme, ako previesť pin PIC GPIO na pin PWM, a aby sme ho otestovali, simulujeme ho na proteuse pomocou digitálneho osciloskopu a tiežovládať polohu servomotora pomocou signálu PWM a meniť jeho pracovný cyklus zmenou potenciometra.
Čo je to signál PWM?
Než sa dostaneme do podrobností, poďme si trochu oprášiť to, čo sú PWM signály. Pulzná šírková modulácia (PWM) je digitálny signál, ktorý sa najčastejšie používa v riadiacich obvodoch. Tento signál je nastavený na vysokú (5v) a nízku (0v) v preddefinovanom čase a rýchlosti. Čas, počas ktorého signál zostáva vysoký, sa nazýva „čas zapnutia“ a čas, počas ktorého signál zostáva nízky, sa nazýva „čas vypnutia“. Ďalej sú uvedené dva dôležité parametre pre PWM:
Pracovný cyklus PWM
Percento času, v ktorom signál PWM zostáva VYSOKÝ (v čase), sa nazýva pracovný cyklus. Ak je signál stále ZAPNUTÝ, je v 100% pracovnom cykle a ak je vždy vypnutý, je to 0% pracovný cyklus.
Pracovný cyklus = čas zapnutia / (čas zapnutia + čas vypnutia)
Názov premennej |
Odkazuje na |
PWM_Frequency |
Frekvencia signálu PWM |
T_TOTAL |
Celkový čas potrebný na jeden úplný cyklus PWM |
T_ON |
V čase signálu PWM |
T_OFF |
Čas vypnutia signálu PWM |
Pracovný cyklus |
Pracovný cyklus signálu PWM |
Takže poďme na matematiku.
Toto sú štandardné vzorce, kde frekvencia predstavuje iba prevrátený čas. Hodnotu frekvencie musí rozhodnúť a nastaviť užívateľ na základe svojej požiadavky na aplikáciu.
T_TOTAL = (1 / PWM_Frequency)
Keď používateľ zmení hodnotu pracovného cyklu, náš program by mal podľa toho automaticky upraviť čas T_ON a čas T_OFF. Vyššie uvedené vzorce teda možno použiť na výpočet T_ON na základe hodnoty Duty_Cycle a T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Pretože celkový čas signálu PWM pre jeden celý cyklus bude súčtom času zapnutia a vypnutia. Ako je uvedené vyššie, môžeme vypočítať čas vypnutia T_OFF.
T_OFF = T_TOTAL - T_ON
S ohľadom na tieto vzorce môžeme začať programovať mikrokontrolér PIC. Program zahŕňa modul časovača PIC a modul PIC ADC na vytvorenie signálu PWM založeného na meniacom sa pracovnom cykle podľa hodnoty ADC z POT. Ak ste v používaní týchto modulov nováčikom, dôrazne sa odporúča prečítať si príslušný návod kliknutím na hypertextové odkazy.
Programovanie PIC na generovanie PWM na pinoch GPIO
Kompletný program pre tento kurz možno nájsť na spodnej časti webovej stránky, ako vždy. V tejto časti pochopíme, ako je program vlastne napísaný. Ako všetky programy, aj my začneme nastavením konfiguračných bitov. Použil som možnosť zobrazenia pamäte, aby mi ju nastavil.
// KONFIGURÁCIA #pragma config FOSC = HS // Bity pre výber oscilátora (HS oscilátor) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT deaktivovaný) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT deaktivované) #pragma config BOREN = ZAPNUTÉ // Brown-out Reset Povoliť bit (povolené BOR) #pragma config LVP = OFF // Nízkonapäťové (jednoduché napájanie) Sériové programovanie v obvode Povoliť bit (RB3 je digitálny I / O, Na programovanie je potrebné použiť HV na MCLR) #pragma config CPD = OFF // bit ochrany kódu EEPROM dát (ochrana kódu EEPROM dát vypnutá) #pragma config WRT = OFF // zápis do pamäte programu Flash Povolenie bitov (ochrana proti zápisu vypnutá; všetka programová pamäť môže byť zapísaná ovládaním EECON) #pragma config CP = OFF // Bit kódu ochrany kódu pamäte programu (ochrana kódu vypnutá) // #pragma config príkazy by mali predchádzať zahrnutiu súboru projektu. // Použite enums projektu namiesto #define na ZAPNUTIE a VYPNUTIE. #include
Potom spomenieme taktovú frekvenciu použitú v hardvéri, tu môj hardvér používa kryštál 20 MHz, môžete zadať hodnotu na základe vášho hardvéru. Nasleduje hodnota frekvencie signálu PWM. Keďže je mojím cieľom riadiť hobby RC servomotor, ktorý vyžaduje frekvenciu PWM 50 Hz, nastavil som ako hodnotu frekvencie 0,05 kHz, môžete to tiež zmeniť podľa svojich požiadaviek na aplikáciu.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0,05 // v KHz (50Hz)
Teraz, keď máme hodnotu Frequency, môžeme vypočítať T_TOTAL pomocou vyššie diskutovaných vzorcov. Výsledok sa vydelí číslom 10, aby sa získala hodnota času v milisekundách. V mojom prípade bude hodnota T_TOTAL 2 milisekundy.
int T_TOTAL = (1 / PWM_Frequency) / 10; // výpočet celkového času z frekvencie (v mil. s)) // 2 ms
Potom inicializujeme moduly ADC na čítanie polohy potenciometra, ako je popísané v našom výučbe ADC PIC. Ďalej tu máme rutinu prerušenia služby, ktorá sa bude volať zakaždým, časovač pretečie, k tomu sa vrátime neskôr, teraz si poďme skontrolovať hlavnú funkciu.
Vo vnútri hlavnej funkcie konfigurujeme modul časovača. Tu som nakonfiguroval modul časovača na pretečenie každých 0,1 ms. Hodnotu času je možné vypočítať pomocou nasledujúcich vzorcov
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) oneskorenie v sekundách a Fosc v hz
V mojom prípade by pre oneskorenie 0,0001 sekundy (0,1ms) s prescalarom 64 a Fosc na 20MHz mala byť hodnota môjho registra (TMR0) 248. Konfigurácia teda vyzerá takto
/ ***** Konfigurácia portu pre časovač ****** / OPTION_REG = 0b00000101; // Timer0 s externými frekvenciami a 64 ako predkallar // Tiež umožňuje PULL UPs TMR0 = 248; // Načítanie časovej hodnoty za 0,0001 s; delayValue môže byť medzi 0-256 iba TMR0IE = 1; // Povoliť bit prerušenia časovača v registri PIE1 GIE = 1; // Povoliť globálne prerušenie PEIE = 1; // Povoliť prerušenie periférie / *********** ______ *********** /
Potom musíme nastaviť vstupnú a výstupnú konfiguráciu. Tu používame pin AN0 na čítanie hodnoty ADC a piny PORTD na výstup signálov PWM. Inicializujte ich teda ako výstupné piny a pomocou nasledujúcich riadkov kódu ich znížte.
/ ***** Konfigurácia portu pre I / O ****** / TRISD = 0x00; // Inštruujte MCU, aby všetky piny na PORT D boli na výstupe PORTD = 0x00; // Inicializujte všetky piny na 0 / *********** ______ *********** /
Vo vnútri nekonečnej while slučky musíme z pracovného cyklu vypočítať hodnotu on time (T_ON). Čas zapnutia a pracovný cyklus sa líši podľa polohy POT, takže to robíme opakovane vo vnútri while slučky, ako je uvedené nižšie. 0,0976 je hodnota, ktorú treba vynásobiť 1024, aby sme dostali 100, a pre výpočet T_ON sme ju vynásobili 10, aby sme dostali hodnotu v milisekundách.
while (1) { POT_val = (ADC_Read (0)); // Načítaj hodnotu POT pomocou ADC Duty_cycle = (POT_val * 0,0976); // Mapa 0 až 1024 až 0 až 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Vypočítajte On Time pomocou jednotky vzorcov v milisekundách __delay_ms (100); }
Pretože je časovač nastavený na nadmerný tok každých 0,1 ms, bude sa každých 0,1 ms volať servisná rutina prerušenia časovača ISR. Vo vnútri servisnej rutiny používame premennú zvanú count a zvyšujeme ju každých 0,1ms. Takto môžeme sledovať čas. Ak sa chcete dozvedieť viac informácií o prerušeniach v mikrokontroléri PIC, kliknite na odkazy
if (TMR0IF == 1) // Bol spustený príznak časovača kvôli pretečeniu časovača -> nastavený na pretečenie každých 0,1ms { TMR0 = 248; // Načítanie časovača Hodnota TMR0IF = 0; // Vymazať počet príznakov prerušenia časovača ++; // Počet prírastkov každých 0,1 ms -> počet / 10 poskytne hodnotu počtu v ms }
Nakoniec je čas prepnúť pin GPIO na základe hodnoty T_ON a T_OFF. Máme premennú count, ktorá sleduje čas v milisekundách. Pomocou tejto premennej teda skontrolujeme, či je čas kratší ako čas , ak áno, potom ponecháme pin GPIO zapnutý, inak ho vypneme a vypneme, kým nezačne nový cyklus. To sa dá urobiť porovnaním s celkovou dobou jedného cyklu PWM. Kód, ktorý urobí to isté, je uvedený nižšie
if (count <= (T_ON)) // Ak je čas kratší ako čas RD1 = 1; // Zapnite GPIO else RD1 = 0; // V opačnom prípade vypnite GPIO if (count> = (T_TOTAL * 10)) // Ponechajte vypnuté, kým nezačne nový cyklus count = 0;
Schéma zapojenia
Schéma zapojenia pre generovanie PWM s pinom GPIO mikrokontroléra PIC je naozaj jednoduchá, stačí napájať PIC oscilátorom a pripojiť potenciometer na pin AN0 a servomotor na pin RD1, na získanie signálu PWM môžeme použiť pin GPIO, vybral som RD1 iba náhodne. Potenciometer aj servomotor sú napájané z 5 V, ktoré sú regulované z 7805, ako je to znázornené na schéme zapojenia.
Simulácia
Na simuláciu projektu som použil softvér proteus. Vytvorte obvod zobrazený nižšie, prepojte kód so svojou simuláciou a spustite ho. Mali by ste dostať signál PWM na kolík RD1 GPIO podľa nášho programu a pracovný cyklus PWM by sa mal riadiť na základe polohy potenciometra. Nižšie uvedený GIF ukazuje, ako signál PWM a servomotor reagujú, keď sa hodnota ADC zmení pomocou potenciometra.
Hardvérové nastavenie pre riadenie servomotora pomocou mikrokontroléra PIC
Moje kompletné nastavenie hardvéru je zobrazené nižšie. Pre ľudí, ktorí sledujú moje výukové programy, by táto doska mala vyzerať dobre. Je to rovnaká doska, ktorú som doteraz používal vo všetkých svojich výučbách. Ak sa chcete dozvedieť, ako ho zostavím, môžete si prečítať návod na blikanie LED. Inak postupujte podľa schémy zapojenia vyššie a všetko by malo fungovať dobre.
Nahrajte program a nastavte potenciometer. Mali by ste vidieť, ako servo mení polohu na základe polohy potenciometra. Úplné fungovanie projektu je uvedený vo videu danej na konci tejto stránky. Dúfam, že ste projektu porozumeli a stavanie sa vám páčilo, ak máte otázky, neváhajte ich uverejniť na fóre a ja sa v odpovediach pokúsim.
Mám v pláne posunúť tento projekt vpred pridaním možností ovládania viacerých servomotorov a tým pádom z toho vybudovať robotické rameno, podobné robotickému ramenu Arduino, ktoré sme už postavili. Takže dovtedy sa uvidíme !!