程序如下,用定时器中断int2,不对称取样法,产生pwm,但每次按下reset后,就不能产生pwem
;--------------------------------------以下是主程序-----------------------------------------------------
.TEXT
;--------------------------------------系统初始化程序--------------------------------------------------
_C_INT0 SETC INTM ;置位INTM,禁止中断
CLRC CNF ;清零CNF,B0为数据存储区
CLRC SXM
CLRC OVM
LDP #224 ;STO寄存器DP位置为224
SPLK #4H,SCSR1 ;4倍频,CLKOUT 40MHz
SPLK #68H,WDCR ;不用看门狗
LDP #225
LACC MCRA
OR #0FC0H ;设置PWM1-6引脚
SACL MCRA
LDP #225
LACC MCRB
OR #0100H
SACL MCRB
;--------------------------------------中断初始化程序------------------------------------------------
LDP #0
SPLK #0FFFFH,IFR ;清所有系统中断标志
SPLK #2H,IMR ;开IINT2中断
LACC #0ff00H
LDP #225
AND MCRC ;设置led
SACL MCRC
LDP #225
SPLK #0FF00H,PEDATDIR
LACC #06FFFH
AND PBDATDIR
SACL PBDATDIR ;设置按键初始化
LDP #232
SPLK #0FFFH,EVAIFRA ;清事件管理器A所有中断标志
SPLK #0FH,EVAIFRB
SPLK #0FH,EVAIFRC
SPLK #0200H,EVAIMRA ;开T1下溢中断
SPLK #0,EVAIMRB ;屏蔽所有中断
SPLK #0,EVAIMRC ;屏蔽所有中断
;--------------------------------------初始化事件管理器A程序-----------------------------------------
SPLK #1000,T1PR ;T1周期值=1000
SPLK #1000,CMPR1 ;占空比初值 0%
SPLK #1000,CMPR2
SPLK #1000,CMPR3
SPLK #0000011001100110B,ACTRA ;引脚PWM1,3,5高有效,2,4,6低有效
SPLK #01F4H,DBTCONA ;死区时间1*32*50ns=1.6uμs
SPLK #1000001000000000B,COMCONA ;允许比较,下溢重载
SPLK #0000100001000010B,T1CON ;连续增减计数方式,预分频=1
CLRC INTM ;开总中断
;--------------------------------------变量初始化---------------------------------------------------------
LDP #5
SPLK #0,K_ ;K=0
SPLK #0,FLAG
SPLK #42166,PITC ;π*T_carr =42166,Q28格式
SPLK #37749,F2M ;F-M转换系数,Q21格式
SPLK #1000,T_HALF ;T_carr/2的定时器计数脉甯鍪?Q0格式
SPLK #40000,F_CARR ;载波频率,Q1格式
SPLK #800,F_MODU ;Q4格式0~800,间隔16,
SPLK #120,PMIN ;最小正脉宽(脉冲个数),Q0格式
SPLK #1880,PMAX ;最小负脉宽时的最大正脉宽,Q0格式
;--------------------------------------主循环-------------------------------------------------------------
CYCLE
LDP #5
LACC F_MODU,13 ;调制波频率,Q4格式
SACH TEMP ;右移3位,Q1格式
LACC F_CARR ;载波频率,Q1格式
RPT #15
SUBC TEMP ;计算N=F_carr/F_modu
SACL N_ ;保存N,Q0格式
LACC N_,1 ;2N
SACL KMAX ;保存,Q0格式
LT F2M ; F-M转换系数37749,Q21格式
MPY F_MODU ;Q4格式
PAC
SACH M_
CALL KEY
B CYCLE
KEY:
SST #0,ST0_SAVE ;保存现场ST0
SST #1,ST1_SAVE ;保存ST1
LDP #5
SACH ACCH
SACL ACCL ;保存ACC
SPH P_HI
SPL P_LO ;保存 P
MPY #1 ;P<=T
SPL T_SAVE ;保存 T
DUJIAN LDP #225
LACC PBDATDIR
AND #80H
SUB #80H
BCND DUJIAN,EQ
YANSHI CALL DELAY
LDP #225
LACC PBDATDIR
AND #80H
SUB #80H
BCND DUJIAN,EQ
LDP #225
SPLK #0FFFFH,PEDATDIR
LDP #5
SPLK #800,F_MODU
SHIFANG LDP #225
LACC PBDATDIR
AND #80H
SUB #80H
BCND SHIFANG,NEQ
LDP #5 ;恢复现场
LT P_LO ;恢复P
MPY #1
LPH P_HI
LT T_SAVE ;恢复T
LACC ACCH,16
ADDS ACCL ;恢复ACC
LDP #0 ;指向B2
LST #1,ST1_SAVE ; 恢复ST1
LST #0,ST0_SAVE ; 恢复ST0
RET
;循环
;--------------------------------------假中断子程序---------------------------------------------------------
PHANTOM RET ;假中断
;--------------------------------------按键处理子程序-----------------------------------------
;--------------------------------------延时子程序-----------------------------------------
DELAY:
SST #0,ST0_SAVE ;保存现场ST0
SST #1,ST1_SAVE ;保存ST1
LDP #5
SACH ACCH
SACL ACCL ;保存ACC
SPH P_HI
SPL P_LO ;保存 P
MPY #1 ;P<=T
SPL T_SAVE ;保存 T
LACC #6000
KEYD1: SUB #1
BCND KEYD1,NEQ
LDP #5 ;恢复现场
LT P_LO ;恢复P
MPY #1
LPH P_HI
LT T_SAVE ;恢复T
LACC ACCH,16
ADDS ACCL ;恢复ACC
LDP #0 ;指向B2
LST #1,ST1_SAVE ; 恢复ST1
LST #0,ST0_SAVE ; 恢复ST0
RET
;--------------------------------------T1下溢中断处理子程序-----------------------------------------
_C_INT2 SST #0,ST0_SAVE ;保存现场ST0
SST #1,ST1_SAVE ;保存ST1
LDP #5
SACH ACCH
SACL ACCL ;保存ACC
SPH P_HI
SPL P_LO ;保存 P
MPY #1 ;P<=T
SPL T_SAVE ;保存 T
LDP #224
LACC PIVR,1 ;读偏移地址
ADD # PVECTORS ;子向量表首地址
BACC
WXM LDP #232
SPLK #0200H,EVAIFRA ;清中断标志
LDP #5
LT PITC ;π*T_carr =42166,Q28格式
MPY K_ ;Q0格式
PAC ;计算K*π*T_carr
SACH TEMP1 ;保存乘积,Q12格式
LT TEMP1
MPY F_MODU ;乘调制波频率,Q4格式
PAC ;计算K*π*T_carr*T_modu
RPT #3
ROR ;右移4位,Q12格式
SACL TEMP1 ;保存第1个角度值
LACC TEMP1
ADD #8579 ;加2π/3,Q12格式
SACL TEMP2 ;保存第2个角度值
SUB #25736 ;检测是否小于2π,Q12格式
BCND WXM1 ,LEQ ;小于2π跳转
SACL TEMP2 ;否则保存
WXM1 LACC TEMP1
ADD #17157 ;加4π/3,Q12格式
SACL TEMP3 ;保存第3个角度值
SUB #25736 ;检测是否小于2π,Q12格式
BCND WXM2 ,LEQ ;小于2π跳转
SACL TEMP3 ; 否则保存
WXM2 LT TEMP1 ;开始将第1个角度转换成度
MPY #917 ;乘转换系数,Q4格式
PAC
SACH TEMP1 ;保存第1个角度值,Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP1 ;偏移量
TBLR TEMP1 ;保存第1个SIN值,Q14格式有符号数
LT TEMP1
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP1,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP1
ADD #1,14 ;加+1
SACL TEMP1 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP1
PAC
SACH TEMP1,2 ;相当于右移14位,保存为Q0格式
LT TEMP2 ;开始将第2个角度转换成度
MPY #917
PAC
SACH TEMP2 ;保存第2个角度值,Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP2 ;偏移量
TBLR TEMP2 ;保存第2个SIN值,Q14格式有符号数
LT TEMP2
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP2,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP2
ADD #1,14 ;加+1
SACL TEMP2 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP2
PAC
SACH TEMP2,2 ;相当于右移14位,保存为Q0格式
LT TEMP3 ;开始将第3个角度转换成度
MPY #917
PAC
SACH TEMP3 ;保存第3个角度值,Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP3 ;偏移量
TBLR TEMP3 ;保存第3个SIN值,Q14格式有符号数
LT TEMP3
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP3,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP3
ADD #1,14 ;加+1
SACL TEMP3 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP3
PAC
SACH TEMP3,2 ;相当于右移14位,保存为Q0格式
LACC K_
ADD #1 ;K+1
SACL K_
LT PITC ;π*T_carr =42166,Q28格式
MPY K_ ;Q0格式
PAC ;计算K*π*T_carr
SACH TEMP4 ;保存乘积,Q12格式
LT TEMP4
MPY F_MODU ;乘调制波频率,Q4格式
PAC ;计算K*π*T_carr*T_modu
RPT #3
ROR ;右移4位,Q12格式
SACL TEMP4 ;保存第4个角度值
LACC TEMP4
ADD #8579 ;加2π/3,Q12格式
SACL TEMP5 ;保存第5个角度值
SUB #25736 ;检测是否小于2π,Q12格式
BCND WXM3 ,LEQ ;小于2π跳转
SACL TEMP5 ;否则保存
WXM3 LACC TEMP4
ADD #17157 ;加4π/3,Q12格式
SACL TEMP6 ;保存第6个角度值
SUB #25736 ;检测是否小于2π,Q12格式
BCND WXM4 ,LEQ ;小于2π跳转
SACL TEMP6 ;否则保存
WXM4 LT TEMP4 ;开始将第4鼋嵌茸怀啥?
MPY #917 ;乘转换系数,Q4格式
PAC
SACH TEMP4 ;保存第4个角度值,Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP4 ;偏移量
TBLR TEMP4 ;保存第4个SIN值,Q14格式有符号数
LT TEMP4
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP4,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP4
ADD #1,14 ;加+1
SACL TEMP4 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP4
PAC
SACH TEMP4,2 ;相当于右移14位,保存为Q0格式
LT TEMP5 ;开始将第5个角度转换成度
MPY #917
PAC
SACH TEMP5 ;保存第5个角度值,Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP5 ;偏移量
TBLR TEMP5 ;保存第5个SIN值,Q14格式有符号数
LT TEMP5
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP5,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP5
ADD #1,14 ;加+1
SACL TEMP5 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP5
PAC
SACH TEMP5,2 ;相当于右移14位,保存为Q0格式
LT TEMP6 ;开始将第6个角度转换成度
MPY #917
PAC
SACH TEMP6 ;保存第6个角度?Q0格式
LACC #SIN_ENTRY ;SIN表入口地址
ADD TEMP6 ;偏移量
TBLR TEMP6 ;保存第6个SIN值,Q14格式有符号数
LT TEMP6
MPY M_ ;乘M,Q9格式
PAC ;Q23格式
SACH TEMP6,7 ;相当于右移9位,Q14格式有符号数
LACC TEMP6
ADD #1,14 ;加+1
SACL TEMP6 ;保存, Q14格式
LT T_HALF ;T_carr/2=1000,Q0格式
MPY TEMP6
PAC
SACH TEMP6,2 ;相当于右移14位,保存为Q0格式
LACC K_
ADD #1 ;K+1
SACL K_
SUB KMAX ;比较K是否小于2N
BCND WXM5,LT ;是则跳转
SPLK #0,K_ ;否则K=0
WXM5 LACC TEMP1
ADD TEMP4 ;计算脉宽
SACL TEMP1 ;暂存
SUB PMIN ;检测是否小于最小正脉宽3微秒
BCND WXM6,GT ;不是继续
SPLK #0,TEMP1 ;是则删除窄脉冲
B WXM7
WXM6 LACC TEMP1 ;检测是否小于最小负脉宽3微秒
SUB PMAX
BCND WXM7,LT ;不是继续
SPLK #2000,TEMP1 ;是则删除窄脉冲
WXM7 LACC #2000 ;2倍周期值
SUB TEMP1 ;计算比较值1
ROR ;除2
LDP #232 ;指向事件管理器A
SACL CMPR1 ;保存比较值1
LDP #5
LACC TEMP2
ADD TEMP5 ;计算脉宽
SACL TEMP2 ;暂存
SUB PMIN ;检测是否小于最小正脉宽3微秒
BCND WXM8,GT ;不是继续
SPLK #0,TEMP2 ;是则删除窄脉冲
B WXM9
WXM8 LACC TEMP2 ;检测是否小于最小负脉宽3微秒
SUB PMAX
BCND WXM9,LT ;不是继续
SPLK #2000,TEMP2 ;是则删除窄脉冲
WXM9 LACC #2000 ;2倍周期值
SUB TEMP2 ;计算比较值2
ROR ;除2
LDP #232 ;指向事件管理器A
SACL CMPR2 ;保存比较值2
LDP #5
LACC TEMP3
ADD TEMP6 ;计算脉宽
SACL TEMP3 ;暂存
SUB PMIN ;检测是否小于最小正脉宽3微秒
BCND WXM10,GT ;不是继续
SPLK #0,TEMP3 ;是则删除窄脉冲
B WXM11
WXM10 LACC TEMP3 ;检测是否小于最小负脉宽3微秒
SUB PMAX
BCND WXM11,LT ;不是继续
SPLK #2000,TEMP3 ;是则删除窄脉冲
WXM11 LACC #2000 ;2倍周期值
SUB TEMP3 ;计算比较值3
ROR ;除2
LDP #232 ;指向事件管理器A
SACL CMPR3 ;保存比较值3
LDP #5 ;恢复现场
LT P_LO ;恢复P
MPY #1
LPH P_HI
LT T_SAVE ;恢复T
LACC ACCH,16
ADDS ACCL ;恢复ACC
LDP #0 ;指向B2
LST #1,ST1_SAVE ; 恢复ST1
LST #0,ST0_SAVE ; 恢复ST0
CLRC INTM ; 开中断
RET ; 返回
|