Regolatore di velocita' motore cc PWM con 8051

 Manuale dell' TLC548   Manuale MJ3001

 

Test pwm con profilo a rampa Untitled
pwmo   = P1.0  ; uscita PWM
CS     = P1.5
CLK    = P1.6
DATA   = P1.7

pwmval = 10h    ;valore PWM  0..255 0..100%
adcval = 11h    ;ultimo valore letto dall'ADC

	org 8200h
	call init
main:
	mov r1,#250
ltestpwm:
	call lettadc
	mov adcval,a
	djnz r1,ltestpwm

	inc pwmval
	jmp main
	

;++++++++++++++ Subroutine lettura ADC seriale TLC548 ++++++++++++++++++++++++
;Il valore letto ritorna sul registro A
lettadc:
	mov r0,#8
	clr CS
loopcv: 
	mov c,DATA
	rlc a
	setb CLK
	clr CLK
	djnz r0,loopcv
	setb CS
	ret

;-----------------------------------------------------------------------------
;Servizio di interruzione Timer0
ser_t0:
	push acc
	mov th0,#0ffh
	jb flon,pwmoff
pwmon:	
        setb pwmo
	mov a,#0ffh
        clr c
	subb a,pwmval
	mov tl0,a
	setb flon
	pop acc
	reti
pwmoff:
        clr pwmo
        mov tl0,pwmval
	clr flon     
        pop acc
	reti

;-----------------------------------------------------------------------------
t_mod2  = 1     ; Modo funzionamento 2
itv     = 0     ; conteggio di partenza  
flon    = 20h.0 ; Flag PWM on
init:
;inizializzazione timer0 in  modo 2
	clr tr0
	mov a,tmod
	anl a,#0F0h
	orl a,#t_mod2
	mov tmod,a
;inizializzazione vettore interrupt timer0
	mov dptr,#80A4h
	mov a,#high(ser_t0)
	movx @dptr,a
	inc dptr
	mov a,#low(ser_t0)
	movx @dptr,a 
;preparazione conteggio timer0
	mov th0,#0ffh
	mov tl0,#0;		
;abilita interrupt e avvia il timer
        setb et0
        setb tr0  
        clr flon
        clr pwmo
;inizializza linee di controllo ADC
	setb CS
	clr CLK
	setb DATA 
	ret		
	end
Regolatore proporzionale
pwmo    = P1.0  ; uscita PWM
CS      = P1.5
CLK     = P1.6
DATA    = P1.7
;Variabili e costanti regolatore
pwmval  = 10h   ;valore PWM  0..255 0..100%
adcval  = 11h   ;ultimo valore letto dall'ADC
rif	 = 13h   ;Riferimento  
k       = 14h   ;  
;Variabili e costanti acquisizione
nacq	 = 0F0h    ;N. acquisizioni

bufacq	 = 9000h   ;indirizzo di inizio del buffer di acquisizione


	org 8200h
	call init
	call initacq

main:
;Ciclo di ritardo per dar tempo alla velocit? di assestarsi all'ultimo valore pwmval
	mov r1,#25
ltestpwm:
	call lettadc
	mov adcval,a
	djnz r1,ltestpwm

	call acq        ;Acquisizione
	call regola     ;Regolazione
	jmp main
;REGOLATORE
;Esegue pwmval=(rif-adcval)*k
regola:
	mov a,rif
	clr c
	subb a,adcval
	jc zero         ;se la differenza รจ negativa mette a zero pwmval

	mov b,k
lmolt:
      	mul ab
       	mov r3,a
       	mov a,b
       	jz wrpwm       ;se > 0FFh allora forza a 0FFh  
       	mov r3,#0FFh
wrpwm: 	     
	mov pwmval,r3
	ret
zero:
	mov pwmval,#0
	ret

;++++++++++++++ Acquisisce valore                    ++++++++++++++++++++++++
acq:
	djnz cacq,doacq
	mov cacq,#nacq
	mov dptr,#bufacq
doacq:
	movx @dptr,a
	inc dptr
	ret  
	
;++++++++++++++ Subroutine lettura ADC seriale TLC548 ++++++++++++++++++++++++
;Il valore letto ritorna sul registro A
lettadc:
	mov r0,#8
	clr CS
loopcv: 
	mov c,DATA
	rlc a
	setb CLK
	clr CLK
	djnz r0,loopcv
	setb CS
	ret

;-----------------------------------------------------------------------------
;Servizio di interruzione Timer0
ser_t0:
	push acc
        push psw
	mov th0,#0ffh
	jb flon,pwmoff
pwmon:	
	setb pwmo
	mov a,#0ffh
	clr c
	subb a,pwmval
	mov tl0,a
	setb flon
        pop psw
	pop acc
	reti
pwmoff:
	clr pwmo
	mov tl0,pwmval
	clr flon
        pop psw     
	pop acc
	reti

;-----------------------------------------------------------------------------
t_mod1  = 1     ; Modo funzionamento 1
itv     = 0     ; conteggio di partenza  
flon    = 20h.0 ; Flag PWM on
init:
;inizializzazione timer0 in  modo 1
	clr tr0
	mov a,tmod
	anl a,#0F0h
	orl a,#t_mod1
	mov tmod,a
;inizializzazione vettore interrupt timer0
	mov dptr,#80A4h
	mov a,#high(ser_t0)
	movx @dptr,a
	inc dptr
	mov a,#low(ser_t0)
	movx @dptr,a 
;preparazione conteggio timer0
	mov th0,#0ffh
	mov tl0,#0;		
;abilita interrupt e avvia il timer
	setb et0
	setb pt0
	setb tr0  
	clr flon
	clr pwmo
;inizializza linee di controllo ADC
	setb CS
	clr CLK
	setb DATA 
	ret
;-----------------------------------------------------------------------------
initacq:
	mov cacq,#1
	ret

	end

Regolazione pseudo integrativa (correzione a rampa)
pwmo   = P1.0  ; uscita PWM
CS     = P1.5
CLK    = P1.6
DATA   = P1.7

pwmval = 10h    ;valore PWM  0..255 0..100%
adcval = 11h    ;ultimo valore letto dall'ADC

nacq	= 0F0h   ;N. acquisizioni
cacq	= 12h	  ;conteggio posizione buf acq
bufacq	= 9000h

rif	= 13h   ; Riferimento  

	org 8200h
	call init
	call initacq

main:
	mov r1,#250
ltestpwm:
	call lettadc
	mov adcval,a
	djnz r1,ltestpwm

	call acq
	call regola
	jmp main


regola:
	mov a,rif
	clr c
	subb a,adcval
        jz u_reg
	jc decrem
        mov a,pwmval
        cjne a,#0FFh,increm
        jmp u_reg        	
increm:
	inc pwmval
        jmp u_reg
decrem:
	mov a,pwmval       
        jz u_reg
        dec pwmval
u_reg:	
	ret  	

;++++++++++++++ Acquisisce valore                    ++++++++++++++++++++++++
acq:
	djnz cacq,doacq
	mov cacq,#nacq
	mov dptr,#bufacq
doacq:
	movx @dptr,a
	inc dptr
	ret  

	
;++++++++++++++ Subroutine lettura ADC seriale TLC548 ++++++++++++++++++++++++
;Il valore letto ritorna sul registro A
lettadc:
	mov r0,#8
	clr CS
loopcv: 
	mov c,DATA
	rlc a
	setb CLK
	clr CLK
	djnz r0,loopcv
	setb CS
	ret

;-----------------------------------------------------------------------------
;Servizio di interruzione Timer0
ser_t0:
	push acc
        push psw
	mov th0,#0ffh
	jb flon,pwmoff
pwmon:	
	setb pwmo
	mov a,#0ffh
	clr c
	subb a,pwmval
	mov tl0,a
	setb flon
        pop psw
	pop acc
	reti
pwmoff:
	clr pwmo
	mov tl0,pwmval
	clr flon
        pop psw     
	pop acc
	reti

;-----------------------------------------------------------------------------
t_mod1  = 1     ; Modo funzionamento 1
itv     = 0     ; conteggio di partenza  
flon    = 20h.0 ; Flag PWM on
init:
;inizializzazione timer0 in  modo 1
	clr tr0
	mov a,tmod
	anl a,#0F0h
	orl a,#t_mod1
	mov tmod,a
;inizializzazione vettore interrupt timer0
	mov dptr,#80A4h
	mov a,#high(ser_t0)
	movx @dptr,a
	inc dptr
	mov a,#low(ser_t0)
	movx @dptr,a 
;preparazione conteggio timer0
	mov th0,#0ffh
	mov tl0,#0;		
;abilita interrupt e avvia il timer
	setb et0
	setb pt0
	setb tr0  
	clr flon
	clr pwmo
;inizializza linee di controllo ADC
	setb CS
	clr CLK
	setb DATA 
	ret
;-----------------------------------------------------------------------------
initacq:
	mov cacq,#1
	ret

	end