Sunteți pe pagina 1din 18

Aplicaţii cu microcontrolere din familia 8051

COMANDA UNUI MOTOR DE CURENT CONTINUU

1. Scopul lucrării
• studiul comenzii unui motor de curent continuu;
• analiza rutinelor de comandă a motorului de curent continuu;

2. Aparatura necesară
• montajul experimental;
• osciloscop;

3. Consideraţii teoretice

3.1. Circuite pentru comanda motoarelor de curent continuu. Puntea H

Pentru a comanda un motor de curent continuu cu ajutorul unui


microcontroler trebuie să avem un circuit de forţă care să răspundă la un
nivel logic.
Cea mai simplă metodă de control este utilizarea unui tranzistor de
putere înseriat cu circuitul motorului.

Figura 1 – Comanda unui motor de cc într-un singur sens

Folosind acest fel de control, motorul se va roti într-un singur sens.


Pentru a realiza inversarea sensului de rotaţie trebuie să avem posibilitatea de
a inversa tensiunea de alimentare la bornele motorului. Acest lucru se poate

124
Comanda unui motor de curent continuu

realiza cu ajutorul unei punţi H. Puntea H conţine patru elemente


comutatoare dispuse ca în figura 2.
V+

SW1 SW4

1 M 2

SW2 SW3

GND
Figura 2 – Puntea H

În această configuraţie, putem avea următoarele situaţii:


SW1 SW2 SW3 SW4 Starea motorului
0 0 0 0 Oprit
1 0 1 0 Sens 1
0 1 0 1 Sens 2
1 1 0 0 Nepermis, scurtcircuit
0 0 1 1 Nepermis, scurtcircuit
1 0 0 1 Frânare dinamică
0 1 1 0 Frânare dinamică
Figura 3 – Modalităţi de comandă pentru puntea H

Motorul va fi pornit când una din perechile SW1-SW3 sau SW2-SW4 vor
fi cuplate.
V+ V+

SW1 SW4 SW1 SW4

(+) (-) (-) (+)


1 2 1 M 2
M

SW2 SW3 SW2 SW3

GND GND
Figura 4 – Inversarea sensului de rotaţie al motorului
După cum se observă din figura 4, dacă SW1 şi SW3 sunt cuplate, polul
1 al motorului va fi conectat la V+ şi polul 2 la GND, imprimând o mişcare

125
Aplicaţii cu microcontrolere din familia 8051

de rotaţie de un anumit sens. Dacă se cuplează SW2 şi SW4, polul 1 al


motorului se va conecta la GND iar polul 2 la V+, rotaţia realizându-se în
sens contrar.

3.2. Comanda PWM

Dacă în circuitul de comandă al motorului elementul comutator este


cuplat permanent, motorul va efectua o rotaţie la viteza maximă, impusă de
tensiunea de alimentare. Pentru a controla viteza de rotaţie a motorului,
trebuie să controlăm tensiunea la bornele acestuia. O primă metodă ar fi
controlul liniar, adică folosirea unui element regulator pe care să impunem o
cădere de tensiune egală cu diferenţa dintre tensiunea de alimentare si
tensiunea ce se doreşte pe motor. A doua metodă este controlul în impulsuri
modulare în durată (PWM, Pulse Width Modulation). Această metodă
presupune aplicarea unor impulsuri cu frecvenţă fixă şi de durată variabilă la
bornele motorului.

T
T_off T_on

A D=20%

D=50%

D=80%

Figura 5 – Semnalul PWM

Bazându-ne pe efectul integrativ al motorului, putem spune că acesta va


vedea doar componenta continuă a semnalului PWM. Această componetă se
poate exprima ca fiind produsul dintre amplitudinea semnalului PWM şi
factorul de umplere al acestuia.
T _ on
U Motor = A * D = A *
T

Unde:
A – amplitudinea semnalului PWM

126
Comanda unui motor de curent continuu

D – factorul de umplere
T_on – timpul de conducţie
T – perioada semnalului
Avantajul evident al acestei metode constă în faptul că elementele de
comandă SW1-SW4 lucrează în regim de comutaţie (saturat – blocat), deci cu
randament maxim.
Pentru realizarea comenzii PWM cu ajutorul unui microcontroler, trebuie
să stabilim perioada semnalului PWM şi un număr de paşi (cuante) pentru
reglajul factorului de umplere.
T

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Figura 6 – Modalitatea de implementare a PWM digital

Fixând un număr de K eşantioane şi amplitudinea A, notând cu N


numărul de eşantioane ce reprezintă timpul de conducţie, putem scrie:
N
U Motor = A *
K
Pentru implementarea acestui tip de control vom avea nevoie de o bază
T
de timp cu intervalul , ce reprezintă perioada unei cuante PWM. Folosind
K
această bază de timp, vom acţiona elementele de comandă pe durata
cuantelor de la 1 la N şi le vom inhiba pe durata N+1 la K. În cazul particular
din figura 6 avem K=16 şi N=9.
Schema logică pentru realizarea PWM-ului este ilustrată în figura 7.
Variabila Contor este utilizată pentru a baleia ciclic cuantele aferente unei
perioade. Astfel, ea va lua valori între 1 şi K, incrementându-se după fiecare
parcurgere a buclei. Dacă valoarea din variabila Contor devine mai mare
decât K spunem că am completat o perioadă a semnalului de ieşire. În acest
moment resetăm contorul la valoarea iniţială, 1 şi citim valoarea variabilei N,
care reprezintă factorul de umplere şi se poate modifica din exteriorul buclei.

127
Aplicaţii cu microcontrolere din familia 8051

START

Initializam K, N
1

Contor = 1

Eveniment
baza de timp?

DA NU
Contor <= N

Iesire = 1 Iesire = 0

Contor = Contor+1

DA NU

Citeste N Contor > K 2

Figura 7 – Schema logică pentru implementarea PWM

3.3. Montajul experimental

Montajul experimental este reprezentat de o punte H realizată cu


tranzistoare MOS, comandate în grilă de câte un buffer inversor cu drenă în
gol, de tip 74HC06 (figura 14). Puntea dispune de două intrări pentru cele
două sensuri de rotaţie ale motorului. Comanda punţii realizându-se cu un
microcontroler din familia 8051 a cărui ieşiri sunt în stare logică 1 la pornire,
intrările se vor alege active în 0, pentru a evita comanda simultană a acestora
în momentul punerii sub tensiune a montajului. În plus, intrările bufferelor
inversoare sunt prevăzute cu rezistenţe de pull-up pentru a păstra nivelul
logic 1 la intrare chiar în cazul decuplării microcontrollerului.
Controlul turaţiei şi sensului de rotaţie se face cu ajutorul unei tastaturi
matriciale de 3 rânduri şi 3 coloane. Se vor defini 4 taste pentru
mărirea/micşorarea vitezei şi pentru sensurile stânga/dreapta.

128
Comanda unui motor de curent continuu

3.4. Descrierea programului

Programul realizează comanda PWM a motorului de curent continuu în


32 cuante, cu o frecvenţă de 100Hz şi scanarea tastaturii cu o frecvenţă de
10Hz. Pentru a obţine baza de timp necesară implementării PWM-ului vom
folosi timerul 0. Vom calcula cea mai mică periodă de timp de care avem
nevoie, restul bazându-se pe multiplul acesteia. Aceasta este cea necesitată
pentru PWM, şi se va calcula ţinând cont de frecvenţa semnalului PWM şi
numărul de cuante:
1
TK =
f PWM * K
Unde:
TK – perioada unei cuante
FPWM - frecvenţa
K – numărul de cuante
Înlocuind cu valorile de mai sus, obţinem TK=312,5μs
Folosind un tact de 11.0592MHz pentru microcontroler, vom calcula
valoarea de reîncărcare a timerului 0 pentru a obţine TK=312,5μs. Durata
unui ciclu maşină fiind de 12 tacţi, adică 1,085μs, putem scrie:
T ⎛ 312,5 ⎞
TH 0, TL0 = 65635 − K = 65535 − int ⎜ ⎟ = 65535 − 288 = 65247
TCY ⎝ 1,085 ⎠
Împărţind valoarea pe cei doi regiştri pe 8 biţi şi facând
transformările:
TH 0 = 0 xFE
TL0 = 0 xDF
Având fixată baza de timp, vom folosi întreruperea aferentă timerului 0
pentru a lua o decizie referitoare la starea ieşirii după trecerea fiecărui
interval de 312,5μs, conform figurii 6.
Tastatura folosită este una de tip matricial cu 9 taste. Aceasta se va
conecta la microcontroler prin intermediul a 6 pini de port, dintre care 3 se
vor folosi pentru scanarea tastaturii şi 3 pentru citirea valorii returnate. Cei 6
pini vor fi alocaţi din portul P2, alături de semnalele PWM pentru comanda
motorului, ca în tabelul de mai jos:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Coloana Coloana Coloana Linia 3 Linia 2 Linia 1 PWM PWM
3 2 1 Dir 1 Dir 0

Figura 8 – Alocarea pinilor portului P2

