|
第二部分,TMR1中断处理程序,输出所有通道的PPM信号,只有通道尾脉冲的计数值是在中断中实时计算的。
;**********************************************************************
ORG 0x000 ; processor reset vector
nop ; nop required for icd
goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register
;开始处理TMR1溢出中断
banksel STATUS
btfss PIR1,TMR1IF ;是否TMR1溢出中断,TMR1IF=1则处理中断
goto Go_main ;不是TMR1溢出中断,退出中断
bcf PIR1,TMR1IF ;清除TMR1溢出中断标志
bcf T1CON,TMR1ON ;暂停TMR1
;在进入中断和暂停TMR1前有约14us的延迟
;这个时间应该在最终完成所有程序后得到负补偿
;无论是在头脉冲,尾脉冲,还是固定间隔宽度
;判断是否脉冲头
;***********************
btfsc ppm_head_flag,0 ; PPM通道脉冲头标志为0则输出PPM通道脉宽/2us
goto Get_ppm_head ;取PPM通道脉冲头/2us
Get_ppm_ch ;输出PPM通道脉宽
Tail_ppm ;/26us
;通道尾脉冲也视作最后一个正常通道来处理,同时完成标志/计数的复位
;***********************
btfss ch_ppm_sel,4 ;判断是否通道尾输出/2us
goto ch3_ppm ;转去通道3/2us
clrf ch_ppm_sel ;重置通道选择
bsf ch_ppm_sel,0
;********************************计算尾脉冲
;取尾计数值的补数/把下面的减法变加法(方便统一理解程序)
comf ppm_tail_L,f
comf ppm_tail_H,f
movlw 0x01
addwf ppm_tail_L,f
skpnc ;2us
incf ppm_tail_H,f
;用常数减计数值求TMR1计数初值(用补数变加法)
movlw 0xE0 ; 0xE0(65536-20000)低8位
addwf ppm_tail_L,f ;固定的20ms间隔低8位
skpnc ;判断进位/2us
incf ppm_tail_H,f ;高8位加1
;计算高8位
movlw 0xB1 ; 0xB1(65536-20000)高8位
addwf ppm_tail_H,f ;固定的20ms间隔低高8位
;************************
;取通道尾的PPM计数初值低8位
;************************
movf ppm_tail_L,w ;取PPM计数初值数据
movwf TMR1L ;送TMR1L
;取通道尾的PPM计数初值高8位
;************************
movf ppm_tail_H,w ;取PPM计数初值数据
movwf TMR1H ;送TMR1H
;清尾数
clrf ppm_tail_L
clrf ppm_tail_H
;
goto Start_tmr1 ;2us
ch3_ppm ;/14us
;通道3
;************************
btfss ch_ppm_sel,3 ;判断是否通道3输出/2us
goto ch2_ppm ;转去通道2/2us
rlf ch_ppm_sel,f ;通道选择,准备下一通道
;取通道3的PPM计数初值低8位
;************************
movf ch_ppm_buff+ch3,w ;取PPM计数初值数据
movwf TMR1L ;送TMR1L
;累计PPM尾
addwf ppm_tail_L,f ;累计PPM脉冲尾低8位
skpnc ;判断进位/2us
incf ppm_tail_H,f ;高8位加1
;
;取通道3的PPM计数初值高8位
;************************
movf ch_ppm_buff+ch3+1,w ;取PPM计数初值数据
movwf TMR1H ;送TMR1H
;********************************累计PPM尾
addwf ppm_tail_H,f ;累计PPM脉冲尾高8位
;************************
goto Start_tmr1 ;2us
ch2_ppm ;/14us
;通道2
;************************
btfss ch_ppm_sel,2 ;判断是否通道2输出
goto ch1_ppm ;转去通道1
rlf ch_ppm_sel,f ;通道选择,准备下一通道
;取通道2的PPM计数初值低8位
;************************
movf ch_ppm_buff+ch2,w ;取PPM计数初值数据
movwf TMR1L ;送TMR1L
;累计PPM尾
addwf ppm_tail_L,f ;累计PPM脉冲尾低8位
skpnc ;判断进位
incf ppm_tail_H,f ;高8位加1
;
;取通道2的PPM计数初值高8位
;************************
movf ch_ppm_buff+ch2+1,w ;取PPM计数初值数据
movwf TMR1H ;送TMR1H
;********************************累计PPM尾
addwf ppm_tail_H,f ;累计PPM脉冲尾高8位
;************************
goto Start_tmr1
ch1_ppm ;/14us
;通道1
;************************
btfss ch_ppm_sel,1 ;判断是否通道1输出
goto ch0_ppm ;转去通道1
rlf ch_ppm_sel,f ;通道选择,准备下一通道
;取通道1的PPM计数初值低8位
;************************
movf ch_ppm_buff+ch1,w ;取PPM计数初值数据
movwf TMR1L ;送TMR1L
;累计PPM尾
addwf ppm_tail_L,f ;累计PPM脉冲尾低8位
skpnc ;判断进位
incf ppm_tail_H,f ;高8位加1
;
;取通道1的PPM计数初值高8位
;************************
movf ch_ppm_buff+ch1+1,w ;取PPM计数初值数据
movwf TMR1H ;送TMR1H
;********************************累计PPM尾
addwf ppm_tail_H,f ;累计PPM脉冲尾高8位
;************************
goto Start_tmr1
ch0_ppm ;/14us
;通道0
;************************
btfss ch_ppm_sel,0 ;判断是否通道0输出
goto $+1 ;匹配指令周期数
rlf ch_ppm_sel,f ;通道选择,准备下一通道
;取通道0的PPM计数初值低8位
;************************
movf ch_ppm_buff+ch0,w ;取PPM计数初值数据
movwf TMR1L ;送TMR1L
;累计PPM尾
addwf ppm_tail_L,f ;累计PPM脉冲尾低8位
skpnc ;判断进位
incf ppm_tail_H,f ;高8位加1
;
;取通道0的PPM计数初值高8位
;************************
movf ch_ppm_buff+ch0+1,w ;取PPM计数初值数据
movwf TMR1H ;送TMR1H
;********************************累计PPM尾
addwf ppm_tail_H,f ;累计PPM脉冲尾高8位
;************************
goto Start_tmr1
Get_ppm_head;/9us
;输出PPM通道脉冲头
;取PPM脉冲头宽度低8位
;************************
movlw 0x0C ; PPM头脉冲宽度65536-500us=(0xFE0C)
movwf TMR1L ;送TMR1L
;累计PPM尾
addwf ppm_tail_L,f ;累计PPM脉冲尾低8位
skpnc ;判断进位/2us
incf ppm_tail_H,f ;高8位加1
;
;取PPM脉冲头宽度高8位
;************************
movlw 0xFE ; PPM头脉冲宽度65536-500us=(0xFE0C)
movwf TMR1H ;送TMR1H
;********************************累计PPM尾
addwf ppm_tail_H,f ;累计PPM脉冲尾高8位
;*************************
Start_tmr1
bsf T1CON,TMR1ON ;启动TMR1
;输出PPM信号
;**************************
btfsc ppm_head_flag,0
goto Output_head ;输出高电平PPM通道脉冲头
Output_ch_ppm
bcf PORTD,1 ;输出低电平PPM通道脉宽,包括尾脉冲
goto Go_clear
Output_head
bsf PORTD,1 ;输出高电平通道脉冲头
;***************************
Go_clear
;输出PPM脉冲头标志位反转,输出一次脉冲头,再输出一次PPM脉冲宽度
comf ppm_head_flag,f
Go_main
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt |
|