『壹』 跪求一個 用stc12c系列 pca發送40khz 單片機 定時捕捉回波 的超聲波測距 c語言程序
超聲波的話我用的是X寶上的潮汕波模塊,這里我寫了一個超聲波的頭文件 我傳給你好了,還有頭文件上說明,應該能看懂的
傳不來 文件 直接發給你好了。
/*
頭文件說明:
本頭文件有三個可以調用的函數
1.串口的初始化函數 UESC_UART_Init(uint band)
1)參數是設定的波特率,晶振是12MHz,建議設置為2400.
2)注意初始化後要簡短延時。
2. UESC_UART_Putchar(char kkk)
該函數可以向上位機發送一個位元組的數據,參數就是要發送的數據。
本函數是用到了中斷,這樣程序在接收數據的時候可以運行其他程序。
單片機通過串口接收到數據之後將8位的數據放在 date 的外部變數中,所以在主函數里可以直接操作接收來的變數;
接收到數據後同時會將外部變數flag置位,以適應不同的應用場合。
注意: 使用到串口是 定時器1不能使用。
發送單個字元的時候記得加 『』 將字元括起來。
記得將flag置一;
第二次修改的內容:
給初始化函數加了晶振的選擇,傳遞的參數就是晶振的頻率 12M的晶振就傳遞12
注意:該函數在12M 24M 24.576M測試搜通過。 但是11.0592死活不成功,不要問為什麼,搞得好像我知道似的!
建議在調用之前建議先測試一下該晶振頻率能否通過。
第二次修改的內容:
解決了部分晶振頻率串口通信失敗的問題,現在所有的晶振均測試通過。
同時加了字元串輸出函數:UART_PutString(char *s) 參數就是要顯示的字元串,記得用「」。
作者@Jack_kk
完成日期:2014_4_14
第一次修改時間:2014_5_13
第二次修改時間:2014_5_18
第三次修改時間:2014_5_19
*/
#include<reg51.h>
#include<stdio.h>
#include"UART.h"
char get_char;
bit flag;
unsigned char date;
void UESC_UART_Init(uint band,double MHz)
{
TMOD|=0x20;
TH1=256-(double)(MHz*2604)/band;
TL1=TH1;
SM0=0; //和下面的一條語句同時設定串口工作方式
SM1=1;
REN=1; //允許串口接收
EA=1; //總中斷
TR1=1; //定時器開始
ES=1; //開串口中斷
}
void UESC_UART_Putchar(char kkk)
{
ES=0;
SBUF=kkk;
while(!TI);
TI=0;
ES=1;
}
void UART_PutString(char *s)
{
while(*s)
{
UESC_UART_Putchar(*s++);
}
}
/*
void UESC_UART_Getchar(void) //這個部分注釋掉是因為 沒有用到中斷。
{
ES=0; //發送數據之前把串口關閉
// TI=1; //這里是發送一個字元串printf的用法,先關閉窗口中斷,然後TI 好就是這樣、
// puts(" Please input a letter");
// TI=0;
while(!RI);
RI=0;
get_char=SBUF;
// TI=1;
// printf("The letter you just input is ");
// TI=0;
SBUF=get_char;
while(!TI);
TI=0;
ES=1;
}
*/
錯了,那是串口頭文件 sorry
/*
********************頭文件說明**********************
本頭文件適用於HC-HR04超聲波模塊
經封裝本頭文件可以直接調用的函數是:
1.Ultrasound_Init();
初始化定時器0;
2.Get_time();
取得距離函數,返回值是距離,單位厘米,聲速是240m/s時的測量結果。
示例:
Ultrasound_Init();
while(1)
{
dis=Get_time();
display(dis);
}
注意:
1.本頭文件佔用了定時器0,在主函數裡面就不要在使用定時器0了;
2.調用本頭文件之前記得修改IO口;
3.測量周期建議在60ms以上。
作者@Jack_kk
時間:2014_5_14
*/
#include"Ultrasound.h"
#include<intrins.h>
#include<reg51.h>
sbit Echo=P3^2;
sbit Trig=P1^0;
void Delay15us() //@12.000MHz
{
unsigned char i;
i = 42;
while (--i);
}
void Ultrasound_Init()
{
TMOD|=0x09;
TH0=TL0=0;
ET0=1;
TR0=1;
EA=1;
}
unsigned int Get_dis()
{
int timeout=20000;
Trig=1;
Delay15us();
Trig=0;
while(!Echo&timeout)
timeout--;
timeout=20000;
while(Echo&timeout)
timeout--;
timeout=TH0*256+TL0; //這里偷了一點懶,將變數防死機變數timeout作為了返回值
TH0=TL0=0;
return timeout*0.024;
}
『貳』 誰有超聲波探頭的程序麻煩發一下
我這是單片機控制超聲波探頭的匯編源程序,已驗證可以
中斷入口程序 *
;********************************************
;
ORG 0000H
LJMP START
ORG 0003H
LJMP PINT0
ORG 000BH
LJMP INTT0
ORG 0013H
RETI
ORG 001BH
LJMP INTT1
ORG 0023H
RETI
ORG 002BH
RETI
;
;********************************************
;* 主 程 序 *
;********************************************
;
START: MOV SP,#4FH
MOV R0,#40H
MOV R7,#0BH
CLEARDISP: MOV @R0,#00H
INC R0
DJNZ R7,CLEARDISP
MOV 20H,#00H
MOV TMOD,#21H ;T1為8位自動重裝模式,T0為16位定時器
MOV TH0,#00H ;65毫秒初值
MOV TL0,#00H
MOV TH1,#0F2H ;40KHZ初值
MOV TL1,#0F2H
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
MOV R4,#04H ;超聲波肪沖個數控制(為賦值的一半)
SETB PX0
SETB ET0
SETB EA
SETB TR0 ;開啟測距定時器
start1: LCALL DISPLAY
JNB 00H,START1 ;收到反射信號時標志位為1
CLR EA
LCALL WORK ;計算距離子程序
SETB EA
CLR 00H
SETB TR0 ;重新開啟測距定時器
MOV R2,#64H ;測量間隔控制(約4*100=400MS)
LOOP: LCALL DISPLAY
DJNZ R2,LOOP
SJMP Start1
;
;****************************************************
;* 中斷程序* *
;****************************************************
;T0中斷,65毫秒中斷一次
INTT0: CLR EA
CLR TR0
MOV TH0,#00H
MOV TL0,#00H
SETB ET1
SETB EA
SETB TR0 ;啟動計數器T0,用以計算超聲來回時間
SETB TR1 ;開啟發超聲波用定時器T1
OUT: RETI
;T1中斷,發超聲波用
INTT1: CPL VOUT
DJNZ R4,RETIOUT
CLR TR1 ;超聲波發送完畢,關T1
CLR ET1 ;
MOV R4,#04H
SETB EX0 ;開啟接收回波中斷
RETIOUT: RETI
;外中斷0,收到回波時進入
PINT0: CLR TR0 ;關計數器
CLR TR1
CLR ET1
CLR EA ;
CLR EX0 ;
MOV 44H,TL0 ;將計數值移入處理單元
MOV 45H,TH0 ;
SETB 00H ;接收成功標志
RETI
;
;****************************************************
;* 顯示程序 *
;****************************************************
; 40H為最高位,43H為最低位,先掃描高位
DISPLAY: MOV R1,#40H;G
MOV R5,#0F7H;G
PLAY: MOV A,R5
MOV P0,#0FFH
MOV P2,A
MOV A,@R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P0,A
LCALL DL1MS
INC R1
MOV A,R5
JNB ACC.0,ENDOUT;G
RR A
MOV R5,A
AJMP PLAY
ENDOUT: MOV P2,#0FFH
MOV P0,#0FFH
RET
;
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH
;共陽段碼表 "0" "1" "2" "3" "4" "5""6" "7" "8" "9" "不亮""A""-"
;
;****************************************************
;* 延時程序 *
;****************************************************
;
DL1MS: MOV R6,#14H
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;
;****************************************************
;* 距離計算程序 (=計數值*17/1000cm) *
;****************************************************
;
work: PUSH ACC
PUSH PSW
PUSH B
MOV PSW, #18h
MOV R3, 45H
MOV R2, 44H
MOV R1, #00D
MOV R0, #17D
LCALL MUL2BY2
MOV R3, #03H
MOV R2, #0E8H
LCALL DIV4BY2
LCALL DIV4BY2
MOV 40H, R4
MOV A,40H
JNZ JJ0
MOV 43H,#0AH
JJ0: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #100D
LCALL DIV4BY2
MOV 42H, R4
MOV A,42H
JNZ JJ1
MOV A,40H
SUBB A,#0AH
JNZ JJ1
MOV 42H,#0AH
JJ1: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #10D
LCALL DIV4BY2
MOV 41H, R4
MOV A,41H
JNZ JJ2
MOV A,42H
SUBB A,#0AH
JNZ JJ2
MOV 41H,#0AH
JJ2: MOV 40H, R0
POP B
POP PSW
POP ACC
RET
;
;****************************************************
;* 兩位元組無符號數乘法程序 *
;****************************************************
; R7R6R5R4 <= R3R2 * R1R0
;
MUL2BY2: CLR A
MOV R7, A
MOV R6, A
MOV R5, A
MOV R4, A
MOV 46H, #10H
MULLOOP1: CLR C
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
JNC MULLOOP2
MOV A, R4
ADD A, R2
MOV R4, A
MOV A, R5
ADDC A, R3
MOV R5, A
MOV A, R6
ADDC A, #00H
MOV R6, A
MOV A, R7
ADDC A, #00H
MOV R7, A
MULLOOP2: DJNZ 46H, MULLOOP1
RET
;
;****************************************************
;* 四位元組/兩位元組無符號數除法程序 *
;****************************************************
;R7R6R5R4/R3R2=R7R6R5R4(商)...R1R0(余數)
;
DIV4BY2: MOV 46H, #20H
MOV R0, #00H
MOV R1, #00H
DIVLOOP1: MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
CLR C
MOV A, R0
SUBB A, R2
MOV B, A
MOV A, R1
SUBB A, R3
JC DIVLOOP2
MOV R0, B
MOV R1, A
DIVLOOP2: CPL C
DJNZ 46H, DIVLOOP1
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
RET
;
END
『叄』 超聲波測距程序
以下是用匯編語言編寫的超聲波測距控制源程序:採用AT89S51 12MHz晶振 顯示緩沖單元在40H~43H,使用內存44H、45H、46H用於計算距離
20H用於標志
VOUT EQU P1.0 ;脈沖輸出埠
*中斷入口程序*
ORG 0000H
LJMP START
ORG 0003H
LJMP PINT0
ORG 000BH
LJMP INTT0
ORG 0013H
RETI
ORG 001BH
LJMP INTT1
ORG 0023H
RETI
ORG 002BH
RETI
*主程序*
START: MOV SP, #4FH
MOV R0, #40H ;40~43H為顯示數據存放單元(40為最高位)
MOV R7,#0BH
CLEARDISP:MOV @R0, #00H
INC R0
DJNZ R7, CLEARDISP
MOV 20H, #00H
MOV TMOD, #21H ;T1為8位自動重裝模式,T0為16位定時器
MOV TH0, #00H ;65ms初值
MOV TL0, #00H ;40KHz初值
MOV TH1, #0F2H
MOV TL1, #0F2H
MOV P0, #0FFH
MOV P1, #0FFH
MOV P2, #0FFH
MOV P3, #0FFH
MOV R4, #04H ;超聲波脈沖個數控制(為賦值的一半)
SETB PX0
SETB ET0
STEB EA
CLR 00H
SETB TR0 ;開啟測距定時器
START1: LCALL DISPLAY
JNB 00H, START1 ;收到反射信號時標志位為1
CLR EA
LCALL WORK;計算距離子程序
SETB EA
CLR 00H
SETB TR0;重新開啟測距定時器
MOV R2, #64H ; 測量間隔控制(約4*100=400ms)
LOOP: LCALL DISPLAY
DJNZ R2, LOOP
SJMP START 1
*中斷程序*
;T0中斷,65ms中斷一次
INTT0: CLR EA
CLR TR0
MOV TH0, #00H
MOV TL0, #00H
SETB ET1
SETB EA
SETB TR0 ;啟動計時器T0,用以計算超聲波來回時間
SETB TR1 ;開啟發超聲波用定時器T1
OUT: RETI;T1中斷,發超聲波用
INTT1: CPL VOUT
DJNZ R4,RETIOUT
CLR TR1;超聲波發送完畢,關T1
CLR ET1
MOV R4,#04H
SETB EX0;開啟接收回波中斷
RETIOUT: RETI;外中斷0,收到回波時進入
PINT0: CLR TR0 ;關計數器
CLR TR1
CLR ET1
CLR EA
CLR EX0
MOV 44H, TL0;將計數值移入處理單元
MOV 45H, TH0
SETB 00H ;接收成功標志
RETI
*延時程序*
DL1MS: MOV R6, #14H
DL1: MOV R7, #19H
DL2: DJNZ R6, DL2
DJNZ R6, DL1
RET
*顯示程序*
;40H為最高位,43H為最低位,先掃描高位
DISPLAY: MOV R1, #40H;G
MOV R5,#0F7H;G
PLAY: MOV A, R5
MOV P0, #0FFH
MOV P2, A
MOV A, @R1
MOV DPTR, #TAB
MOVC A, @A+DPTR
MOV P0, A
LCALL DLIMS
INC R1
MOV A, R5
JNB ACC.0, ENDOUT;G
RR A
MOV R5, A
AJMP PLAY
ENDOUT: MOV P2, #0FFH
MOV P0, #0FFH
RET
TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH
;共陽數碼管 0 ,1, 2,3,4,5,6,7,8,9,不亮,A,
*距離計算程序(=計算值×17/1000cm) 近似
WORK: PUSH ACC
PUSH PSW
PUSH B
MOV PSW, #18H
MOV R3, 45H
MOV R2, 44H
MOV R1, #00D
MOV R0, #17D
LCALL MUL2BY2
MOV R3, #03H
MOV R2, #0E8H
LCALL DIV4BY2
LCALL DIV4BY2
MOV 40H, R4
MOV A, 40H
JNZ JJ0
MOV40H,#0AH ;最高位為0,不點亮
JJ0: MOV A R0
MOV R4, A
MOV A R1
MOV R5,A
MOV R3, #00D
MOV R2, #100D
LCALL DIV4BY2
MOV 41H, R4
MOV A, 41H
JNZ JJ1
MOV A, 40H ;此高位為0,先看最高位是否為不亮
SUBB A, #0AH
JNZ JJ1
MOV 41H, #0AH ; 最高位不亮,次高位也不亮
JJ1: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #10D
LCALL DIV4BY2
MOV 42H, R4
MOV A 42H
JNZ JJ2
MOV A,41H ;次高位為0,先看次高位是否為不亮
SUBB A, #0AH
JNZ JJ2
MOV 42H, #0AH ;次高位不亮,次高位也不亮
JJ2: MOV 43H, R0
POP B
POP PSW
POP ACC
RET
*兩位元組無符號數乘法程序
MUL2BY2: CLR A
MOV R7, A
MOV R6, A
MOV R5, A
MOV R4, A
MOV 46H, #10H
MULLOOP1: CLR C
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
JNC MULLOOP2
MOV A, R4
ADD A, R2
MOV R4, A
MOV A, R5
ADDC A, R3
MOV R5, A
MOV A, R6
ADDC A, #00H
MOV R6, A
MOV A, R7
ADDC A, #00H
MOV R7, A
MULLOOP2: DJNZ 46H, MULLOOP1
RET
*四位元組/兩位元組無符號數除法程序*
DIV4BY2: MOV 46H, #20H
MOV R0, #00H
MOV R1, #00H
DIVLOOP1: MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
CLR C
MOV A, R0
SUBB A, R2
MOV B, A
MOV A, R1
SUBB A, R3
JC DIVLOOP2
MOV R0, B
MOV R1, A
DIVLOOP2: CPL C
DJNZ 46H, DIVLOOP1
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
RET
END
『肆』 51單片機超聲波測距代碼
1602液晶顯示 的超聲波模塊程序
介面程序里邊都有、、
#include
//#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^3;
sbit lcden=P2^2;
sbit trig=P2^0; //超聲波發送
//sbit echo=P3^2; //超聲波接受
//P0____________DB0-DB7
uchar dis[]="Disp_HC-SR04";
uchar num[]="0123456789";
uint distance;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=121;y>0;y--);
}
void HC_init()
{
TMOD=0x09;
TR0=1;
TH0=0;TL0=0;
}
uint HC_jisuan()
{
uint dist,timer;
timer=TH0;
timer<<=8;
timer=timer|TL0;
dist=timer/53; //晶振11.0592MHz 距離cm=微秒us/58
return dist; //1個機器周期是12個時鍾周期 timer*12/(58*11.0592)=timer/53
}
void HC_run()
{
uint tempH=0x00,tempL=0x00;
TH0=0;TL0=0;
trig=0;
trig=1;
delay(1);
trig=0;
while((TH0-tempH!=0||TL0-tempL!=0)||(TH0==0&&TL0==0))
{
tempH=TH0;
tempL=TL0;
}
delay(1);
}
void lcd_write_com(uchar com) //LCD寫指令
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_write_data(uchar date) //LCD寫數據
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void lcd_init() //LCD初始化
{
lcden=0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
}
void lcd_display(uchar temp)
{
uint i;
lcd_write_com(0x82);
for(i=0;i<12;i++)
{
lcd_write_data(dis[i]);
}
lcd_write_com(0x80+0x41);
lcd_write_data('D');
lcd_write_data('i');
lcd_write_data('s');
lcd_write_data('t');
lcd_write_data('a');
lcd_write_data('n');
lcd_write_data('c');
lcd_write_data('e');
lcd_write_data(':');
lcd_write_data(num[temp/100]);
lcd_write_data(num[temp/10%10]);
lcd_write_data(num[temp%10]);
lcd_write_data('c');
lcd_write_data('m');
}
void main()
{
lcd_init();
HC_init();
while(1)
{
HC_run();
distance=HC_jisuan();
lcd_display(distance);
delay(200);
}
}