129
Aplicaţii cu microcontrolere din familia 8051

Cele nouă taste vor fi dispuse ca în figura 9. Dintre acestea, se vor folosi
tasta 2, pentru incrementarea vitezei motorului, tasta 5 pentru decrementarea
vitezei motorului, tasta 4 şi 6 pentru cele a impune direcţia de rotaţie.

“1” “2” “3”


0xD8 0xB8 0x78

“4” “5” “6”


0xD4 0xB4 0x74

“7” “8” “9”


0xCC 0xAC 0x6C

Figura 9 – Codurile de scanare pentru tastatură

Scanarea tastaturii se va face pe linii, cu un semnal ca cel din figura 10.


T1
T2

Linia 1

Linia 2

Linia 3

Figura 10 – Semnalul pentru scanarea tastaturii

Aici T1 este perioada de scanare, pentru frecvenţa fixată mai sus, de


10Hz, aceasta va fi de 100ms, iar T2 este perioada în care se citeşte o tastă
apăsată pe linia în curs de scanare. Observăm că T2 = T1/3 = 33.33ms.
Pentru a obţine acest interval de timp, vom folosi baza de timp de
312,48μs. Astfel, vom executa scanarea tastaturii la aproximativ 100 de cicli
de bază de timp. După fiecare interval de timp egal cu T2, se va modifica
starea pinilor de port P2.4, P2.3, P2.2, conform cu valorile exprimate în
figura 3.5.2. Se va avea în vedere faptul că pinii P2.7, P2.6 şi P2.5 vor fi în
stare “1” logic, pentru a le folosi ca şi intrare, iar valoarea de pe pinii P2.1 şi

130
Comanda unui motor de curent continuu

P2.0 trebuie să rămână nealterată, datorită faptului că acestea sunt ieşirile de


PWM.

;DCMotor.a51
$NOMOD51
$INCLUDE (reg52.inc)
NAME DCMOTORCONTROL
;*************************************************************
;Definiri stivă, variabile pe octeţi si pe biţi
;*************************************************************
STIVA SEGMENT IDATA
RSEG STIVA
DS 10
;CONSTANTE SEGMENT CODE
; RSEG CONSTANTE
;
VARIABILE SEGMENT DATA
RSEG VARIABILE
CurrentVal: DS 1 ;Contor pentru iesirea PWM
KbdScanCount: DS 1 ;Contor temporizare scanare tastatură
Kbd_RowScan: DS 1 ;Contor scanare linii
Duty: DS 1 ;Factorul de umplere
KeyToDebounce: DS 1 ;Val. temp. pentru tasta citită
KeyPressed: DS 1 ;Valoare tastă citită
PortMask: DS 3

FLAGURI SEGMENT BIT


RSEG FLAGURI
DebounceFlag: DBIT 1
Dir: DBIT 1
KeyPressed_Flag: DBIT 1
;*************************************************************
;Inceput rutina principala
;*************************************************************
CSEG AT 0 ;Adresa de început a codului
USING 0 ;Folosim bancul de regiştri 0
LJMP START ;Salt la bucla principală
PROGRAM SEGMENT CODE
RSEG PROGRAM
USING 0
start:

131
Aplicaţii cu microcontrolere din familia 8051

mov sp, #STIVA-1 ;Iniţializăm stiva


lcall InitApp ;Apel rutină iniţializări
main: ;Începem bucla principală
lcall KeyDown ;Verificăm dacă e tastă apasată
mov a, r7
jz main ;Apelăm funcţia din nou
lcall ReadKey
mov a, r7
clr c
subb a, #0B8h ;Tasta nr. 2? /Inc. viteză
jz Tasta_UP ;

mov a, r7 ;
clr c
subb a, #0B4h ;Tasta nr. 5? /Dec. viteză
jz Tasta_Down ;

mov a, r7 ;
clr c
subb a, #0D4h ;Tasta nr. 4 /Schimbare direcţie
jz Tasta_Sens_1 ;

mov a, r7
clr c
subb a, #074h ;Tasta nr. 6? /Schimbare direcţie
jnz main

Tasta_Sens_2: ;Dacă s-a apăsat tasta Sens 2


jb Dir, main ;E setat deja sensul?
cpl Dir ;Dacă nu, setăm sensul
jmp main
Tasta_Sens_1: ;Dacă s-a apăsat tasta Sens 1
jnb Dir, main ;E setat deja sensul?
cpl Dir ;Dacă nu, setăm sensul
jmp main
Tasta_Up: ;Dacă s-a apăsat tasta inc. viteză
mov a, Duty
clr c
subb a, #31 ;Verificăm limita superioară
jnc main ;Dacă suntem la limita sup.
;nu luăm nici o măsura
inc Duty ;În caz contrar incr. viteza

