📄 pwm.asm
字号:
*===========================================================
*F = 50KHz
*电机启动电压5V
*电机正常工作电压50V
*start angle is 0.175度
*===========================================================
.title "pwm"
.include "240x.h"
.mmregs
.global _c_int0
.global PHANTOM
.global GISR2
.data
;T1CNT .set 7401H
;T1PR .set 7403H
;T1CON .set 7404H
;COMCONA .set 7411H
;ACTRA .set 7413H
;DBTCONA .set 7415H
;CMPR1 .set 7417H
;GPTCONA .set 7400H
;T1CMPR .set 7402H
;SCSR2 .set 7019H
.bss TEMP1,1
.bss TEMP2,1
.bss TEMP3,1
.bss TEMP4,1
.bss TEMP5,1
.bss TEMP6,1
.bss TEMP7,1
.bss K1,1
.bss K2,1
.bss EK,1
.bss UK,1
ST0_SAVE .usect "CONTEXT",1
ST1_SAVE .usect "CONTEXT",1
ACCH .usect "EXTCONT",1
ACCL .usect "EXTCONT",1
P_H .usect "EXTCONT",1
P_L .usect "EXTCONT",1
T_SAVE .usect "EXTCONT",1
.text
_c_int0:
;=========================系统初始化===========================================
B GOON
;-----------------------------
xxINT1: B PHANTOM
xxINT2: B GISR2
;-----------------------------
GOON: LDP #0
SETC INTM ;禁止中断
CLRC SXM
CLRC OVM
CLRC CNF ;B0 为数据存储区
LDP #00E0H ;DATA ADDRESS IS 7000H--707FH
SPLK #0005H,18H ;SCSR1 ;四倍频,CLKOUT 40MHz,开EVA时钟
SPLK #000DH,19H ;SCSR2 微控制器,片外寻址
SPLK #00E8H,29H ;WDCR ;不用看门狗
LDP #00E1H ;7080H
LACC 10H ;MCRA ;I/O复用控制器
OR #0A80H
SACL 10H
;bit15 TCLKINA/IOPB7
;bit14 TDIRA/IOPB6
;bit13 T2PWM/IOPB5 0 I/O
;bit12 T1PWM/IOPB4 0 I/O
;bit11 PWM6/IOPB3 1 PWM
;bit10 PWM5/IOPB2 0 I/O DIR
;bit9 PWM4/IOPB1 1 PWM
;bit8 PWM3/IOPB0 0 I/O DIR
;bit7 PWM2/IOPA7 1 PWM
;bit6 PWM1/IOPA6 0 I/O DIR
;bit5 CAP3/IOPA5
;bit4 CAP2/IOPA4
;bit3 CAP1/IOPA3
;bit2 XINT1/IOPA2
;bit1 SCIRXD/IOPA1
;bit0 SCITXD/IOPA0
LACC 14H ;7094H MCRC
OR #0000H
SACL 14H
;bit2 PWM8/IOPE2 0 I/O BRKA
;bit1 PWM7/IOPE1 0 I/O BRKA
SPLK #07FF9H,15H ;PEDATDIR
;BIT2 = 0 IOPE2 BAKA = 0
;BIT1 = 0 IOPE1 BAKE = 0
SPLK #07FFFH,18H ;PADATDIR
;bit15--8 1--A6-A0引脚为输出 A6--DIRA
;bit7--0 1--A7-A0引脚输出为高电平
SPLK #07FFFH,1AH ;PBDATDIR
;bit15--8 1--B6-B0引脚为输出 B2--DIRS B0--DIRE
;bit7--0 1--B7-B0引脚输出为高电平
;=========================中断初始化===========================================
RESET_BREAK:
LDP #0H
SPLK #0FFFH,IFR ;清所有系统中断标志
SPLK #0002H,IMR ;开定时器中断,开INT2中断
LDP #00E8H ;7400H
SPLK #0000H,2CH ;EVAIMRA
SPLK #0000H,2DH ;EVAIMRB
SPLK #0000H,2EH ;EVAIMRC ;屏蔽所有中断
SPLK #0FFFH,2FH ;EVAIFRA ;清事件管理器A所有中断标志
SPLK #0FFFH,30H ;EVAIFRB
SPLK #0FFFH,31H ;EVAIFRC
SPLK #0FFFH,2FH ;EVAIFRA ;清事件管理器A所有中断标志
SPLK #0FFFH,30H ;EVAIFRB
SPLK #0FFFH,31H ;EVAIFRC
SPLK #0200H,2CH ;EVAIMRA ;开T1下溢中断
SPLK #0000H,2DH ;EVAIMRB
SPLK #0000H,2EH ;EVAIMRC ;屏蔽所有中断
;========================变量初始化=====================================
LDP #04H
SPLK #1,K1 ;调试系数时此值重新设定
SPLK #0,K2 ;调试系数时此值重新设定
SPLK #0,EK
SPLK #0,UK
*===========================gain the number of T1PR=====================
* 40MHz/50KHz = 800 => T1PR
* 保存在TEMP1
*=======================================================================
LDP #0004H ;B0 200H--204H
SPLK #0C350H,2H ;motor frequent,50KHz
SPLK #5A00H,0H ;
SPLK #0262H,1H ;40MHz
LACC 0H
ADD 1H,16 ;dividend
RPT #000FH
SUBC 2H ;divisor(800)
SUB #0001H
SACL TEMP1 ;save result to 200H
*===========================gain the inflexion value====================
* 180/2^11 = 0.0879 1位为0.0879度
* 两位为0.175度,令其代表5V,起转
* 则电机正常工作时的位数为50/2.5 = 20
* 保存在TEMP2
*=======================================================================
LDP #0004H
SPLK #0032H,TEMP2 ;the motor's work voltage--50V
SPLK #0005H,TEMP3 ;the motor's start voltage--5V
LT TEMP2 ;50/(5/2)
MPY #2H ;两位为0.175度,其代表5V,起转
PAC
RPT #15
SUBC TEMP3
SACL TEMP2 ;save the inflexion value to TEMP2
;=========================事件管理器A初始化====================================
LDP #00E8H
SPLK #0000H,T1CON
SPLK #0000H,00H
SPLK #0041H,00H ;GPTCONA ;EVA 比较输出允许,比较输出低有效
;BIT6 compare output enable or unable
; 0--unable
; 1--enable
;bit3--2 timer2
; 10--high effective
; 01--low effective
;bit1--0 timer1
; 01--low effective
; 10--high effective
LDP #04H
LACL TEMP1
LDP #00E8H
SACL 3H ;T1PR
;SPLK #1000,2H ;T1CMPR
SPLK #0,17H ;CMPR1
SPLK #0,01H ;T1CNT
SPLK #0AA6H,13H ;ACTRA
;bit11--10 10--PWM6高有效
;bit9--8 10--PWM5高有效
;bit7--6 10--PWM4高有效
;bit5--4 10--PWM3高有效
;bit3--2 10--PWM2高有效
;bit1--0 10--PWM1高有效
;SPLK #01F4H,15H ;DBTCONA ;死区控制允许,死区时间为1us
SPLK #0A200H,11H
SPLK #0A200H,11H ;COMCONA ;比较允许,下溢重载
;bit15 比较允许位
; 1--允许
;bit14--13 比较值重载方式位
; 00--下溢时重载
; 01--下溢或等于周期值时重载
;bit12 0--空间矢量禁止
;bit11--10 方式寄存器重载方式位
; 00--下溢时重载
; 11--保留不用
;bit9 1--比较输出允许位
SPLK #9002H,04H ;T1CON ;连续增减记数,1分频,定时器允许,内部时钟,记数为0时重装
SPLK #9042H,04H
;bit15--14 10/11不受仿真挂起影响
;bit12--11 计数工作方式位
; 01--连续增/减计数
; 10--连续增计数
;bit10--8 000--不分频
;bit6 定时器允许位
; 0--禁止
; 1--允许
;bit3--2 定时器比较寄存器重载条件
; 00--计数为0时重载
; 01--计数为0或等于周期寄存器值时重载
;bit1 定时器比较允许位
; 0--禁止
; 1--允许
;bit0 0--使用自己的周期寄存器
CLRC INTM ;开总中断
LOOP NOP
NOP
B LOOP
;===========================main program================================
GISR2:
LDP #00E0H
SPLK 00E8H,WDCR
LDP #0
SST #0,ST0_SAVE ;保护现场ST0
SST #1,ST1_SAVE ;保护现场ST1
SACH ACCH
SACL ACCL
SPH P_H
SPL P_L
MPY #1
SPL T_SAVE
*=========================================================================
* 得出误差角 PI控制: Uk = Uk-1 + K1*ek + K2*ek-1
*=========================================================================
LDP #0004H ;调试系数时用 =
; =
LT EK ;T=ek-1 ; =
MPY K2 ;P=ek-1 * K2, ;K2是Q12格式 =
; =
SPLK #012H,TEMP4 ;预置角度 ; =
SPLK #0000H,TEMP5 ;当前角度 ; =
; =
LACL TEMP4 ; =
SUB TEMP5 ;得误差角 ; =
AND #0FFFH ;width of angle ; =
SACL EK ;保存误差角ek ; =
LACC UK ;Uk-1 ;LACC UK,12 Q12=
LTA EK ;ACC=Uk-1 + ek-1*K2 ;Q12 =
;T=ek ; =
MPY K1 ; ;K1 是Q12格式 =
;P=ek*K1 ; =
APAC ;ACC= Uk-1+ ek-1*K2+ek*K1 ;Q12 =
; ;SACH UK,4 =
SACL TEMP4 ;保存误差角 ;SACH TEMP4,4 =
*=========================================================================
BIT TEMP4,4
BCND DIR0,TC
LDP #0E1H
SPLK #0FFFFH,18H ;PADATDIR IOPA6=1,顺时针转
LDP #04H
SACL TEMP5 ;保存误差角
B COMPARE
DIR0: LDP #0E1H
SPLK #0FFBFH,18H
ABSOLUTE: ;if XF="1",produce absolute,the highest bit is sign
CLRC C
LDP #04H
LACC TEMP5,16
RPT #3H
SFL ;extend the sign bit
ABS
RPT #3H
SFR ;comeback the original value
SACH TEMP5
LACL TEMP5
AND #07FFH ;the value of after getting rid of the sign bit
SACL TEMP5 ;保存误差角
COMPARE:
LDP #0004H
LAR AR0,TEMP2 ;inflexion value
MAR *,AR1
LAR AR1,TEMP5
CMPR 2 ;if the number of ARP is greater than AR0 ,tc=1
BCND FULL,TC
RATE:
LT TEMP1 ;T1PR
MPY TEMP5 ;error angle
PAC
RPT #15
SUBC TEMP2 ;inflexion value
SACL TEMP6 ;K*E,relate PWM value
SACH TEMP7 ;remainder
; LACL 7H
; SPLK #0002H,7H
; RPT #000FH
; SUBC 7H
; SACL 7H ;inflexion/2
;
; LAR AR0,9H ;remainder
; MAR *,AR1
; LAR AR1,7H ;inflexion/2
; CMPR 1
; BCND INFLADD,TC ;if AR1<AR0 TC=1
; LACL 8H
; B LOAD ;if (inflexion/2) < remainder,208H(PWM value)-->CMPR1
;INFLADD: ;if (inflexion/2) > remainder,[208H(PWM value)+1]-->CMPR1
; LACL 8H
; ADD #1H
LOAD:
LDP #00E8H
SACL 17H ;the width of pwm is relate to compare number m
CLRC INTM ;save the count number to T1CMPR
B LOOP
FULL:
LDP #0004H
LACC TEMP1 ;the greatest number
SUB #1
LDP #00E8H
SACL 17H ;output the greatest range
B LOOP
RECOVER
LDP #0H
LT P_L
MPY #1
LPH P_H
LT T_SAVE
LACC ACCH,16
ADDS ACCL
LST #1,ST1_SAVE
LST #0,ST0_SAVE
LDP #0E8H
SPLK #0ffffH,EVAIFRA ;请所有中断标志
LDP #0
CLRC INTM
RET
;====================假中断=============================================
PHANTOM:
LDP #00E0H
SPLK 00E8H,WDCR
CLRC INTM
RET
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -