利用51單片機做的超聲波測距仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
1.png (49.32 KB, 下載次數: 133)
下載附件
2019-4-28 13:04 上傳
單片機源程序如下:
- LCD_RS BIT P1.0 //LCD1602引腳定義
- LCD_RW BIT P1.1
- LCD_EN BIT P1.2
- LCD_DATA EQU P0 //數據并行口
-
- key1 BIT P1.3 //設置
- key2 BIT P1.4 //減1
- key3 BIT P1.5 //加1
- ECHO BIT P3.6 //回波信號端
- TRIG BIT P3.7 //觸發信號端
-
- LED BIT P2.0 //
- BEE BIT P2.1
- water_in BIT P2.2
- water_out BIT P2.3
- TIME_FULL BIT 20H
- START_FLAG BIT 21H
- TX EQU 40H //定時器用
- S_HH EQU 41H //距離上限高8位
- S_HL EQU 42H //距離上限低8位
- S_LH EQU 43H //距離下限高8位
- S_LL EQU 44H //距離下限低8位
- S_H EQU 45H //距離高8位
- S_L EQU 46H //距離低8位
-
- SET_FLAG EQU 47H //設置按鍵按下標志 1設置上限 2設置下限
- ORG 0000H
- LJMP MAIN
- ORG 000BH //定時器0入口
- LJMP TIME0
- ORG 001BH
- LJMP TIME1
- ORG 0030H
- MAIN:
- CLR TRIG
- CLR TIME_FULL
- MOV SP,#52H //預置堆棧地址
- MOV R0,#40H
- MOV A,#0
- CLR_ADD: //把40H-5FH的內容清零
- MOV @R0,A
- INC R0
- CJNE R0,#60H,CLR_ADD
-
- MOV S_HH,#1
- MOV S_HL,#00H ;上限=S_HH*256+S_HL
- MOV S_LH,#0
- MOV S_LL,#00H
-
- MOV S_H,#1
- MOV S_L,#0
- MOV SET_FLAG,#0
- CLR START_FLAG
- LCALL LCD1602_INIT //1602初始化
- LCALL DELAY2
-
- MOV A,#80H
- LCALL WRITE_1602COM
- MOV DPTR,#CODE_PRINT1
- LCALL PRINT //格式:"Now S: "
-
- MOV A,#0C0H
- LCALL WRITE_1602COM
- MOV DPTR,#CODE_PRINT2
- LCALL PRINT //格式:"Set H L "
-
-
- MOV TMOD,#11H //初始化定時器
- MOV TH0,#0; //用于檢測超時
- MOV TL0,#0;
- MOV TH1,#(65536-50000)/256 //50MS 觸發
- MOV TL1,#(65536-50000)MOD 256
- SETB EA
- SETB ET0
- SETB ET1 //開啟中斷
- SETB TR1
- LCALL DISPLAY1
-
-
-
- //主循環
- LOOP:
- LCALL KEYBOARD //調用按鍵
-
- MOV A,#0
- CJNE A,SET_FLAG,LOOP1
- SETB TR1
- LOOP7:
- JB ECHO,LOOP2
- SETB START_FLAG
- SJMP LOOP7
- LOOP2:
- JNB START_FLAG,LOOP3 //為0表示不正常的值 不更新
- CLR START_FLAG
- SETB TR0
- LOOP6:
- JNB ECHO,LOOP4
- JB TIME_FULL,LOOP5 //超出范圍
- SJMP LOOP6
- LOOP4:
- CLR TR0
- LCALL COUNT
- LCALL DISPLAY2 //顯示距離
- LCALL FUNTION //判斷范圍
- SJMP LOOP3
- LOOP5:
- CLR TIME_FULL
- CLR TR0
- MOV TH0,#0;
- MOV TL0,#0;
-
- MOV A,#89H
- LCALL WRITE_1602COM
- MOV DPTR,#CODE_PRINT3
- LCALL PRINT //格式:"Err"
- CLR LED
- CLR BEE //超時 僅報警
- LOOP3:
-
-
- SJMP LOOP
- LOOP1:
- CLR TR1 //按鍵設置的時候禁止測量
- CLR TR0
- LCALL DISPLAY1 //有按鍵時在屏幕上更新上下限的值
- LJMP LOOP
-
-
- FUNTION:
- CLR C
- MOV A,S_H //實際值減去下限
- SUBB A,S_LH
- MOV B,A
- JNC FUN0 //為0跳轉繼續判斷 為1說明低于下限
- FUN1:
- CLR water_in //注水 開燈 報警
- CLR LED
- CLR BEE
- SJMP FUN
- FUN0:
- MOV A,S_L
- SUBB A,S_LL
- JNC FUN2 //低8位是否有借位
- MOV A,B
- CJNE A,#1,FUN1 //有借位B為1說明測量值大于下限 判斷上限
- FUN2: //實際值和上限相比較
- CLR C
- MOV A,S_HH
- SUBB A,S_H
- MOV B,A
- JNC FUN3
- FUN4:
- CLR water_out
- CLR LED
- CLR BEE
- SJMP FUN
- FUN3:
- MOV A,S_HL
- SUBB A,S_L
- JNC FUN5 //
- MOV A,B
- CJNE A,#1,FUN4
- FUN5:
- SETB water_in
- SETB water_out
- SETB LED
- SETB BEE
- FUN:
- RET
-
- COUNT: //計算距離 cm=us/58
- MOV R1,TH0
- MOV R0,TL0
- MOV S_L,#0
- MOV S_H,#0
- MOV TH0,#0
- MOV TL0,#0
- _D1:
- CLR C //循環被除數減去除數的次數就是這個商
- MOV A, R0
- SUBB A, #3AH
- MOV R0, A
- MOV A, R1
- SUBB A, #0
- MOV R1, A
- JC _D2
- INC S_L
- MOV A,S_L
- CJNE A,#0,_D1
- INC S_H
- SJMP _D1
- _D2:
- RET
- //顯示數字函數
-
- DISPLAY1:
- //顯示上下限
- MOV A,#0C5H
- LCALL WRITE_1602COM
- MOV A,#' '
- LCALL WRITE_1602DAT
-
- MOV A,SET_FLAG
- CJNE A,#1,DIS1
- MOV A,#0C5H
- LCALL WRITE_1602COM
- MOV A,#'*'
- LCALL WRITE_1602DAT
- SJMP DIS2
- DIS1:
- CJNE A,#2,DIS2
- MOV A,#0CBH
- LCALL WRITE_1602COM
- MOV A,#'*'
- LCALL WRITE_1602DAT
- DIS2:
- MOV R6,S_HH
- MOV R7,S_HL
- LCALL HB2 //2字節16進制數轉換為3字節壓縮BCD碼
- MOV A,#0C6H
- MOV B,R4
- LCALL DIS_1WEI
- MOV A,R5
- LCALL DIS_2WEI
-
-
- MOV R6,S_LH
- MOV R7,S_LL
- LCALL HB2 //2字節16進制數轉換為3字節壓縮BCD碼
- MOV A,#0CCH
- MOV B,R4
- LCALL DIS_1WEI
- MOV A,R5
- LCALL DIS_2WEI
- RET
- DISPLAY2:
- //顯示距離
- MOV R6,S_H
- MOV R7,S_L
- LCALL HB2 //2字節16進制數轉換為3字節壓縮BCD碼
- MOV A,#089H
- MOV B,R4
- LCALL DIS_1WEI
- MOV A,R5
- LCALL DIS_2WEI
- RET
-
- //按鍵函數
- KEYBOARD:
- JB KEY1,K06 //設置
- LCALL DELAY2
- JB KEY1,K06
- INC SET_FLAG
- MOV A,SET_FLAG
- CJNE A,#3,K07 //為3退出設置狀態
- MOV SET_FLAG,#0
-
- MOV A,#0CBH
- LCALL WRITE_1602COM
- MOV A,#' ' //把*號去掉
- LCALL WRITE_1602DAT
- K07:
- JNB KEY1,$
- LJMP K00
- K06:
- MOV A,SET_FLAG
- CJNE A,#0,K060
- SJMP K00
- K060:
- JB KEY2,K04 //加
- LCALL DELAY2
- JB KEY2,K04
- CJNE A,#1,K061 //按下設置鍵第一次上限 第二次下限
- INC S_HL //上限加 不能高于500即可
- MOV A,S_HL
- CJNE A,#0F5H,K063 //最大值為1F4(500),所以得先判斷是否到最大值
- MOV A,S_HH
- CJNE A,#1,K063 //不相等表示沒到500 繼續設置
- DEC S_HL
- SJMP K05
- K063:
- MOV A,S_HL
- CJNE A,#0,K05
- INC S_HH //進位
- SJMP K05
- K061:
- MOV A,S_LL //下限加 不能高于上限且判斷進位
- CJNE A,S_HL,K062
- MOV A,S_LH
- CJNE A,S_HH,K062 //下限不能超過上限 可以相等
- SJMP K05
- K062:
- INC S_LL
- MOV A,S_LL
- CJNE A,#0,K05
- INC S_LH
- K05:
- JNB KEY2,$
- SJMP K00
- K04:
- JB KEY3,K00
- LCALL DELAY1
- JB KEY3,K00
- MOV A,SET_FLAG
- CJNE A,#1,K040
- MOV A,S_HL //上限減 不能低于下限 且還得判斷借位
- CJNE A,S_LL,K041 //相等再判斷高8位 不相等直接減
- MOV A,S_HH
- CJNE A,S_LH,K041 //相等不做任何操作 ,不相等直接減
- K042:
- JNB KEY3,$
- SJMP K00
- K041:
- DEC S_HL
- MOV A,S_HL
- CJNE A,#255,K042 //判斷是否借位 否直接退出
- DEC S_HH
- SJMP K042
- K040: //下限減
- MOV A,S_LL
- CJNE A,#0,K043
- MOV A,S_LH
- CJNE A,#0,K043
- SJMP K042 //下限為0不做任何操作
- K043:
- DEC S_LL
- MOV A,S_LL
- CJNE A,#255,K042 //判斷是否有借位
- DEC S_LH
- SJMP K042
- K00:
- RET
-
-
- //LCD1602初始化函數
- LCD1602_INIT:
- MOV A,#38H
- LCALL WRITE_1602COM
- MOV A,#0CH
- LCALL WRITE_1602COM
- MOV A,#06H
- LCALL WRITE_1602COM
- MOV A,#01H
- LCALL WRITE_1602COM
- RET
-
- WRITE_1602COM: //寫命令
- CLR LCD_RS
- CLR LCD_RW
- MOV P0,A
- LCALL DELAY1
- SETB LCD_EN
- LCALL DELAY1
- CLR LCD_EN
- RET
- WRITE_1602DAT: //寫數據
- SETB LCD_RS
- CLR LCD_RW
- MOV P0,A
- LCALL DELAY1
- SETB LCD_EN
- LCALL DELAY1
- CLR LCD_EN
- RET
-
-
- //1602顯示字符串函數
- PRINT:
- MOV R0,#0
- PRINT01:
- MOV A,R0
- MOVC A,@A+DPTR
- CJNE A,#0,PRINT00
- RET
- PRINT00:
- LCALL WRITE_1602DAT
- INC R0
- SJMP PRINT01
-
- //1602顯示3位整數
- DIS_3WEI:
- MOV R0,A
- MOV B,#100
- DIV AB
- CJNE A,#0,W1
- MOV A,#' '
- SJMP W2
- W1:
- ADD A,#30H
- W2:
- LCALL WRITE_1602DAT
- MOV A,B
- MOV B,#10
- DIV AB
- CJNE A,#0,W3
- CJNE R0,#100,W5
- SJMP W3
- W5:
- MOV A,#' '
- SJMP W4
- W3:
- ADD A,#30H
- W4:
- LCALL WRITE_1602DAT
- MOV A,B
- ADD A,#30H
- LCALL WRITE_1602DAT
- RET
-
- //1602顯示2位整數
- DIS_2WEI:
- MOV B,#16
- DIV AB
- ADD A,#30H
- LCALL WRITE_1602DAT
- MOV A,B
- ADD A,#30H
- LCALL WRITE_1602DAT
- RET
-
- //1602顯示1位整數
- DIS_1WEI: ;A是地址 B放數據
- LCALL WRITE_1602COM
- MOV A,B
- ADD A,#30H
- LCALL WRITE_1602DAT
- RET
-
- DELAY1: ;延時1
- MOV 30H,#20
- DJNZ 30H,$
- RET
-
- DELAY2: ;延時2
- MOV 30H,#50
- DELAY20:
- MOV 31H,#50
- DJNZ 31H,$
- DJNZ 30H,DELAY20
- RET
-
- ;//定時器0中斷函數
- TIME0:
- PUSH PSW
- PUSH ACC
-
- SETB TIME_FULL
- POP ACC
- POP PSW
- RETI
-
-
- TIME1:
- PUSH PSW
- PUSH ACC
- MOV TH1,#(65536-50000)/256; //50MS
- MOV TL1,#(65536-50000)MOD 256;
- INC TX
- MOV A,TX
- CJNE A,#8,TIME10 //400MS測量一次
- MOV TX,#0
- SETB TRIG
- LCALL DELAY1
- CLR TRIG
- TIME10:
- POP ACC
- POP PSW
- RETI
-
- ; 功能:雙字節十六進制整數轉換成雙字節BCD碼整數
- ; 入口條件:待轉換的雙字節十六進制整數在R6、R7中。
- ; 出口信息:轉換后的三字節BCD碼整數在R3、R4、R5中。
- HB2:
- CLR A ;BCD碼初始化
- MOV R3,A
- MOV R4,A
- MOV R5,A
- MOV R2,#10H ;轉換雙字節十六進制整數
- HB3:
- MOV A,R7 ;從高端移出待轉換數的一位到CY中
- RLC A
- MOV R7,A
- MOV A,R6
- RLC A
- MOV R6,A
- MOV A,R5 ;BCD碼帶進位自身相加,相當于乘2
- ADDC A,R5
- DA A ;十進制調整
- MOV R5,A
- MOV A,R4
- ADDC A,R4
- DA A
- MOV R4,A
- MOV A,R3
- ADDC A,R3
- MOV R3,A ;雙字節十六進制數的萬位數不超過6,不用調整
- DJNZ R2,HB3 ;處理完16bit
- RET
-
- CODE_PRINT1:
- DB " Now S: cm",0
- CODE_PRINT2:
- DB "Set H L ",0
- CODE_PRINT3:
- DB "Err",0
- END
復制代碼
0.png (2.89 KB, 下載次數: 116)
下載附件
2019-4-28 13:04 上傳
仿真如上圖所示,有需要歡迎下載。全部資料51hei下載地址:
仿真.zip
(24.09 KB, 下載次數: 112)
2019-4-28 08:42 上傳
點擊文件名下載附件
仿真文件 下載積分: 黑幣 -5
51超聲波測距 匯編語言.zip
(37.92 KB, 下載次數: 92)
2019-4-28 08:45 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|