132
Comanda unui motor de curent continuu

jmp main

Tasta_Down: ;S-a apăsat tasta decr. viteză?


mov a, Duty
jz main ;Verificăm dacă nu suntem la 0
dec Duty ;Dacă nu, decrementăm viteza
jmp main

ljmp main ;Sfârşit buclă principală


;*************************************************************
;Sfârşit rutină principală
;*************************************************************
;Început bloc rutine de întrerupere
;*************************************************************
;Început rutină de întrerupere pentru Timer 0
CSEG AT 0Bh ;adresa rutinei de întrerupere
TMR0
ljmp TMR0_Handler
TMR0_Handler SEGMENT CODE
RSEG TMR0_Handler
USING 1

push psw ;salvăm PSW pe stivă


mov psw, #80h ;comutăm în bancul 1
push acc ;salvăm acumulatorul
;început cod user
mov th0, #0FEh ;reîncărcăm timerul
mov tl0, #0DFh

mov a, CurrentVal
clr c
subb a, Duty ;verificăm PWM activ/inactiv
jc T0_CheckDir ;dacă e activ, verificăm direcţia
jmp T0_OutIdle ;dacă nu, setăm stările inactive
T0_CheckDir:
jnb Dir, T0_OutActive_1
T0_OutActive_0: ;dacă direcţia e 0,
clr P2.0 ;setăm ieşirea activă
setb P2.1 ;pentru portul P2.0
jmp T0_NextPWM ;
T0_OutActive_1: ;dacă direcţia e 1,
setb P2.0 ;setăm ieşirea activă

133
Aplicaţii cu microcontrolere din familia 8051

clr P2.1 ;pentru portul P2.1


jmp T0_NextPWM
T0_OutIdle: ;pentru PWM inactiv
setb P2.0 ;setăm ambele ieşiri
setb P2.1 ;inactive
T0_NextPWM:
mov a, CurrentVal
clr c
subb a, #31 ; capăt de perioadă PWM
jc T0_IncPWMCnt
mov CurrentVal, #0 ;reluăm ciclul
jmp T0_KbdScan
T0_IncPWMCnt:
inc CurrentVal ;trecem la următorul eşantion
T0_KbdScan: ;ciclu scanare tastatură
djnz KbdScanCount, T0_Exit ;temporizare citire tastatură
T0_DbFlagTrue:
mov KbdScanCount, #100 ;capăt interval de temporizare?
;reîncărcăm
jnb DebounceFlag, T0_DbFlagFalse ;ciclu de verificare?
clr DebounceFlag ;ştergem flagul de verificare
mov a, P2
anl a, #0FCh ;citim tasta
clr c
subb a, KeyToDebounce ;o comparăm cu ce s-a citit
jnz T0_DbFlagFalse ; nu corespunde?
mov KeyPressed, KeyToDebounce ;dacă da, o memorăm
setb KeyPressed_Flag ;si setăm flagul de tastă validă
jmp T0_Exit ;părăsim rutina de întrerupere

T0_DbFlagFalse: ;dacă e ciclu de citire


mov a, P2 ;citim tastatura
anl a, #0E0h
xrl a, #0E0h ;şi verificăm dacă e tastă apasată
jz T0_KeyNotPressed ;dacă nu, scanăm în continuare
mov a, P2 ;dacă da,
anl a, #0FCh ;citim tasta
mov KeyToDebounce, a ;o memorăm, pentru a fi
;verificată
setb DebounceFlag ;setăm flagul de verificare
jmp T0_Exit ;părăsim rutina de întrerupere
T0_KeyNotPressed:

134
Comanda unui motor de curent continuu

mov a, #PortMask ;vom seta masca pentru scanare


