我用LF2407A通过PID控制PWM占空比来稳定输出电压在3V,但占空比不随ADCIN0输入的电压而变化,不知问题在哪里?请各位高手指教!!!程序如下:
.title \"ex.asm\"
.include \"F2407REGS.H\"
;.def _c_int0
Kp_init .set 100h
Ki_high_init .set 00h
Ki_low_init .set 1000h
Kd_init .set 05h
PID_ref_init .set 03
PID_output_MAX .set 07FFh
PID_output_MIN .set 0h
T3COMPR .set 00FFh
.data
ADRESULT .word 00h
PID_input .word 00h
PID_output .word 00h
PID_output1 .word 00h
PID_reference .word 00h
PID_e0 .word 00h
PID_e1 .word 00h
PID_e2 .word 00h
Kp .word 00h
Ki_high .word 00h
Ki_low .word 00h
Kd .word 00h
A_coeff_high .word 00h
A_coeff_low .word 00h
B_coeff .word 00h
tmp1_high .word 00h
tmp1_low .word 00h
tmp2_high .word 00h
tmp2_low .word 00h
tmp3 .word 00h
e0_sign .word 00h
abs_e0 .word 00h
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;(1)建立中断向量表
.sect \".vectors\"
RSVECT B _c_int0
INT1 B GISR1
INT2 B PHANTOM
INT3 B PHANTOM
INT4 B PHANTOM
INT5 B PHANTOM
INT6 B PHANTOM
;中断子向量入口定义
.sect \".pvecs\" ;定义子向量段
PVECTORS B PHANTOM ;保留向量偏移量0000H
B PHANTOM ;偏移量0001H
B PHANTOM ;偏移量0002H
B PHANTOM ;偏移量0003H
B ADCINT_ISR ;偏移量0004H
B PHANTOM ;偏移量0005H
B PHANTOM ;偏移量0006H
B PHANTOM ;偏移量0007H
B PHANTOM ;偏移量0008H
B PHANTOM ;偏移量0009H
B PHANTOM ;偏移量000AH
B PHANTOM ;偏移量000BH
B PHANTOM ;偏移量000CH
B PHANTOM ;偏移量000DH
B PHANTOM ;偏移量000EH
B PHANTOM ;偏移量000FH
B PHANTOM ;偏移量0010H
B PHANTOM ;偏移量0011H
B PHANTOM ;偏移量0012H
B PHANTOM ;偏移量0013H
B PHANTOM ;偏移量0014H
B PHANTOM ;偏移量0015H
B PHANTOM ;偏移量0016H
B PHANTOM ;偏移量0017H
B PHANTOM ;偏移量0018H
B PHANTOM ;偏移量0019H
B PHANTOM ;偏移量001AH
B PHANTOM ;偏移量001BH
B PHANTOM ;偏移量001CH
B PHANTOM ;偏移量001DH
B PHANTOM ;偏移量001EH
B PHANTOM ;偏移量001FH
B PHANTOM ;偏移量0020H
B PHANTOM ;偏移量0021H
B PHANTOM ;偏移量0022H
B PHANTOM ;偏移量0023H
B PHANTOM ;偏移量0024H
B PHANTOM ;偏移量0025H
B PHANTOM ;偏移量0026H
B PHANTOM ;偏移量0027H
B PHANTOM ;偏移量0028H
B PHANTOM ;偏移量0029H
B PHANTOM ;偏移量002AH
B PHANTOM ;偏移量002BH
B PHANTOM ;偏移量002CH
B PHANTOM ;偏移量002DH
B PHANTOM ;偏移量002EH
B PHANTOM ;T3PINT_ISR ;偏移量002FH,T3PINT周期中断
B PHANTOM ;偏移量0030H
B PHANTOM ;偏移量0031H
B PHANTOM ;偏移量0032H
B PHANTOM ;偏移量0033H
B PHANTOM ;偏移量0034H
B PHANTOM ;偏移量0035H
B PHANTOM ;偏移量0036H
B PHANTOM ;偏移量0037H
B PHANTOM ;偏移量0038H
B PHANTOM ;偏移量0039H
B PHANTOM ;偏移量003AH
B PHANTOM ;偏移量003BH
B PHANTOM ;偏移量003CH
B PHANTOM ;偏移量003DH
B PHANTOM ;偏移量003EH
B PHANTOM ;偏移量003FH
B PHANTOM;CANMBX_ISR ;偏移量0040H
B PHANTOM ;偏移量0041H
B PHANTOM ;偏移量0042H
.text
_c_int0:
NOP
CALL system_init
CALL PWM_INIT
CALL PID_init
CALL cy_AD_init
cy_LOOP:
NOP
NOP
B cy_LOOP
system_init:
SETC INTM
CLRC OVM
CLRC SXM
CLRC CNF
LDP #DP_PF1
SPLK #085FEh,SCSR1
SPLK #0E8h,WDCR
LDP #0
SPLK #0001h,IMR
SPLK #0FFFFh,IFR
RET
;(4)EVB模块的PWM初始化程序
PWM_INIT:
LDP #DP_PF2 ;指向7080h~7100h区
LACL MCRC
OR #007EH ;IOPE[1~6]被配置为基本功能方式:PWM[7~12]
SACL MCRC
LDP #DP_EVB ;指向7500h~7580h区
SPLK #0FFFFH,EVAIFRA ;清EVB 全部中断标志
SPLK #00006H,ACTRB ;PWM12,10,8 低有效,PWM11,9,7 高有效
SPLK #00H,DBTCONB
SPLK #ADRESULT,T3COMPR ;不使能死区控制
SPLK #T3COMPR,CMPR4 ;设置比较初值 PWM7高电平占,
; PWM8低电平占10/60
SPLK #250H,T3PR ;设置定
;即PWM周期为250h个CPU时钟周期
SPLK #0A600H,COMCONB ;使能比较操作
SPLK #0,T3CNT
SPLK #041H,GPTCONB ;TCOMPOE=1使能
; T3PIN=01低有效
SPLK #080H,EVAIMRA ;通用定时器3周期中
SPLK #0174EH,T3CON ;TMODE=10 连续增计数模式,
;TENABLE=1 定时器计数使能, TCLKS=00
;内部CPU时钟
;TECMPR=1 定时器3比较使能, SELT3PR=0
CLRC INTM ;开总中断
RET
;(5)定时器3中断程序
GISR2: ;优先级INT2中断入口
;保护现场
LDP #0E0H
LACC PIVR,1 ;读取外设中断向
ADD #PVECTORS
BACC ;跳到相应的中断服务子程序
T3GP_ISR: ;通用定时器3中断入口
LDP #6
CALL ADCINT_ISR
LDP #DP_EVB
SACL CMPR4
SPLK #0,T3CNT
GISR2_RET: ;中断返回
;恢复现场
CLRC INTM ;开总中
RET
cy_AD_init:
LDP #DP_EVB
SPLK #0000h,T4CNT
SPLK #0176h,T4PR
SPLK #0400h,GPTCONB
SPLK #0160Ch,T4CON
SPLK #0FFFFh,EVBIFRA
SPLK #0FFFFh,EVBIFRB
SPLK #0FFFFh,EVBIFRC
SPLK #00000h,EVBIMRA
SPLK #00000h,EVBIMRB
SPLK #00000h,EVBIMRC
LDP #DP_PF2
SPLK #0000h,ADCTRL1
SPLK #8404h,ADCTRL2
SPLK #0001h,MAXCONV
SPLK #0000h,CHSELSEQ1
SPLK #0000h,CHSELSEQ2
SPLK #0000h,CHSELSEQ3
SPLK #0000h,CHSELSEQ4
CALL AD_Start
LDP #4
SPLK #0000h,ADRESULT
RET
AD_Start:
LDP #DP_EVB
LACL T4CON
OR #0040h
SACL T4CON
RET
PID_Control:
SETC SXM
SETC OVM
SPM #0
LDP #4
LACL ADRESULT
SACL PID_input
LACC Ki_high,16
ADDS Ki_low
ADD Kp,16
ADD Kd,16
SACH A_coeff_high
SACL A_coeff_low
LACC Kd,16
SFL
ADD Kp,16
SACH B_coeff
LACC PID_reference
SUB PID_input
SACL PID_e0
LT Kd
MPY PID_e2
PAC
LT B_coeff
MPY PID_e1
SPAC
SACH tmp1_high,1
SACL tmp1_low,1
LACC PID_e0
SACL e0_sign
ABS
SACL abs_e0
LT abs_e0
MPYU A_coeff_low
SPH tmp2_low
MPYU A_coeff_high
PAC
ADDS tmp2_low
SACH tmp2_high,1
SACL tmp2_low,1
LACC e0_sign
BCND cy_DONE,GT
LACC tmp2_high,16
ADDS tmp2_low
NEG
SACH tmp2_high
SACL tmp2_low
cy_DONE:
LACC tmp1_high,16
ADDS tmp1_low
ADDS tmp2_low
ADD tmp2_high,16
SACH tmp3
LACC PID_output1,16
ADD tmp3,16
SACH PID_output
LACC PID_output
SUB #PID_output_MAX
BCND greater_MAX,GT
LACC PID_output
SUB #PID_output_MIN
BCND less_MIN,LT
B PID_end
greater_MAX:
SPLK #PID_output_MAX,PID_output
B PID_end
less_MIN:
SPLK #PID_output_MIN,PID_output
PID_end:
LDP #4
LACC PID_e1
SACL PID_e2
LACC PID_e0
SACL PID_e1
LACC PID_output
SACL PID_output1
CLRC SXM
RET
PID_init:
LDP #4
SPLK #Kp_init,Kp
SPLK #Ki_high_init,Ki_high
SPLK #Ki_low_init,Ki_low
SPLK #Kd_init,Kd
SPLK #PID_ref_init,PID_reference
SPLK #0,PID_e2
SPLK #0,PID_e1
SPLK #0,PID_e0
SPLK #0,PID_output1
SPLK #0,PID_output
RET
GISR1:
LDP #DP_PF1
LACC PIVR,1
ADD #PVECTORS
BACC
ADCINT_ISR:
CLRC SXM
LDP #4
LAR AR2,#RESULT0
MAR *,AR2
LACC *,10
SACH ADRESULT
CALL PID_Control
CLRC INTM
RET
PHANTOM:
LDP #DP_PF1
SPLK #05555h,WDKEY
SPLK #0AAAAh,WDKEY
RET
.end
可以进入中断吗?
初步感觉,在PHANTOM中要有
CLRC INTM
还不行
在PHANTOM中加了CLRC INTM 也不行。如何看能否进入中断?
可以在中断程序里设个断点。
如果不能设,就全速运行,点停止。
多试几次,看会不会停在中断程序处。
还有,我看你的程序,没有保护和恢复现场。
有啊
有啊
GISR1不是保护和恢复了了现场吗?GISR2是不是多余的?与GISR1有没有冲突? MY QQ:497872962。不能设置断点,全速运行后,总是停在CY_LOOP中的NOP语句上。可见没进ADCINT中断,原因何在?据说2407A和2407的ADC模块不兼容,我的AD程序是2407的,是不是这个原因?
你根本没有保护现场。
保护现场需要保护A,P,T,ST0,ST1
这几个寄存器。给你个例子:
保护现场:
LDP #0
SST #ST0,ST0_SAVE ;保存现场ST0
SST #ST1,ST1_SAVE ;保存ST1
LDP #10H
SACH ACCH
SACL ACCL ;保存ACC
SPH P_HI
SPL P_LO ;保存 P
MPY #1 ;P<=T
SPL T_SAVE ;保存 T
恢复现场:
LDP #10H ;恢复现场
LT P_LO ;恢复P
MPY #1
LPH P_HI
LT T_SAVE ;恢复T
LACC ACCH,16
ADDS ACCL ;恢复ACC
LDP #0
LST #ST1,ST1_SAVE ; 恢复ST1
LST #ST0,ST0_SAVE ; 恢复ST0
CLRC INTM ; 开中断
RET
还是不行
加了现场保护和恢复现场,还是不行,请各位大侠帮忙!!!!!!!!!
看不到
不能设断点,怎么看结果寄存器里的值随不随电压变化?
你可以先给AD上加一个电压,运行程序。
点击停止,在数据空间查看结果寄存器里的值。
然后换个电压,继续运行程序。
点击停止,在看一次寄存器里的值,就可以了。