- Què és un senyal PWM?
- Programació de PIC per generar PWM en pins GPIO
- Esquema de connexions
- Simulació
- Configuració del maquinari per controlar el servomotor mitjançant microcontrolador PIC
La generació de senyals PWM és una eina vital per a tots els arsenal d’enginyers integrats, són molt útils per a moltes aplicacions com controlar la posició del servomotor, canviar pocs circuits electrònics de potència en convertidors / inversors i fins i tot per a un simple control de la brillantor del LED Als microcontroladors PIC es poden generar senyals PWM mitjançant els mòduls Compare, Capture i PWM (CCP) establint els registres necessaris, ja hem après a fer-ho al tutorial PIC PWM. Però hi ha un inconvenient considerable amb aquest mètode.
El PIC16F877A pot generar senyals PWM només als pins RC1 i RC2, si fem servir els mòduls CCP. Però és possible que ens trobem amb situacions en què necessitem més pins per tenir la funcionalitat PWM. Per exemple, en el meu cas, vull controlar 6 servomotors RC per al meu projecte de braç robòtic per al qual el mòdul CCP no té esperança. En aquests escenaris podem programar els pins GPIO per produir senyals PWM mitjançant mòduls temporitzadors. D’aquesta manera podem generar tants senyals PWM amb qualsevol pin necessari. També hi ha altres pirates informàtics de maquinari com fer servir un CI de multiplexor, però per què invertir en maquinari quan es pot aconseguir el mateix mitjançant la programació. Així doncs, en aquest tutorial aprendrem com convertir un pin PIC GPIO en un pin PWM i, per provar-lo, el simularem en proteus amb oscil·loscopi digital i tambécontroleu la posició del servomotor mitjançant el senyal PWM i varieu el seu cicle de treball variant un potenciòmetre.
Què és un senyal PWM?
Abans d’entrar en els detalls, expliquem una mica el que són els senyals PWM. La modulació d’amplada de pols (PWM) és un senyal digital que s’utilitza més habitualment en circuits de control. Aquest senyal s’estableix com a alt (5v) i baix (0v) en un temps i una velocitat predefinits. El temps durant el qual el senyal es manté elevat s’anomena “hora puntual” i el temps durant el qual el senyal es manté baix es diu “temps apagat”. Hi ha dos paràmetres importants per a un PWM, tal com es descriu a continuació:
Cicle de treball del PWM
El percentatge de temps en què el senyal PWM roman ALT (puntual) s’anomena cicle de treball. Si el senyal sempre està activat, està en un 100% de cicle de treball i si sempre està apagat, és un 0% de cicle de treball.
Cicle de treball = Temps d’activació / (Temps d’encès + Temps d’APAGAT)