add a, Kbd_RowScan ;în fcţ. de linia care va fi citita
mov r0, a
mov a, P2
orl a, #0FCh ;mascăm ieşirile de PWM
anl a, @r0
mov P2, a ;setăm portul la valoarea măstii
inc Kbd_RowScan ;pregătim linia următoare
mov a, Kbd_RowScan
xrl a, #3 ;dacă linia scanată e ultima
jnz T0_Exit
mov Kbd_RowScan, #0 ;revenim la
T0_Exit:
;SFÂRŞIT COD USER
pop acc ;refacem acc. de pe stivă
pop psw ;refacem PSW de pe stivă
reti
;Sfârşit rutină de întrerupere pentru Timer 0
;Sfârşit bloc rutine de întrerupere
;*************************************************************
;Început Bloc Rutine Utilizator
InitApp: ;Rutină pentru iniţializarea aplicaţiei
mov tmod, #0F1h ;Config Timer 0
mov th0, #0FEh ;Incărcăm TMR0
mov tl0, #0DFh ;celor 312,48us pentru PWM
setb tr0 ;Pornim timerul 0
setb et0 ;Pornim întreruperea aferentă
TMR0
setb ea ;Pornim întreruperile
mov a, #0EFh ;Setăm val. măştii de scanare pt.
mov P2, a ;prima linie
mov Duty, #3 ;Factor de umplere impl.
mov PortMask+0, #0EFh ;Definim valorile măştilor
mov PortMask+1, #0F7h ;de scanare
mov PortMask+2, #0FBh ;pentru cele trei linii
mov Kbd_RowScan, #0 ;iniţ. contorul pentru scanare
mov KbdScanCount, #0 ;temporizarea pentru scanare
mov CurrentVal, #0 ;iniţ. contorul pentru PWM
ret

KeyDown: ;Rutină pentru verif. tastă apăsată


mov r7, #0 ;Implicit returnăm valoarea 0

135
Aplicaţii cu microcontrolere din familia 8051

jnb KeyPressed_Flag, KeyDown_Ret ;Dacă e tastă apasată


mov r7, #1 ;Returnăm valoarea 1
KeyDown_Ret:
ret

ReadKey: ;Rutină citire tastă


mov r7, KeyPressed ;Returnăm valoarea tastei
clr KeyPressed_Flag ;Ştergem flagul de tastă validă
ret
;*************************************************************
;Sfârşit Bloc Rutine Utilizator
;*************************************************************
END

136
Comanda unui motor de curent continuu

3.5. Schema logică a programului

START

Initializare
aplicatie

Citire flag tasta


apasata

NU Tasta
apasata?

DA

DA DA
Tasta =
Duty <31 Duty = Duty + 1
Incrementare?

NU
NU

DA DA
Tasta =
Decrementare Duty > 0 Duty = Duty -1
?
NU
NU

Tasta = DA
Directie 1
?
Dir = !Dir
NU

NU Tasta =
Directie 2
? DA

Figura 11 – Schema logică a programului principal

137
Aplicaţii cu microcontrolere din familia 8051

START ISR

Reîncarcare
Timer0

NU
CurrentVal P2. 0 = 1
< P2. 1 = 1
Duty
DA

DA NU
Dir = 0

P2. 0 = 0 P2. 0 = 1
P2. 1 = 1 P2. 1 = 0

CurrentVal=
CurrentVal+ 1

NU
CurrentVal CurrentVal= 0
< 32
DA

KbdScanCount=
KbdScanCount- 1

KbdScanCount NU
1
=0

DA
KbdScanCount=
100

Figura 12 – Schema logică a vectorului de întrerupere (partea 1)

138
Comanda unui motor de curent continuu

NU DA
DebounceFlag
=1
DebounceFlag= 0
NU
Tasta citita ?

DA NU Tasta citita =
KeyToDebounce
KeyToDebounce =
Tasta citita
DA
KeyPressed=
DebounceFlag= 1
KeyToDebounce

KeyPressed_Flag
1 =1

1
P2 =
PortMask[Linie]

Linie = Linie+1

NU
Linie < 3 Linie = 0

DA
1

STOP ISR

Figura 13 – Schema logică a vectorului de întrerupere (partea 2)

139
Aplicaţii cu microcontrolere din familia 8051

4. Modul de lucru
• Se va rula codul pas cu pas, utilizând depanatorul de programe
inclus în Keil µVision2;
• Se vor vizualiza cu ajutorul osciloscopului formele de undă
pentru comanda motorului, la diferite valori ale factorului de
umplere;
• Se vor vizualiza formele de undă pentru scanarea tastaturii.

5. Prelucrarea datelor
• Să se modifice programul, astfel încât PWM-ul generat să aibă
o frecvenţă de 50Hz cu 64 paşi, iar tastatura să se scaneze cu o
frecvenţă de 15Hz.
• Să se modifice maparea tastelor, astfel încât tastele pentru
incrementarea/decrementarea vitezei să fie 3 respectiv 4, iar
cele pentru direcţie să fie 8 şi 9.
• Să se propună un algoritm de schimbare lentă a sensului de
rotaţie.

140
Comanda unui motor de curent continuu

Figura 14 – Schema montajului experimental

141

S-ar putea să vă placă și