📄 wpks1.9.asm
字号:
In_Idle_Mode:
Ultrasonic_Scan: ;接收返回的超声波,如果没有硬件问题,Ultrasonic_Bit总是可以检测到高电平
JB Time60ms,NearDis ;TimeNow60ms ;如果跳出,则没有传感器
JNB Ultrasonic_Bit,Ultrasonic_Scan ;;没收到返回信号,继续等待
Scan_Puls1_Up:
CLR TR0
MOV Puls_Time_TL,TL0 ;得到第一个符合要求的上升沿的时间
MOV Puls_Time_TH,TH0 ;用于近距离的判断
SETB TR0 ;如果没有探头会取到极限值(25536+1700)
Delay180us:
MOV R7,#35;30 ;1cycle
Loop180us:
JNB Ultrasonic_Bit,Ultrasonic_Scan ;2cycle 检测高电平时间,以去杂波(小于140US为杂波)
DJNZ R7,Loop180us ;2cycle
MOV A,Puls_Time_TL ;
CLR C ;未接探头时盲点时间为1250us左右(含500us的超声波发送时间)
SUBB A,#082H;0C2H ;是否大于1250+5536=0x1A82, 5536即15A0为T0计数初值,
MOV A,Puls_Time_TH ;这是判断经过的时间是否大于 1250us.
SUBB A,#01AH;0B6H
JC Ultrasonic_Scan
Right_Up:
MOV Temp1,Puls_Time_TL ;暂存第一个符合要求上升沿到达时间,即盲点时间
MOV Temp2,Puls_Time_TH
MOV A,Puls_Time_TL ;接上探头时余振时间范围为1500-1765us左右,
CLR C ;只要低于1765us,就能正常检测到最小探测距离0.3m(1765us)
SUBB A,Scot_Time_L ;
MOV A,Puls_Time_TH
SUBB A,Scot_Time_H ;是否大于余振时间
JC Not_NearDis
NearDis:
MOV Data_Buf,#0 ;大于余振时间为近距离,直接设距离值为0
MOV Two_Digital_Dis,#0
AJMP Receive_Over
Not_NearDis:
Wait_Puls_Low:
JB Time60ms,TimeNow60ms ;等待超声波返回时的下降沿,如果检测不到则是远距离无返回信号
JB Ultrasonic_Bit,Wait_Puls_Low
Delay140us:
MOV R7,#30;20 ;1 cycle
Loop140us:
JB Ultrasonic_Bit,Wait_Puls_Low ;2 检测低电平保持时间,小于120US为杂波
DJNZ R7,Loop140us ;2
Puls_Turn_Low:
CLR TR0 ;检测到了正确的下降波形,有信号返回
MOV Puls_Time_TL,TL0 ;得到第一个脉冲的下降沿时间
MOV Puls_Time_TH,TH0 ;用于计算距离
SETB TR0
SETB Puls_Num_F1 ;检测到一个完整回波,标志置位
Wait_60ms_over:
JNB Time60ms,Wait_60ms_Over
TimeNow60ms:
JB Puls_Num_F1,Rx_1_Puls ;检测到一个完整的脉冲,然后可以进行时间计算
No_Sensor:
AJMP LongDst
;------------------------------------------------------------
Rx_1_Puls:
MOV A,Puls_Time_TL ;计算返回时间,以测出其距离
CLR C
SUBB A,#T60msL ;当前时间减去起点时间,得到发送到返回的时间
MOV Puls_Time_TL,A ;保存经过时间
MOV A,Puls_Time_TH
SUBB A,#T60msH
MOV Puls_Time_TH,A
MOV A,Puls_Time_TL ;判断时间是否太长,大于14706us(3972H,对应250cm)视为长距离。
CLR C
SUBB A,#72H
MOV A,Puls_Time_TH
SUBB A,#39H
JNC LongDst ;长距离
CALL CalculateDistance ;计算距离
AJMP Receive_Over
;-----------------------------------------------
LongDst:
MOV Data_Buf,#25
MOV Two_Digital_Dis,#250
Receive_Over: ;;接收完成
CALL ScotTimeUpdate ;更新盲点时间
RET
;==================超声波收发结束===============
;================================================距离计算程序==============================================
;乘法部分
;入口:Puls_Time_TH,Puls_Time_TL(被乘数)
;出口:Temp4,Temp3,Temp2(乘积)
;使用:Temp1(乘数),Temp5(扩展的被乘数字节),A,R7
;功能:(Puls_Time_TH)(Puls_Time_TL)
; x (Temp1) ---34
; ----------------------------
; (Temp4)(Temp3)(Temp2)
CalculateDistance:
MOV Temp1,#0
MOV Temp2,#0 ;乘积的低一位
MOV Temp3,#0 ;乘积的第二位
MOV Temp4,#0 ;乘积的第三位
MOV Temp5,#0 ;同Puls_Time_TH\Puls_Time_TL一起组成被乘数
MOV R7,#6 ;移位次数
MOV Temp1,#34 ;乘数(34DM/10MS)
Re_Mul34:
MOV A,Temp1
RRC A
MOV Temp1,A ;乘数除以2
JNC Zero_Bit
MOV A,Temp2 ;是1则结果加上被乘数
ADD A,Puls_Time_TL ;;低位相加
MOV Temp2,A
MOV A,Temp3
ADDC A,Puls_Time_TH ;;带进位 高位相加
MOV Temp3,A
MOV A,Temp4
ADDC A,Temp5
MOV Temp4,A
Zero_Bit: ;;移位出来的数为零则从这里开始. 将被乘数左移一位
CLR C ;乘数除以2,被乘数乘以2
MOV A,Puls_Time_TL
RLC A
MOV Puls_Time_TL,A
MOV A,Puls_Time_TH
RLC A
MOV Puls_Time_TH,A
MOV A,Temp5
RLC A
MOV Temp5,A
DJNZ R7,Re_Mul34
;---------------------------------------------------------------
;USE Data Temp4(H)Temp3(M)Temp2(L)(100US*DM)/2000(0x4E20)=XX(DECimeter)
;---------------------------------------------------------------
;除法部分
;入口: Temp4,Temp3,Temp2(被除数)
;出口: Data_Buf(最后的商)
;使用: Temp1(暂存商),Temp5(暂存余数),A,B,R7
;功能:
; (Temp1)
; ---------------------
; 2000 |(Temp4)(Temp3)(Temp2)
;减法代替除法实现运算
MOV R7,#9 ;共8次
MOV Temp1,#0;保存商数
Re_Div_2000:
MOV A,Temp3 ;从高两位开始减被除数(相当于被除数已经被除了8次2)
CLR C
SUBB A,#0D0h ;(Temp4)(Temp3)-0x7D0 (即减2000)
;; SUBB A,#0C8h
MOV Temp5,A ;暂存余数
MOV A,Temp4
SUBB A,#07H
;; SUBB A,#0
JC Subb_Carried
Subb_No_Carried:
INC Temp1 ;没有借位,商数加一;余数存入Temp3,Temp4
MOV Temp4,A
MOV Temp3,Temp5
AJMP Re_Div_2000
Subb_Carried: ;Round4_5
DJNZ R7,Div_2000_Not_Over
CLR C ;除法结束,再做四舍五入,减2000不够,试减1000,以做四舍五入
MOV A,Temp1
CLR C
SUBB A,#3
JC Not_Correct_Dis
MOV Temp1,A ;误差校正
Not_Correct_Dis:
MOV Two_Digital_Dis,Temp1
MOV A,Temp1
MOV B,#10
DIV AB
MOV Data_Buf,A
CJNE A,#3,If_Round45 ;小于0.3M,不再做四舍五入
If_Round45:
JC Not_Round45
MOV A,B
CLR C
SUBB A,#5
JC Not_Round_UP_10CM
INC Data_Buf
Not_Round45:
Not_Round_UP_10CM:
AJMP Div_Over
Div_2000_Not_Over:
CLR C ;被除数乘以2,商数乘以2
MOV A,Temp2
RLC A
MOV Temp2,A
MOV A,Temp3
RLC A
MOV Temp3,A
MOV A,Temp4
RLC A
MOV Temp4,A
CLR C
MOV A,Temp1
RLC A
MOV Temp1,A
AJMP Re_Div_2000
Div_Over:
RET
;============================================
;================================================盲点更新程序==============================================
ScotTimeUpdate:
MOV A,Temp1 ;盲点时间介于1500us-1765us之间
CLR C
SUBB A,#0DCH ;盲点时间是否大于1500us
MOV A,Temp2
SUBB A,#05H
JC NoUpdate ;小于1500us,不需要更新
MOV A,Temp1
CLR C
SUBB A,#0E5H ;盲点时间是否小于1765us
MOV A,Temp2
SUBB A,#06H
JNC NoUpdate ;大于1765us,不需要更新
Update:
MOV Scot_Time_L,Temp1
MOV Scot_Time_H,Temp2
NoUpdate:
RET
;============================================
/*
;=========================================本次距离值与上次比较=============================================
;若距离之差大于18(1.8m),则视为干扰,抛弃新值,保留原值。
;比较方法:用加法代替减法,差值求补码再与18相加,若溢出则差大于18。
DstCompWithLastTime:
MOV A,Data_Buf
CLR C
SUBB A,Temp3
JC Comp_Difference ;差为负值,直接是补码表示
CPL A ;差为正值,转换为补码
ADD A,#1
Comp_Difference:
CLR C
ADD A,#05H
JC Comp_Over
MOV Data_Buf,Temp3
Comp_Over:
RET
;============================================
*/
;============================================无线数据发送程序==============================================
RF_SEND:
MOV B,#10
MOV A,Min_Distance
MUL AB
ADD A,#2 ;修正舍去低两位产生的误差
ANL A,#11111100B ;低两位存放探头位置号
ADD A,Min_Channel_num
MOV Data_min,A
CPL A
INC A
MOV Data_Cpl,A ;;补码计算,接收端和校验
DATA_SEND: ;;送至高频的数据
CALL PrePulse_Send ;预发送几个脉冲,启动高频模块
CALL Send_head ;;数据头
MOV Send_data,IDH
CALL Send
MOV Send_data,IDL
CALL Send ;;两个ID码
MOV Send_data,Data_min
CALL Send
MOV Send_data,Data_Cpl
CALL Send ;;数据和它的补码
CALL Send_head ;;数据头
MOV Send_data,IDH
CALL Send
MOV Send_data,IDL
CALL Send ;;两个ID码
MOV Send_data,Data_min
CALL Send
MOV Send_data,Data_Cpl
CALL Send ;;数据和它的补码
RET
;;===========================================
;==================================================喂狗程序================================================
;***********************
WDFeed:
CLR EA ;关中断
MOV WFEED1,#0A5H ;执行清零序列第一部分
MOV WFEED2,#5AH ;执行清零序列第二部分
SETB EA ;开中断
RET
;***********************
;;===============================================数据位发送程序============================================
PrePulse_Send:
; SETB WR_Bit
CALL DELAY_200US
CLR WR_Bit
CALL DELAY_200US
SETB WR_Bit
CALL DELAY_200US
CLR WR_Bit
CALL DELAY_200US
SETB WR_Bit
CALL DELAY_200US
CLR WR_Bit
CALL DELAY_200US ;;数据头之前发送三个脉冲
RET
Send_Head:
SETB WR_Bit ;发送数据头,四毫秒的高电平
CLR Time60ms
MOV TL0,#T4msL
MOV TH0,#T4msH
SETB TR0 ;;设置5毫秒的定时器
Wait_Head_Send:
JNB Time60ms,Wait_Head_Send
CLR Time60ms ;;延时5毫秒
CLR WR_Bit
CALL DELAY_200US ;;发完数据头后置低
CALL WDFeed
RET
;----------四个字节子程序---------
/*
;150us高电平450us低电平为"0",450us高电平150us低电平为"1"
Send: ;;发送数据
MOV R6,#8
MOV A,Send_data
SendH_150:
SETB WR_Bit ;先发150US高电平
CALL DELAY_150US
RLC A
JC Send_H
Send_L: ;;为“0”则发300US低电平
CLR WR_Bit
CALL DELAY_150US
CALL DELAY_150US
AJMP SendL_150
Send_H: ;;为“1”则发300US高电平
CALL DELAY_150US
CALL DELAY_150US
SendL_150:
CLR WR_Bit
CALL DELAY_150US ;再发150US低电平
DJNZ R6,SendH_150
RET
Send: ;;发送数据
MOV R6,#8
MOV A,Send_data
Send_START:
RLC A
JC Send_H
Send_L: ;;200us高电平400us低电平为"0"
SETB WR_Bit
CALL DELAY_200US
CLR WR_Bit
CALL DELAY_200US
CALL DELAY_200US
AJMP Send_OVER
Send_H: ;;400us高电平200us低电平为"1"
SETB WR_Bit
CALL DELAY_200US
CALL DELAY_200US
CLR WR_Bit
CALL DELAY_200US
Send_OVER:
DJNZ R6,Send_START
RET
*/
;发送400US高800US低为“0”,800US高400US低为“1”。
Send: ;;发送数据
MOV R6,#8
MOV A,Send_data
SendH_400:
SETB WR_Bit ;先发400US高电平
CALL DELAY_400US
RLC A
JC Send_H
Send_L: ;;为“0”则发400US低电平
CLR WR_Bit
CALL DELAY_400US
AJMP SendL_400
Send_H: ;;为“1”则发400US高电平
CALL DELAY_400US
SendL_400:
CLR WR_Bit
CALL DELAY_400US ;再发400US低电平
DJNZ R6,SendH_400
RET
;;-------------延时150微秒----------------
DELAY_150US:
MOV R7,#30H ;;8M四分频 ;1 cycle
DELAY_150:
NOP ;1 cycle
DJNZ R7,DELAY_150 ;2 cycle
RET ;2 cycle
;;-------------延时200微秒----------------
DELAY_200US:
MOV R7,#40H ;;8M四分频 ;1 cycle
DELAY_200:
NOP ;1 cycle
DJNZ R7,DELAY_200 ;2 cycle
RET ;2 cycle
;;-------------延时400微秒----------------
DELAY_400US:
MOV R7,#84H ;;8M四分频 ;1 cycle
DELAY_400:
NOP ;1 cycle
DJNZ R7,DELAY_200 ;2 cycle
RET ;2 cycle
;=================数据位发送结束===============
;==============================================中断服务程序区==============================================
;Interrupt Program
;==============================================
Ex0_Int:
;---------------------------
Ex1_Int:
;---------------------------
Serial_Int:
;---------------------------
BrouwnOut_Detect:
;---------------------------
I2C_Int:
;---------------------------
KBI_Int:
;---------------------------
Cmp2_Int:
;---------------------------
WatchDog_Timer:
;---------------------------
Cmp1_Int:
RETI
;---------------------------
Timer0_Int:
PUSH ACC
PUSH PSW
SETB Time60ms
CLR TR0
; CPL WR_Bit
POP PSW
POP ACC
RETI
;---------------------------
Timer1_Int:
RETI
;---------------------------
;=================================================
;=================================================程序结束=================================================
;end of program
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -