|
最后是主程序,所有的采样和TMR1的计数脉冲数都在主程序中计算并保存,随时可以在中断中使用。
main
movlw b'00000000' ;初始化前禁止所有中断
movwf INTCON
;Bank1 初始化ADC端口/中断/输出PORT口
;***************
banksel ADCON1
movlw b'00001000'
movwf ADCON1
movlw b'00000001'
movwf PIE1
bcf TRISD,1
;Bank0 初始化常量
;****************
banksel STATUS
bcf PORTD,1
; PPM每个通道的固定间隔宽度65536-488us(0xFE18)
movlw 0x18
movwf ppm_interval_origin
movlw 0xFE
movwf ppm_interval_origin+1
;初始化通道选择;在中断中使用
clrf ch_ppm_sel
bsf ch_ppm_sel,0
; PPM通道脉冲头标志位,首先输出脉冲头
clrf ppm_head_flag
comf ppm_head_flag,f
;Bank0 初始化ADC端口
;****************
movlw b'00000001'
movwf ADCON0
movlw b'00000001'
movwf T1CON
;全部初始化完成后开中断
;****************
movlw b'11000000'
movwf INTCON
ADC_catch
clrf ad_data_point ;复位ADC数据缓冲区指针
ADC_ch0;****
;采样并保存
call ADC_doing ;第一次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
call ADC_doing ;第二次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
;选择下一个通道-通道1
movlw b'00001001'
movwf ADCON0
;数据校验
;***************************************************************
movf ad_data_buff+ch0,w ;第一次数据->w
subwf ad_data_buff+ch0+1,w ;第二次数据-第一次数据->w
sublw ad_check_no ;最大误差值-w,若C=0有借位,数据不合格需要处理
bc Figure_ch0ppm ;C=1则表明数据正确,下一通道采样
;处理不合格数据
movf ad_data_buff+ch0,w ;第一次数据->w
addwf ad_data_buff+ch0+1,f ;第二次数据+第一次数据->第二次数据位
rrf ad_data_buff+ch0+1,f ;两次数据和/2求平均,放入第二次数据位
;***************************************************************
Figure_ch0ppm ;计算PPM通道脉冲宽度
movf ad_data_buff+ch0+1,w ;取最终合格的ADC数据
clrf ch_ppm+1 ;高8位清0
movwf ch_ppm ;数据送到PPM计算临时区低8位
bcf STATUS,C
rlf ch_ppm ;连续两次左移位将ADC结果×4
rlf ch_ppm+1
bcf STATUS,C
rlf ch_ppm
rlf ch_ppm+1
;***************************
;用常数减计数值求TMR1计数初值
movf ch_ppm,w ;低位计算
subwf ppm_interval_origin,w ; ppm_interval_origin减ch_ppm
movwf ch_ppm ;保存结果
skpc ;C=1没有借位跳过下面一条指令
incf ch_ppm+1,f ;有借位高位有借位,补被低位借掉的1
movf ch_ppm+1,w ;高位计算
subwf ppm_interval_origin+1,w ; ppm_interval_origin+1减ch_ppm+1
movwf ch_ppm+1 ;保存结果
;***************************
bcf INTCON,GIE ;禁止中断,保证数据的完整
;***************************
movwf ch_ppm_buff+ch0+1 ;将数据最终存入PPM计数缓存区
movf ch_ppm,w
movwf ch_ppm_buff+ch0
;***************************
bsf INTCON,GIE ;打开中断
;***************************
;通道0采样PPM计数转换完成
ADC_ch1;****
;采样并保存
call ADC_doing ;第一次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
call ADC_doing ;第二次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
;选择下一个通道-通道2
movlw b'00101001'
movwf ADCON0
;数据校验
;***************************************************************
movf ad_data_buff+ch1,w ;第一次数据->w
subwf ad_data_buff+ch1+1,w ;第二次数据-第一次数据->w
sublw ad_check_no ;最大误差值-w,若C=0有借位,数据不合格需要处理
bc Figure_ch1ppm ;C=1则表明数据正确,下一通道采样
;处理不合格数据
movf ad_data_buff+ch1,w ;第一次数据->w
addwf ad_data_buff+ch1+1,f ;第二次数据+第一次数据->第二次数据位
rrf ad_data_buff+ch1+1,f ;两次数据和/2求平均,放入第二次数据位
;***************************************************************
Figure_ch1ppm ;计算PPM通道脉冲宽度
movf ad_data_buff+ch1+1,w ;取最终合格的ADC数据
clrf ch_ppm+1 ;高8位清0
movwf ch_ppm ;数据送到PPM计算临时区低8位
bcf STATUS,C
rlf ch_ppm ;连续两次左移位将ADC结果×4
rlf ch_ppm+1
bcf STATUS,C
rlf ch_ppm
rlf ch_ppm+1
;***************************
;用常数减计数值求TMR1计数初值
movf ch_ppm,w ;低位计算
subwf ppm_interval_origin,w ; ppm_interval_origin减ch_ppm
movwf ch_ppm ;保存结果
skpc ;C=1没有借位跳过下面一条指令
incf ch_ppm+1,f ;有借位高位有借位,补被低位借掉的1
movf ch_ppm+1,w ;高位计算
subwf ppm_interval_origin+1,w ; ppm_interval_origin+1减ch_ppm+1
movwf ch_ppm+1 ;保存结果
;***************************
bcf INTCON,GIE ;禁止中断,保证数据的完整
;***************************
movwf ch_ppm_buff+ch1+1 ;将数据最终存入PPM计数缓存区
movf ch_ppm,w
movwf ch_ppm_buff+ch1
;***************************
bsf INTCON,GIE ;打开中断
;***************************
;通道1采样PPM计数转换完成
ADC_ch2;****
;采样并保存
call ADC_doing ;第一次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
call ADC_doing ;第二次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
;选择下一个通道-通道3
movlw b'00110001'
movwf ADCON0
;数据校验
;***************************************************************
movf ad_data_buff+ch2,w ;第一次数据->w
subwf ad_data_buff+ch2+1,w ;第二次数据-第一次数据->w
sublw ad_check_no ;最大误差值-w,若C=0有借位,数据不合格需要处理
bc Figure_ch2ppm ;C=1则表明数据正确,下一通道采样
;处理不合格数据
movf ad_data_buff+ch2,w ;第一次数据->w
addwf ad_data_buff+ch2+1,f ;第二次数据+第一次数据->第二次数据位
rrf ad_data_buff+ch2+1,f ;两次数据和/2求平均,放入第二次数据位
;***************************************************************
Figure_ch2ppm ;计算PPM通道脉冲宽度
movf ad_data_buff+ch2+1,w ;取最终合格的ADC数据
clrf ch_ppm+1 ;高8位清0
movwf ch_ppm ;数据送到PPM计算临时区低8位
bcf STATUS,C
rlf ch_ppm ;连续两次左移位将ADC结果×4
rlf ch_ppm+1
bcf STATUS,C
rlf ch_ppm
rlf ch_ppm+1
;***************************
;用常数减计数值求TMR1计数初值
movf ch_ppm,w ;低位计算
subwf ppm_interval_origin,w ; ppm_interval_origin减ch_ppm
movwf ch_ppm ;保存结果
skpc ;C=1没有借位跳过下面一条指令
incf ch_ppm+1,f ;有借位高位有借位,补被低位借掉的1
movf ch_ppm+1,w ;高位计算
subwf ppm_interval_origin+1,w ; ppm_interval_origin+1减ch_ppm+1
movwf ch_ppm+1 ;保存结果
;***************************
bcf INTCON,GIE ;禁止中断,保证数据的完整
;***************************
movwf ch_ppm_buff+ch2+1 ;将数据最终存入PPM计数缓存区
movf ch_ppm,w
movwf ch_ppm_buff+ch2
;***************************
bsf INTCON,GIE ;打开中断
;***************************
;通道2采样PPM计数转换完成
ADC_ch3;****
;采样并保存
call ADC_doing ;第一次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
call ADC_doing ;第二次ADC转换
incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
;选择下一个通道-通道0
movlw b'00000001'
movwf ADCON0
;数据校验
;***************************************************************
movf ad_data_buff+ch3,w ;第一次数据->w
subwf ad_data_buff+ch3+1,w ;第二次数据-第一次数据->w
sublw ad_check_no ;最大误差值-w,若C=0有借位,数据不合格需要处理
bc Figure_ch3ppm ;C=1则表明数据正确,下一通道采样
;处理不合格数据
movf ad_data_buff+ch3,w ;第一次数据->w
addwf ad_data_buff+ch3+1,f ;第二次数据+第一次数据->第二次数据位
rrf ad_data_buff+ch3+1,f ;两次数据和/2求平均,放入第二次数据位
;***************************************************************
Figure_ch3ppm ;计算PPM通道脉冲宽度
movf ad_data_buff+ch3+1,w ;取最终合格的ADC数据
clrf ch_ppm+1 ;高8位清0
movwf ch_ppm ;数据送到PPM计算临时区低8位
bcf STATUS,C
rlf ch_ppm ;连续两次左移位将ADC结果×4
rlf ch_ppm+1
bcf STATUS,C
rlf ch_ppm
rlf ch_ppm+1
;***************************
;用常数减计数值求TMR1计数初值
movf ch_ppm,w ;低位计算
subwf ppm_interval_origin,w ; ppm_interval_origin减ch_ppm
movwf ch_ppm ;保存结果
skpc ;C=1没有借位跳过下面一条指令
incf ch_ppm+1,f ;有借位高位有借位,补被低位借掉的1
movf ch_ppm+1,w ;高位计算
subwf ppm_interval_origin+1,w ; ppm_interval_origin+1减ch_ppm+1
movwf ch_ppm+1 ;保存结果
;***************************
bcf INTCON,GIE ;禁止中断,保证数据的完整
;***************************
movwf ch_ppm_buff+ch3+1 ;将数据最终存入PPM计数缓存区
movf ch_ppm,w
movwf ch_ppm_buff+ch3
;***************************
bsf INTCON,GIE ;打开中断
;***************************
;通道3采样PPM计数转换完成
;
goto ADC_catch
;ADC转换子程序
;**********************************************************************
ADC_doing
bsf ADCON0,GO ;开始ADC
btfsc ADCON0,GO ;ADC是否结束
goto $-1 ;等待ADC结束
;保存ADC结果
movlw ad_data_buff ;取ADC数据缓冲区首地址
movwf FSR ;FSR相对寻址
movf ad_data_point,w ;取相对位移指针
addwf FSR,f ;相对地址+位移指针
movf ADRESH,w ;取ADC转换结果
movwf INDF ;放入ADC转换结果
;incf ad_data_point,f ;指针位移+1指向下一个缓冲单元
;这一步在每个通道的主程序中完成
return
;***********************************************************************
END ; directive 'end of program' |
|