- Ano ang isang PWM Signal?
- Programming PIC upang makabuo ng PWM sa GPIO Pins
- Diagram ng Circuit
- Kunwa
- Pag-setup ng Hardware para sa pagkontrol sa Servo Motor gamit ang PIC Microcontroller
Ang pagbuo ng signal ng PWM ay isang mahalagang tool sa bawat naka-embed na arsenal ng mga inhinyero, napakahusay para sa maraming mga application tulad ng pagkontrol sa posisyon ng servo motor, paglipat ng ilang mga elektronikong IC IC sa mga converter / invertor at kahit para sa isang simpleng kontrol ng ilaw ng LED. Sa PIC microcontrollers PWM signal ay maaaring mabuo gamit ang mga Compare, Capture at PWM (CCP) na mga module sa pamamagitan ng pagtatakda ng kinakailangang Mga Rehistro, natutunan na namin kung paano gawin iyon sa tutorial ng PIC PWM. Ngunit may isang malaking sagabal sa pamamaraang iyon.
Ang PIC16F877A ay maaaring makabuo ng mga signal ng PWM lamang sa mga pin RC1 at RC2, kung gagamitin namin ang mga module ng CCP. Ngunit maaaring nakatagpo kami ng mga sitwasyon, kung saan kailangan namin ng maraming mga pin upang magkaroon ng pag-andar ng PWM. Halimbawa sa aking kaso, nais kong makontrol ang 6 RC servo motor para sa aking robotic na proyekto ng braso na kung saan ang module ng CCP ay walang pag-asa. Sa mga sitwasyong ito maaari naming mai- program ang mga GPIO pin upang makagawa ng mga signal ng PWM gamit ang mga module ng timer. Sa ganitong paraan makakabuo kami ng maraming mga signal ng PWM na may anumang kinakailangang pin. Mayroon ding iba pang mga pag-hack sa hardware tulad ng paggamit ng multiplexer IC, ngunit bakit namuhunan sa hardware kung magkatugma ang magkakamit kahit na ang pag-program. Kaya sa tutorial na ito matututunan natin kung paano i-convert ang isang PIC GPIO pin sa isang PWM pin at upang subukan ito ay gayahin namin ito sa proteus gamit ang digital oscilloscope at pati na rinkontrolin ang posisyon ng motor ng Servo gamit ang signal ng PWM at ibahin ang cycle ng tungkulin nito sa pamamagitan ng pag-iiba ng isang potensyomiter.
Ano ang isang PWM Signal?
Bago namin makuha ang mga detalye, magsipilyo muna tayo sa kung ano ang mga PWM Signal. Ang Pulse Width Modulation (PWM) ay isang digital signal na karaniwang ginagamit sa control circuitry. Ang signal na ito ay nakatakda nang mataas (5v) at mababa (0v) sa isang paunang natukoy na oras at bilis. Ang oras kung saan mananatiling mataas ang signal ay tinatawag na "on time" at ang oras kung saan mananatiling mababa ang signal ay tinatawag na "off time". Mayroong dalawang mahalagang mga parameter para sa isang PWM tulad ng tinalakay sa ibaba:
Pag-ikot ng tungkulin ng PWM
Ang porsyento ng oras kung saan ang signal ng PWM ay mananatiling TAAS (sa oras) ay tinawag bilang duty cycle. Kung ang signal ay laging ON ito ay nasa 100% na cycle ng tungkulin at kung palaging naka-off ito ay 0% na cycle ng tungkulin.
Duty Cycle = I-ON ang oras / (I-ON ang oras + I-OFF ang oras)
Pangalan ng variable |
Tumutukoy sa |
PWM_Frequency |
Dalas ng PWM Signal |
T_TOTAL |
Kinuha ang kabuuang oras para sa isang kumpletong cycle ng PWM |
TONELADA |
Sa oras ng signal ng PWM |
T_OFF |
Patay na oras ng PWM signal |
Duty_ motorsiklo |
Pag-ikot ng tungkulin ng signal ng PWM |
Kaya ngayon, gawin natin ang matematika.
Ito ang pamantayang mga pormula kung saan ang dalas ay simpleng kapalit ng oras. Ang halaga ng dalas ay kailangang magpasya at itakda ng gumagamit batay sa kanyang kinakailangan sa aplikasyon.
T_TOTAL = (1 / PWM_Frequency)
Kapag binago ng gumagamit ang halaga ng cycle ng Duty, dapat na awtomatikong ayusin ng aming programa ang oras ng T_ON at oras ng T_OFF alinsunod dito. Kung gayon ang mga formula sa itaas ay maaaring magamit upang makalkula ang T_ON batay sa halaga ng Duty_Cycle at T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Dahil ang Kabuuang oras ng signal ng PWM para sa isang buong cycle ay ang kabuuan ng oras at off time. Maaari naming kalkulahin ang off time na T_OFF tulad ng ipinakita sa itaas.
T_OFF = T_TOTAL - T_ON
Sa pag-iisip ng mga formula na ito maaari nating simulan ang pagprogram ng PIC microcontroller. Ang programa ay nagsasangkot ng PIC Timer Module at PIC ADC Module upang lumikha ng isang signal ng PWM batay sa iba't ibang cycle ng tungkulin ayon sa form ng halaga ng ADC na POT. Kung bago ka sa paggamit ng mga modyul na ito, masidhing inirerekomenda na basahin ang naaangkop na tutorial sa pamamagitan ng pag-click sa mga hyperlink.
Programming PIC upang makabuo ng PWM sa GPIO Pins
Ang kumpletong programa para sa tutorial na ito ay matatagpuan sa ilalim ng website tulad ng lagi. Sa seksyong ito, intindihin natin kung paano talaga nakasulat ang programa. Tulad ng lahat ng mga programa, nagsisimula kami sa pamamagitan ng pagtatakda ng mga bit ng mga pagsasaayos. Ginamit ko ang pagpipilian ng mga view ng memorya upang itakda ito para sa akin.
// CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Paganahin ang bit (hindi pinagana ang WDT) #pragma config PWRTE = OFF // Power-up Timer Paganahin ang bit (PWRT hindi pinagana) #pragma config BOREN = ON // Brown-out Reset Paganahin ang bit (pinagana ang BOR) #pragma config LVP = OFF // Mababang Boltahe (Single-Supply) In-Circuit Serial Programming Paganahin ang bit (ang RB3 ay digital I / O, Dapat gamitin ang HV sa MCLR para sa pagprograma) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Proteksyon ang code ng EEPROM code) #pragma config WRT = OFF // Flash Program Memory Sumulat Paganahin ang mga bits (Isulat ang proteksyon; lahat ng memorya ng programa ay maaaring isinulat ng kontrol ng EECON) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Proteksyon ang code off) // Ang mga pahayag ng #pragma config ay dapat na mauna sa proyekto ng file na kasama. // Gumamit ng mga enum ng proyekto sa halip na # tukuyin para sa ON at OFF. # isama
Pagkatapos ay binabanggit namin ang dalas ng orasan na ginamit sa hardware, narito ang aking hardware ay gumagamit ng 20MHz na kristal, maaari mong ipasok ang halaga batay sa iyong hardware. Sinusundan niyan ang halaga ng dalas ng signal ng PWM. Dahil ang aking hangarin dito upang makontrol ang isang libangan RC servo motor na nangangailangan ng dalas ng PWM na 50Hz na itinakda ko na 0.05KHz bilang halagang Frequency maaari mo ring baguhin ito batay sa iyong mga kinakailangan sa aplikasyon.
#define _XTAL_FREQ 20000000 # tukuyin ang PWM_Frequency 0.05 // sa KHz (50Hz)
Ngayon, na mayroon kaming halaga ng Frequency maaari naming kalkulahin ang T_TOTAL gamit ang mga tinalakay na pormula sa itaas. Ang resulta ay sumisid ng 10 upang makuha ang halaga ng oras sa milli segundo. Sa aking kaso ang halaga ng T_TOTAL ay magiging 2 milli segundo.
int T_TOTAL = (1 / PWM_Frequency) / 10; // kalkulahin ang Kabuuang Oras mula sa dalas (sa milli sec)) // 2msec
Sinusundan iyon, pinasimulan namin ang mga module ng ADC para sa pagbabasa ng posisyon ng Potentiometer na tinalakay sa aming ADC PIC tutorial. Susunod na mayroon kaming Nakagagambala na gawain sa serbisyo na tatawagin sa tuwing, umaapaw ang timer babalik tayo sa paglaon, sa ngayon suriin natin ang pangunahing pagpapaandar.
Sa loob ng pangunahing pag-andar ay nai-configure namin ang module ng timer. Dito ko na-configure ang module ng Timer upang mag-overflow para sa bawat 0.1ms. Ang halaga para sa oras ay maaaring kalkulahin sa pamamagitan ng paggamit ng mga formula sa ibaba
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) pagkaantala sa sec at Fosc sa hz
Sa aking kaso para sa isang pagkaantala ng 0,0001 segundo (0.1ms) na may prescalar na 64 at Fosc ng 20MHz ang halaga ng aking rehistro (TMR0) ay dapat na 248. Kaya ganito ang pagsasaayos
/ ***** Configure ng Port para sa Timer ****** / OPTION_REG = 0b00000101; // Timer0 na may panlabas na freq at 64 bilang prescalar // Pinapagana din ang Pull UPs TMR0 = 248; // Load ang halaga ng oras para sa 0,0001s; ang delayValue ay maaaring nasa pagitan ng 0-256 lamang TMR0IE = 1; // Paganahin ang timer makagambala nang kaunti sa PIE1 rehistro GIE = 1; // Enable Global Interrupt PEIE = 1; // Paganahin ang Peripheral Interrupt / *********** ______ **** ***** /
Pagkatapos ay kailangan nating itakda ang pagsasaayos ng Input at Output. Narito ginagamit namin ang AN0 pin para sa pagbabasa ng halaga ng ADC at mga PORTD na pin upang i-output ang mga signal ng PWM. Kaya simulan ang mga ito bilang mga output pin at gawin silang mababa sa pamamagitan ng paggamit ng mga linya sa ibaba ng code.
/ ***** Configure ng Port para sa I / O ****** / TRISD = 0x00; // Turuan ang MCU na ang lahat ng mga pin sa PORT D ay output PORTD = 0x00; // Ipasimula ang lahat ng mga pin sa 0 / ********* ** ______ ********* /
Sa loob ng walang hanggan habang loop, kailangan nating kalkulahin ang halaga ng oras (T_ON) mula sa cycle ng tungkulin. Ang cycle ng oras at takbo ng tungkulin ay nag- iiba batay sa posisyon ng POT kaya't ginagawa namin ito nang paulit-ulit sa loob ng habang loop tulad ng ipinakita sa ibaba. Ang 0.0976 ay ang halagang kailangang i-multiply sa 1024 upang makakuha ng 100 at upang makalkula ang T_ON ay pinarami namin ito ng 10 upang makakuha ng halaga sa milli segundo.
habang (1) { POT_val = (ADC_Read (0)); // Basahin ang halaga ng POT gamit ang ADC Duty_cycle = (POT_val * 0.0976); // Map 0 to 1024 to 0 to 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Kalkulahin Sa Oras gamit ang mga yunit ng formula sa milli segundo __delay_ms (100); }
Dahil ang timer ay nakatakda sa higit na daloy para sa bawat 0.1ms, ang timer makagambala sa gawain na ISR ay tatawagan para sa bawat 0.1ms. Sa loob ng gawain ng serbisyo ay gumagamit kami ng isang variable na tinatawag na bilang at dagdagan ito para sa bawat 0.1ms. Sa ganitong paraan masusubaybayan natin ang oras ng f. Upang matuto nang higit pa tungkol sa Mga Nakagagambala sa PIC microcontroller, sundin ang mga link
kung (TMR0IF == 1) // Ang timer ng flag ay na-trigger dahil sa pag-overflow ng timer -> nakatakda sa overflow para sa bawat 0.1ms { TMR0 = 248; // Load the timer Halaga TMR0IF = 0; // Clear timer makagambala bilang ng flag ++; // Count increment para sa bawat 0.1ms -> count / 10 ay magbibigay ng halaga ng bilang sa ms }
Sa wakas oras na upang i-toggle ang pin ng GPIO batay sa halaga ng T_ON at T_OFF. Mayroon kaming variable na bilang na sumusubaybay sa oras sa milli segundo. Kaya ginagamit namin ang variable na iyon upang suriin kung ang oras ay mas mababa kaysa sa oras , kung oo pagkatapos ay pinapanatili namin ang GPIO pin na nakabukas kung hindi namin patayin ito at panatilihin itong naka-patay hanggang magsimula ang bagong ikot. Maaari itong magawa sa pamamagitan ng paghahambing nito sa kabuuang oras ng isang PWM cycle. Ang code na gawin ang pareho ay ipinapakita sa ibaba
kung (count <= (T_ON)) // Kung ang oras ay mas mababa kaysa sa oras RD1 = 1; // Turn on GPIO else RD1 = 0; // Else turn off GPIO if (count> = (T_TOTAL * 10)) // Panatilihin itong patayin hanggang sa magsimulang bilang ang isang bagong ikot = 0;
Diagram ng Circuit
Ang circuit diagram para sa pagbuo ng PWM na may GPIO pin ng PIC microcontroller ay talagang simple, paganahin lamang ang PIC na may oscillator at ikonekta ang potensyomiter upang i-pin ang AN0 at Servo Motor upang i-pin ang RD1, maaari naming gamitin ang GPIO pin upang makuha ang PWM signal, napili ko Ang RD1 ay wala nang random. Ang parehong Potentiometer at ang Servo motor ay pinalakas ng 5V na kinokontrol mula sa 7805 tulad ng ipinakita sa ibaba sa circuit diagram.
Kunwa
Upang gayahin ang proyekto ginamit ko ang aking proteus software. Buuin ang circuit na ipinakita sa ibaba at i-link ang code sa iyong kunwa at patakbuhin ito. Dapat kang makakuha ng isang senyas ng PWM sa RD1 GPIO pin ayon sa aming programa at ang ikot ng tungkulin ng PWM ay dapat na makontrol batay sa posisyon ng potensyomiter. Ipinapakita ng GIF sa ibaba kung paano tumugon ang signal ng PWM at servo motor kapag binago ang halaga ng ADC sa pamamagitan ng potensyomiter.
Pag-setup ng Hardware para sa pagkontrol sa Servo Motor gamit ang PIC Microcontroller
Ang aking kumpletong pag-set up ng hardware ay ipinapakita sa ibaba, para sa mga taong sumusunod sa aking mga tutorial na ito sa lupon ay dapat pamilyar, ito ay ang parehong board na ginamit ko sa lahat ng aking mga tutorial sa ngayon. Maaari kang mag-refer sa tutorial na Blinking LED kung interesado kang malaman kung paano ko ito binuo. Kung hindi man sundin lamang ang circuit diagram sa itaas at dapat na gumana ang lahat.
I-upload ang programa at ibahin ang potensyomiter at dapat mong makita ang servo na binabago ang posisyon batay sa posisyon ng potensyomiter. Ang kumpletong pagtatrabaho ng proyekto ay ipinapakita sa video na ibinigay sa pagtatapos ng pahinang ito. Inaasahan kong naintindihan mo ang proyekto at nasiyahan sa pagbuo, kung mayroon kang mga quire, huwag mag-atubiling mai-post ang mga ito sa forum at susubukan ko ang aking makakaya sa pagsagot.
Plano kong isulong ang proyektong ito sa pamamagitan ng pagdaragdag ng mga pagpipilian upang makontrol ang maraming motor na servo at sa gayon ay magtayo ng isang robot na braso palabas nito, katulad ng Arduino Robotic Arm na itinayo na namin. Kaya hanggang doon makita mo !!