|
Nom de la variable |
Es refereix a |
|
PWM_Freqüència |
Freqüència del senyal PWM |
|
T_TOTAL |
Temps total necessari per a un cicle complet de PWM |
|
T_ON |
Puntual del senyal PWM |
|
T_OFF |
Temps d’aturada del senyal PWM |
|
Cicle de treball |
Cicle de treball del senyal PWM |
Ara doncs, fem les matemàtiques.
Aquestes són les fórmules estàndard on la freqüència és simplement la recíproca del temps. El valor de freqüència l’ha de decidir i establir l’usuari en funció del requisit de la seva aplicació.
T_TOTAL = (1 / PWM_Freqüència)
Quan l'usuari canvia el valor del cicle de treball, el nostre programa hauria d'ajustar automàticament el temps T_ON i el temps T_OFF d'acord amb això. Per tant, les fórmules anteriors es poden utilitzar per calcular T_ON en funció del valor de Duty_Cycle i T_TOTAL.
T_ON = (Cicle_de_deure * T_TOTAL) / 100
Atès que el temps total del senyal PWM per a un cicle complet serà la suma de temps d’activació i temps d’aturada. Podem calcular el temps d’aturada T_OFF tal com es mostra més amunt.
T_OFF = T_TOTAL - T_ON
Tenint en compte aquestes fórmules, podem començar a programar el microcontrolador PIC. El programa inclou el mòdul PIC Timer i el mòdul PIC ADC per crear un senyal PWM basat en un cicle de treball variable segons el valor ADC del POT. Si no esteu fent servir aquests mòduls, es recomana llegir el tutorial adequat fent clic als enllaços.
Programació de PIC per generar PWM en pins GPIO
El programa complet d’aquest tutorial es pot trobar a la part inferior del lloc web com sempre. En aquesta secció comprenem com s’escriu realment el programa. Com tots els programes, comencem configurant els bits de configuració. He utilitzat l'opció de visualitzacions de memòria per configurar-la.
// CONFIG #pragma config FOSC = HS // Bits de selecció dels oscil·ladors (oscil·lador HS) #pragma config WDTE = OFF // Bit de habilitació del temporitzador de vigilància (WDT desactivat) #pragma config PWRTE = OFF // Bit d’activació del temporitzador d’encesa (PWRT) desactivat) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low Voltage (Single-Supply) In-Circuit Serial Programming Enable Bit Hable (RB3 is E / S digital, S'ha d'utilitzar HV a MCLR per a la programació) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Protecció contra escriptura desactivada; tota la memòria del programa pot ser escrita pel control EECON) #pragma config CP = OFF // Bit de protecció del codi de memòria del programa Flash (Protecció de codi desactivada) // Les sentències #pragma config haurien de precedir el fitxer de projecte inclòs // Utilitzeu enums del projecte en lloc de #define per a ON i OFF. #incloure
A continuació, esmentem la freqüència de rellotge utilitzada al maquinari, aquí el meu maquinari utilitza cristall de 20 MHz, podeu introduir el valor basat en el vostre maquinari. A continuació es mostra el valor de freqüència del senyal PWM. Des del meu objectiu aquí és controlar un servomotor RC hobby que requereixi una freqüència PWM de 50Hz, he establert 0,05 KHz com a valor de freqüència, també podeu canviar-ho segons els requisits de la vostra aplicació.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0,05 // en KHz (50Hz)
Ara, que tenim el valor de Freqüència, podem calcular el T_TOTAL utilitzant les fórmules comentades anteriorment. El resultat es submergeix en 10 per obtenir el valor del temps en milis segons. En el meu cas, el valor de T_TOTAL serà de 2 milis segons.
int T_TOTAL = (1 / PWM_Frequency) / 10; // calcular el temps total a partir de la freqüència (en milis segons)) // 2 ms
Seguidament, inicialitzem els mòduls ADC per llegir la posició del potenciòmetre tal com es comenta al nostre tutorial ADC PIC. A continuació, tenim la rutina de servei d'interrupció que es cridarà cada vegada que es desbordarà el temporitzador. Tornarem més endavant, de moment comprovem la funció principal.
Dins de la funció principal configurem el mòdul temporitzador. Aquí he configurat el mòdul Temporitzador per desbordar-se per cada 0,1 ms. El valor del temps es pot calcular mitjançant les fórmules següents
RegValue = 256 - ((Retard * Fosc) / (Prescalar * 4)) retard en segons i Fosc en hz
En el meu cas per un retard de 0,0001 segons (0,1 ms) amb prescalar de 64 i Fosc de 20 MHz el valor del meu registre (TMR0) hauria de ser de 248. Per tant, la configuració té aquest aspecte
/ ***** Configuració del port per al temporitzador ****** / OPTION_REG = 0b00000101; // Temporitzador0 amb freq extern i 64 com a prescalar // També habilita PULL UP TMR0 = 248; // Carregueu el valor de temps de 0,0001 s; delayValue només pot estar entre 0-256 TMR0IE = 1; // Activa el bit d’interrupció del temporitzador al registre PIE1 GIE = 1; // Activa la interrupció global PEIE = 1; // Activa la interrupció perifèrica / *********** ______ *********** /
Després hem d’ establir la configuració d’entrada i sortida. Aquí fem servir el pin AN0 per llegir el valor ADC i els pins PORTD per emetre els senyals PWM. Per tant, inicieu-los com a pins de sortida i feu-los baixos mitjançant les línies de codi següents.
/ ***** Configuració del port per a E / S ****** / TRISD = 0x00; // Indiqueu a la MCU que tots els pins de PORT D es generin PORTD = 0x00; // Inicialitzeu tots els pins a 0 / *********** ______ *********** /
Dins del bucle while infinit, hem de calcular el valor de on time (T_ON) a partir del cicle de treball. El temps i deure cicle varia en funció de la posició de l'olla per ho fem repetidament dins el temps de bucle com es mostra a continuació. 0,0976 és el valor que s’ha de multiplicar per 1024 per obtenir 100 i per calcular T_ON l’hem multiplicat per 10 per obtenir valor en milis segons.
mentre (1) { POT_val = (ADC_Read (0)); // Llegiu el valor de POT mitjançant ADC Duty_cycle = (POT_val * 0,0976); // Mapa de 0 a 1024 a 0 a 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Calcular el temps d'ús mitjançant la unitat de fórmules en mil·lis segons __delay_ms (100); }
Com que el temporitzador està configurat per excedir-se per cada 0,1 ms, es cridarà a la rutina ISR de servei d’interrupció del temporitzador per cada 0,1 ms. Dins de la rutina de servei utilitzem una variable anomenada count i l'incrementem per cada 0,1 ms. D’aquesta manera podem fer un seguiment del temps. Per obtenir més informació sobre les interrupcions del microcontrolador PIC, seguiu els enllaços
si (TMR0IF == 1) // El marcador del temporitzador s'ha activat a causa del desbordament del temporitzador -> definit com a desbordament per a cada 0,1 ms { TMR0 = 248; // Carregueu el valor del temporitzador TMR0IF = 0; // Esborra el compte de banderes d’interrupció del temporitzador ++; // Els increments de recompte per cada 0,1 ms -> recompte / 10 donaran el valor del recompte en ms }
Finalment, és hora de canviar el pin GPIO en funció del valor de T_ON i T_OFF. Tenim la variable de recompte que fa un seguiment del temps en milis segons. Per tant, fem servir aquesta variable per comprovar si el temps és inferior a l’hora , si és així, mantenim el pin GPIO activat, si no, el desactivem i el mantenim apagat fins que comenci el nou cicle. Això es pot fer comparant-ho amb el temps total d’un cicle PWM. A continuació es mostra el codi per fer el mateix
if (count <= (T_ON)) // Si el temps és inferior al temps RD1 = 1; // Activeu GPIO else RD1 = 0; // Si no, desactiveu GPIO if (count> = (T_TOTAL * 10)) // Mantingueu-lo apagat fins que un nou cicle comenci a count = 0;
Esquema de connexions
El diagrama del circuit per generar PWM amb pin GPIO del microcontrolador PIC és realment senzill, només cal alimentar el PIC amb oscil·lador i connectar el potenciòmetre al pin AN0 i Servo Motor al pin RD1, podem utilitzar el pin GPIO per obtenir el senyal PWM, he seleccionat RD1 acabat de ser aleatori. Tant el potenciòmetre com el motor servo són alimentats per 5 V que es regula des del 7805 tal com es mostra a continuació al diagrama del circuit.

Simulació
Per simular el projecte he utilitzat el meu programari proteus. Construïu el circuit que es mostra a continuació i enllaceu el codi amb la simulació i executeu-lo. Heu d’obtenir un senyal PWM al pin RDIO GPIO segons el nostre programa i el cicle de treball del PWM s’hauria de controlar en funció de la posició del potenciòmetre. El GIF següent mostra com responen el senyal PWM i el servomotor quan es canvia el valor ADC a través del potenciòmetre.

Configuració del maquinari per controlar el servomotor mitjançant microcontrolador PIC
La configuració completa del maquinari es mostra a continuació, per a les persones que segueixen els meus tutorials, aquest tauler hauria de semblar familiar, és el mateix tauler que he utilitzat en tots els meus tutorials fins ara. Podeu consultar el tutorial LED intermitent si esteu interessat en saber com el construeixo. En cas contrari, seguiu el diagrama de circuits anterior i tots haurien de funcionar bé.

Carregueu el programa i varieu el potenciòmetre i hauríeu de veure com el servo canvia de posició en funció de la posició del potenciòmetre. El funcionament complet del projecte es mostra al vídeo presentat al final d'aquesta pàgina. Espero que hagueu entès el projecte i us hagi agradat construir, si teniu dubtes, no dubteu a publicar-los al fòrum i faré tot el possible per respondre.
Estic planejant tirar endavant aquest projecte afegint opcions per controlar diversos servomotors i, per tant, construir un braç robòtic fora d’ell, similar al braç robòtic Arduino que ja vam construir. Així que fins llavors ens veiem !!
