📄 las1.asm
字号:
;_______________________________________
; 激光传感器程序
; RS485las.asm
; 2003年12月19日
; 用于RS485输出
;____________________________________________
w equ H'0000'
f equ H'0001'
indf equ H'0000'
tmr0 equ H'0001'
pcl equ H'0002'
status equ H'0003'
fsr equ H'0004'
porta equ H'0005'
portb equ H'0006'
pclath equ H'000A'
intcon equ H'000B'
option_rg equ H'0001'
trisa equ H'0005'
trisb equ H'0006'
;----- OPTION Bits --------------------------------------------------------
not_rbpu EQU H'0007'
intedg EQU H'0006'
t0cs EQU H'0005'
t0se EQU H'0004'
psa EQU H'0003'
ps2 EQU H'0002'
ps1 EQU H'0001'
ps0 EQU H'0000'
tmr1ie equ 0
tmr1if equ 0
tmr1on equ 0
t0ie equ .4
gie equ 7
ccpxm3 equ 3
tmr0ie equ .5
peie equ .6
gie equ .7
t0if equ .2
tmr2ie equ .1
tmr2if equ .1
;----- status Bits --------------------------------------------------------
irp EQU H'0007'
rp0 EQU H'0005'
rp1 EQU H'0006'
z EQU H'0002'
c EQU H'0000'
;----- Register Files --------------------------------------------------
portc EQU H'0007'
sda EQU H'0004'
scl EQU H'0003'
portd EQU H'0008'
porte EQU H'0009'
pir1 EQU H'000C'
sspif equ .3
pir2 EQU H'000D'
tmr1l EQU H'000E'
tmr1h EQU H'000F'
t1con EQU H'0010'
tmr2 EQU H'0011'
t2con EQU H'0012'
sspcon2 equ 11h
sen equ .0
rsen equ .1
pen equ .2
rcen equ .3
acken equ .4
ackdt equ .5
ackstat equ .6
gcen equ .7
sspbuf EQU H'0013'
sspcon EQU H'0014'
ccpr1l EQU H'0015'
ccpr1h EQU H'0016'
ccp1con EQU H'0017'
ccpr2l EQU H'001B'
ccpr2h EQU H'001C'
ccp2con EQU H'001D'
ccp1if equ .2
ccp2if equ .0
txif equ .4
rcif equ .5
trisc EQU H'0007'
trisd EQU H'0008'
trise EQU H'0009'
pie1 EQU H'000C'
pie2 EQU H'000D'
pcon EQU H'000E'
pr2 EQU H'0012'
sspadd EQU H'0013'
sspstat EQU H'0014'
txsta EQU H'0018' ;*
rcsta EQU H'0018' ;
txreg EQU H'0019' ;
rcreg EQU H'001a' ;
spbrg EQU H'0019' ;*
adcon0 EQU 1FH
adcon1 EQU 1FH
adres EQU 1EH
go_done EQU 02H
;--------------------------------------------------------------------------
eeadr equ 0dh
eeadrh equ 0fh
eedata equ 0ch
eedatah equ 0eh
eecon1 equ 0ch
eecon2 equ 0dh
eeif equ .4
eepgd equ .7
wrerr equ .3
wren equ .2
wr equ .1
rd equ .0
;应用程序定义特殊寄存器,特殊控制线
sck equ .1
si equ .0
so equ .2
cs equ .3
看门狗 equ 00h
led equ .7
tr equ .4
测量时间 equ 54h
字间隔 equ 27h
rec_num equ 50h
tx_num equ 57h
rtcom equ .5
m_stau equ 51h
补偿杆标志位 equ .0
地面标志位 equ .1
探杆回波2 equ .2
w_mode equ 5fh
; .0=1 有探杆
; .0=0 无探杆
; .1=1 有探杆,有补偿
; .1=0 有探杆,无补偿
; .2=1 有探杆,避探杆第二回波
; .2=0 有探杆,不避探杆第二回波
; .4=0 无补偿计算
; .4=1 有补偿计算
bc_datah equ 53h
bc_datal equ 54h
bc2_datah equ 39h
bc2_datal equ 3ah
dm_datah equ 55h
dm_datal equ 56h
odm_datah equ 7eh
odm_datal equ 7fh
补偿归一h equ 17h ;21cm
补偿归一l equ 0a1h
偏差h equ 01h
偏差l equ .40
收发首地址 equ 20h
crch equ 58h
crcl equ 59h
addressh equ 20h
addressl equ 21h
databuf1 equ 22h
databuf2 equ 23h
dtimeh equ 24h
dtimel equ 25h
data1 EQU 70H
data2 EQU 71H
data3 equ 72h
data4 equ 73h
x1000 equ 74h
x100 equ 75h
x10 equ 76h
x1 equ 77h
ox1000 equ 2ch
ox100 equ 2dh
ox10 equ 2eh
ox1 equ 2fh
oneb equ 79h
calc1h equ 7dh
calc1l equ 7Ah
calc2h equ 7BH
calc2l EQU 7CH
last_data_h equ 67h
last_data_l equ 66h
tx_pi equ 52h
ww1 equ 30h
ww2 equ 31h
ww3 equ 32h
ww4 equ 33h
ww5 equ 34h
ww6 equ 35h
ww7 equ 36h
ww8 equ 37h
ww equ 38h
circle0 equ 5eh
circle1 equ 5fh
fsr00l equ 60h
fsr00h equ 61h
fsr01l equ 62h
fsr01h equ 63h
fsr02l equ 64h
fsr02h equ 65h
fsr03l equ 66h
fsr03h equ 67h
fsr04l equ 68h
fsr04h equ 69h
fsr05l equ 6ah
fsr05h equ 6bh
fsr06l equ 6ch
fsr06h equ 6dh
fsr07l equ 6eh
fsr07h equ 6fh
data1h equ 3bh
data1l equ 3ch
datal equ 41h
data2h equ 42h
data2l equ 43h
i2c_addressh equ 44h
i2c_addressl equ 43h
read_mode equ 0a1h
write_mode equ 0a0h
;************************************
org 000H
clrf pclath
goto main ;去主程序
;************************************
;************************************
org 004H
bcf intcon,7;t0if
retfie
;************************************
;************************************
main
call 系统初始化
call delay1s
; call delay1s
movlw 01h
movwf i2c_addressh
clrf i2c_addressl
bcf portc,1
movlw 30h
movwf fsr
bsf status,irp
call i2c_write_16
call delay10ms
movlw 20h
movwf fsr
bsf status,irp
call i2c_read_16
call 读出所有参数
call 通讯口初始化
;对T1初始化
bcf status,rp0
movlw B'00000001'
movwf t1con
clrf intcon
clrf rec_num
main_loop
call 测量距离
call 计算数据并接受数据
; call delay10ms
goto main_loop
;------------------------------------------------------------------
发送数据
;使用:dtimeh,dtimel
;使用:tx_num,ww3,tx_pi
btfss m_stau,7;是否需要发送?
return
clrf tx_pi
call delay900us
bsf portc,0
call delay900us
call delay900us
call delay900us
call delay900us
call delay900us
sent_datab
btfsc pir1,txif ;是否已发送完数据?
call ok_tx
clrwdt
movf tx_num,w
btfss status,z
goto sent_datab
call delay900us
call delay900us
bcf portc,0
bsf m_stau,6 ;设置刚发送标志
return
;===================================
;===================================
ok_tx
;数据发送子程序
;使用:tx_num,ww3,tx_pi
movf tx_num,w
btfsc status,z
return
movf fsr,w
movwf ww3
movf tx_pi,w
addlw 收发首地址
movwf fsr
bsf status,irp
movf indf,w
movwf txreg
movf ww3,w
movwf fsr
incf tx_pi
decf tx_num
movf tx_pi,w
return
;===================================
计算数据并接受数据
; btfsc m_stau,6 ;设置刚发送标志
; return
incf fsr07l
btfsc status,z
incf fsr07h
call 归一计算 ;260us
call 数据移位存储 ;135us
call 数据平均 ;4000us
return
;===================================
;===================================
归一计算 ;260us
movf odm_datah,w
movwf dm_datah
movf odm_datal,w
movwf dm_datal
return
;===================================
数据移位存储
;135us
movlw 0a0h
movwf data1
movlw .39
movwf data2
bcf ww6,5
call 双移位
movlw 0eeh
movwf fsr
movf dm_datal,w
movwf indf
incf fsr
movf dm_datah,w
movwf indf
return
;===================================
数据平均;同时数据接收
;4ms
;数据在0a0-0efh
;最大数据在1ao-1afh
;最小数据在1b0-1bfh
call 最大初始化
call 最小初始化
clrf x1000
clrf x100
clrf x10
clrf x1
movlw .40
movwf ww1
movlw 0a0h
movwf ww2
clrf ww8
aver_loop
bcf status,irp
movf ww2,w
movwf fsr
movf indf,w
movwf calc1l
incf fsr
movf indf,w
movwf calc1h
call 最大比较
call 最小比较
clrwdt
movf calc1l,w
addwf x1
btfsc status,c
incf calc1h
movf calc1h,w
addwf x10
btfsc status,c
incf x100
incf ww2
incf ww2
btfsc pir1,rcif
call ok_rec
incf ww8
decfsz ww1,f
goto aver_loop
;去掉极值
movlw .16
movwf data3
movlw 0a0h
movwf fsr
bsf status,irp
go_big
movf indf,w
subwf x1
btfsc status,c
goto next_sub
movlw .1
subwf x10
btfss status,c
decf x100
next_sub
incf fsr
movf indf,w
subwf x10
btfss status,c
decf x100
incf fsr
decfsz data3
goto go_big
movlw .48;.24*2
movwf oneb
call divsub3
movf x10,w
movwf last_data_h
movf x1,w
movwf last_data_l
return
;+++++++++++++++++++++++++++++++++++
最大初始化
;在1a0-1afh中置零
movlw 0a0h
movwf fsr
bsf status,irp
movlw .16
movwf data1
loopk1
clrf indf
incf fsr
decfsz data1
goto loopk1
return
;+++++++++++++++++++++++++++++++++++
最小初始化
;在1b0-1bfh中置ffh
movlw 0b0h
movwf fsr
bsf status,irp
movlw .16
movwf data1
loopk2
movlw 0ffh
movwf indf
incf fsr
decfsz data1
goto loopk2
return
;+++++++++++++++++++++++++++++++++++++
最大比较
;最大需要时间=250/5=50us
;数据在calc1h,calc1l
movlw 0afh
movwf fsr
bsf status,irp
movlw .8
movwf data2
combigloop
movf indf,w
subwf calc1h,w
btfsc status,z
goto comb1
btfsc status,c
goto yesbig1
decf fsr
decf fsr
decfsz data2
goto combigloop
return
comb1 decf fsr
movf indf,w
subwf calc1l,w
btfsc status,z
goto comb2
btfsc status,c
goto yesbig2
comb2
decf fsr
decfsz data2
goto combigloop
return
yesbig1
movlw 0a0h
movwf data1
bsf ww6,5
decf data2
call 双移位
movf calc1h,w
movwf indf
decf fsr
movf calc1l,w
movwf indf
return
yesbig2
movlw 0a0h
movwf data1
bsf ww6,5
; decf data2
call 双移位
movf calc1l,w
movwf indf
incf fsr
movf calc1h,w
movwf indf
return
;+++++++++++++++++++++++++++++++++++++
最小比较
;数据在calc1h,calc1l
movlw 0bfh
movwf fsr
bsf status,irp
movlw .8
movwf data2
comsmallloop
movf indf,w
subwf calc1h,w
btfsc status,z
goto coms1
btfss status,c
goto yessmall1
decf fsr
decf fsr
decfsz data2
goto comsmallloop
return
coms1 decf fsr
movf indf,w
subwf calc1l,w
btfsc status,z
goto coms2
btfss status,c
goto yessmall2
coms2
decf fsr
decfsz data2
goto comsmallloop
return
yessmall1
decf data2
movlw 0b0h
movwf data1
bsf ww6,5
call 双移位
movf calc1h,w
movwf indf
decf fsr
movf calc1l,w
movwf indf
return
yessmall2
decf data2
movlw 0b0h
movwf data1
bsf ww6,5
call 双移位
movf calc1l,w
movwf indf
incf fsr
movf calc1h,w
movwf indf
return
;===================================
双移位
;数据首地址=data1
;数据区在ww6,5=0 上区
;数据区在ww6,5=1 下区
;数据长度=data2
;使用:data1,data2,ww
btfsc ww6,5
bsf status,irp
btfss ww6,5
bcf status,irp
movf data2,w
sublw .1
btfsc status,c
return
movf fsr,w
movwf ww
movf data1,w
movwf fsr
move_loop
incf fsr
incf fsr
movf indf,w
decf fsr
decf fsr
movwf indf
incf fsr
incf fsr
incf fsr
movf indf,w
decf fsr
decf fsr
movwf indf
incf fsr
decfsz data2,f
goto move_loop
movf ww,w
movwf fsr
return
;=========================================
;------------------------------------------------------------------
测量距离
;status,c=0 ok
;结果在calc1h,calc1l
adsin movlw b'10000001'
movwf adcon0
bsf adcon0,go_done
nop
nop
adwait btfss adcon0,go_done
goto ok_ad
btfsc pir1,rcif
call ok_rec
goto adwait
ok_ad
movf adres,w
movwf calc1h
movwf odm_datah
bsf status,rp0
movf adres,w
bcf status,rp0
movwf calc1l
movwf odm_datal
bcf status,c
return
;************************************
;求绝对值程序
;输入(calc1h,calc1l),(data2h,data2l)
;输出(data1h,data1l)
;status,c=1 then (calc1h,calc1l)>(data2h,data2l)
;status,c=0 then (calc1h,calc1l)<(data2h,data2l)
;status,z=1 then (calc1h,calc1l)=(data2h,data2l)
求绝对值
movf calc1h,w
subwf data2h,w
btfsc status,z
goto high_equ
btfsc status,c
goto calc1h_small
calclh_big
movf data2l,w
subwf calc1l,w
movwf data1l
btfsc status,c
goto cm53
incf data2h,w
goto cm55
cm53
movf data2h,w
cm55
subwf calc1h,w
movwf data1h
bsf status,c
bcf status,z
return
calc1h_small
movf calc1l,w
subwf data2l,w
movwf data1l
btfsc status,c
goto cm62
incf calc1h,w
goto cm61
cm62
movf calc1h,w
cm61
subwf data2h,w
movwf data1h
bcf status,c
bcf status,z
return
high_equ
movf calc1l,w
subwf data2l,w
btfsc status,z
goto low_equ
btfsc status,c
goto calc1h_small
goto calclh_big
low_equ
clrf data1h
clrf data1l
bsf status,z
return
;************************************
;====================================================
;数据接收程序
ok_rec
bsf status,irp
movf rcreg,w
movwf ww
bcf pir1,rcif
bcf m_stau,6 ;清除刚发送标志
movf rec_num,w
btfsc status,z
goto rec_no1
xorlw .8
btfsc status,z
goto 分析接收到的数据 ;已收满一帧信息,返回
;未收满一帧信息
btfsc pir1,tmr1if
goto rec_no1
movf tmr1h,w
sublw 字间隔
btfsc status,c
goto 累加收
rec_no1
movlw .1
movwf rec_num
bcf pir1,tmr1if
clrf tmr1h
clrf tmr1l
movlw 收发首地址
movwf fsr
movf ww,w
movwf indf
return
累加收
movf rec_num,w
addlw 收发首地址
movwf fsr
bcf pir1,tmr1if
clrf tmr1h
clrf tmr1l
movf ww,w
movwf indf
incf rec_num
movf rec_num,w
xorlw .8
btfsc status,z
goto 分析接收到的数据 ;已收满一帧信息,返回
return
;====================================================
分析接收到的数据
;是否要发送?
;m_stau,7=0 不发送
;m_stau,7=1 需发送
;发送的数据长度:tx_num
bcf m_stau,7
movf rec_num,w
xorlw .8
btfss status,z
return ;未收满一帧信息,返回
clrf rec_num
;分析接收到的信息
movlw 收发首地址
movwf fsr
movf indf,w
btfsc status,z
goto address0_ok
xorwf fsr06l,w
btfss status,z
return
;地址正确,非广播地址
call 校验程序 ;120us
btfsc m_stau,4
return ;crc错误
;分析功能
incf fsr01l ;指令累加
btfsc status,z
incf fsr01h
movlw 收发首地址+1
movwf fsr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -