51单片机超声波测距源代码

合集下载

51单片机超声测距汇编

51单片机超声测距汇编

;***P1.0口发射,P1.2口接收,P0.0~P0.3与P0.4~P0.7分别接SN74LS47N解码器的A、B、C、D脚,再接到两位七段数码管;***************产生超声波发射所需的发射脉冲信号******************** 0RG 00HSTART:MOV A,#0FFH ;ACC=0FFHMOV P1,A ;P1.2将作为输出口,需要先写入“1”MOV TMOD,#02H ;设置Timer0工作在模式2下TIMER0_LOAD:MOV TH0,#0F4H ;往TH0中载入计数初始值MOV TL0,#0F4H ;往TL0中载入计数初始值RESEND_PULSE:MOV R2,#40 ;一个方波对应2个Timer延时,所以设为40SEND_PAUSE:SETB TR0 ;启动Timer0TIMER0_CHECK:JNB TF0,TIMER0_CHECK ;检测Timer溢出标志,当TF0=1,跳出CLR TR0 ;关闭Timer0CLR TF0 ;将TF0清零CPL P1.0 ;将TF0取反DJNZ R2,SEND_PULSE ;如果R2不为0,跳到SEND_PULSE继续;***************等待回波信号时的计时功能********************WAITECHO: ;等待回波信号MOV TMOD,#12H ;Timer1模式1,Timer0模式2 TIMER1_LOAD:MOV TL1,#00H ;载入最小的计数初始值,以获得最大计时MOV TH1,#00HSETB TR1 ;启动Timer1ECHO_CHECK:JB P1.2,RECORD ;检测回波信号,如果P1.2=1,回波到达JNB TF1,ECHO_CHECK ;如果回波还没有到达,Timer1继续计时CLR TR1 ;Timer1计时完成,关闭Timer1CLR TF1 ;清TF1JMP RESEND_PULSE ;跳回SEND_PULSE重新发射超声波RECORD:CLR TR1 ;已接收到回波,停止Timer1CLR TF1 ;清TF1MOV 30H,TL1 ;30H存储计时的低位字节MOV 31H,TH1 ;31H存储计时的高位字节MOV R0,#00H ;R0记录的是1米的倍数,清0 MOV R1,#00H ;R1记录的是1/10米的倍数,清0MOV SP,#50H ;定义堆栈初始地址为50HCLR C ;进位CY清0 METER: ;与一米的时间差16FAH进行比较PUSH 30H ;先将30H上的时间差低位压入堆栈MOV A,30H ;时间差低位载入ACCSUBB A,#0FAH ;时间差低位与1米对应的时间差低位FAH相减MOV 30H,A ;结果存回30HMOV A,31H ;时间差高位载入ACCSUBB A,#16H ;时间差高位与1米对应的时间差高位16H相减JC DECIMETER ;如果有借位,说明相减结果已经小于1米,则跳到DECIMETER与1/10米的时间差进行比较INC R0 ;如果没有借位,米数增加1 MOV 31H,A ;高位相减结果存回31H JMP METER ;继续与1米的时间差进行比较DECIMETER: ;与1/10米的时间差024CH进行比较POP 30H ;将堆栈中存储的时间差低位弹出到30HDECIMETER_1:MOV A,30H ;时间差低位载入ACC中SUBB A,#4CH ;时间差低位与1/10米对应的时间差低位4C相减MOV 30H,A ;结果存回30HMOV A,31H ;时间差高位载入ACCSUBB A,#02H ;时间差高位与1/10米的时间差高位02H相减JC DISPLAY ;如果有借位,说明相减结果已经小于1/10米,则时间差比较计算完成,跳到显示程序段INC R1 ;如果没有借位,1/10米数增加1MOV 31H,A ;高位相减结果存回31H JMP DECIMETER_1 ;继续与1/10米的时间差进行比较DISPLAY:MOV A,R0 ;1米的倍数载入ACCSWAP A ;ACC中高、低位互换ADD A,R1 ;ACC与R1相加,得到显示数据MOV P0,A ;显示数据从P0口输出JMP START ;循环END。

单片机课程设计超声波测距设计代码注释

单片机课程设计超声波测距设计代码注释

尊敬的读者:感谢您对本篇文章的关注和阅读。

在本篇文章中,我将为您介绍单片机课程设计中超声波测距设计代码的注释。

希望这些注释能够帮助您更好地理解超声波测距的原理和代码实现。

注释一:引入头文件```c#include <reg52.h>#include <intrins.h>```这里引入了reg52.h和intrins.h两个头文件,reg52.h是51单片机的特殊寄存器及位字段定义,intrins.h包含了一系列嵌入汇编的内置函数,用于单片机的延时等操作。

注释二:定义IO口```csbit Trig = P1^0;sbit Echo = P1^1;```Trig表示超声波发射端的控制引脚,Echo表示超声波接收端的输入引脚。

注释三:延时函数定义```cvoid DelayUs2x(unsigned char t){while (--t);}void DelayMs(unsigned char t){while(t--){DelayUs2x(245);DelayUs2x(245);}}```这里定义了微秒级和毫秒级的延时函数,用于超声波测距模块的操作时序控制。

注释四:超声波测距函数```cunsigned int distance() {unsigned int long ms; Trig = 0;_nop_();_nop_();Trig = 1;DelayUs2x(10);Trig = 0;while(!Echo);ms = 0;while(Echo){DelayUs2x(1);ms++;if(ms > 5000)return 0;}return ms;}```这段代码是超声波测距的核心算法,首先通过Trig引脚发送一个10us的高电平脉冲,然后在Echo引脚接收超声波回波,并计算回波的时间,最后将时间转换成距离值返回。

注释五:主函数```cvoid m本人n(){unsigned int dis;while(1){dis = distance();if(dis){dis = dis * 1.7 / 58;}DelayMs(500);}}```在主函数中,不断调用distance函数获取距离值,然后根据超声波的传播速度将时间转换成距离,并进行延时500ms后再次进行测距。

51单片机超声波测距

51单片机超声波测距

flag=0; TR0=0; TH0=0; TL0=0; IE0=0; }
//重置 flag 变量 //停止计数 //定时器重装初值(高八位) //定时器重装初值(低八位) //外中断 0 请求标志清零
Байду номын сангаас
void send() { fa=0;delay_3();_nop_();fa=1;delay_3(); fa=0;delay_3();_nop_();fa=1;delay_3(); fa=0;delay_3();_nop_();fa=1;delay_3(); TH0=0;TL0=0;//定时器装初值 TR0=1; //发送完后启动定时器 EX0=1; //外部中断允许位 IE0=0; //中断标志位清零 EA=1; //开启总中断 } void Display() { uint i; A[10]=Number[temp_B/1000]; A[11]=Number[temp_B/100%10]; A[12]=Number[temp_B%10]; write_cmd(0x90); for(i=0;i<16;i++) { write_dat(A[i]); } } void main() { init_time(); LCD_INIT(); while(1) { send(); // // // // // while(flag==0) { Display(); temp_C++; //当没执行中断时,flag=0,执行下面的语句
51 单片机超声波测距程序
#include<reg52.h> #include<intrins.h> #include"LCD12864Driver.h" #define unchar unsigned char #define unint unsigned int #define unlong unsigned long uchar A[]={"超声波测距 CM"}; uchar Number[]={"0123456789"}; sbit fa=P1^0; sbit di=P3^2; //位申明

51单片机超声波测距

51单片机超声波测距

//超声波模块显示程序#include <reg52.h> //包括一个52标准内核的头文件#define uchar unsigned char //定义一下方便使用#define uint unsigned int#define ulong unsigned longsbit Tx = P3^1; //产生脉冲引脚sbit Rx = P3^0; //回波引脚sbit dula=P2^6;sbit wela=P2^7;uchar code dispbit[]={ 0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f};//共阴极数码管显示位码uchar code SEG7[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};//数码管0-9 uint distance[4]; //测距接收缓冲区uchar ge,shi,bai,temp,outcomeH,outcomeL,i, dispcount; //自定义寄存器static unsigned char count=0;uint temp_data,distance_data;uchar dispbuf[4]; //显示缓冲区void delay_20us();//********函数声明//void conversion(uint temp_data);void display(){dula = 0;dula = 1;P0 = SEG7[dispbuf[dispcount]]; //根据dispcount当前计算值到dispbuf//显示缓冲存储区取待显示值作为参数到//SEG7段码存储区取显示段码赋给P0口dula = 0;wela = 0;wela = 1;P0 = dispbit[dispcount]; //根据dispcount当前计算值到dispbit位选存储区//取显示位码赋给P0口wela = 0;dispcount++;if(dispcount == 4) //共4位显示位{dispcount = 0;}count++;if(count == 100) //约25MS读取一次{count = 0;}}//void delay_20us();void main(void) // 主程序{Tx=0; //首先拉低脉冲输入引脚TMOD=0x01; //定时器0,定时器1,16位工作方式IT0=0; //由高电平变低电平,触发外部中断ET0=1; //打开定时器0中断// EX0=1; //关闭外部中断EA=1; //打开总中断TH0 =(65536-2500)/256; //约2.50MS定时器初值TL0 =(65536-2500)%256; //约2.50MS定时器初// EA=1;//Rx=1; //while(1) //程序循环{Tx=1;delay_20us(); //产生一个20us的脉冲,在Tx引脚Tx=0;TR0=1; //启动定时器0EX0=1; //打开外部中断//TF1=0; //}}//***************************************************************//外部中断0,用做判断回波电平INTO_() interrupt 0 // 外部中断是0号{TR0=0;// EX0=0; //关闭外部中断outcomeH =TH0; //取出定时器的值outcomeL =TL0; //取出定时器的值TH0 =(65536-2500)/256; //约2.50MS定时器初值TL0 =(65536-2500)%256; //约2.50MS定时器初值TH0 = 0xef; TL0 = 0x94; //写入定时器0初始值distance_data=outcomeH; //测量结果的高8位distance_data<<=8; //放入16位的高8位distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据// distance_data*=12; //因为定时器默认为12分频distance_data/=58;dispbuf[0] = distance_data / 1000; //千位dispbuf[1] = distance_data % 1000 / 100; //百位dispbuf[2] = distance_data % 100 / 10; //十位dispbuf[3] = distance_data % 10; //个位display();}//****************************************************************//定时器0中断,用做显示timer0() interrupt 1 // 定时器0中断是1号{TH0 =(65536-2500)/256; //约2.50MS定时器初值TL0 =(65536-2500)%256; //约2.50MS定时器初值TH0 = 0xef; TL0 = 0x94; //写入定时器0初始值dispbuf[0] = 10; //显示"-"dispbuf[1] = 10; //显示"-"dispbuf[2] = 10; //显示"-"dispbuf[3] = 10; //显示"-"display();}//******************************************************************void delay_20us(){ uchar bt ;for(bt=0;bt<60;bt++);}。

基于51单片机控制的超声波测距程序

基于51单片机控制的超声波测距程序
sj2=40;
s=sj2;
}
void k3cl()
{
sj3=sj3+10;
if(sj3> 500)
sj3=100;
sj1-1;
sx1=sx1/csbc;
mqs=sx1/4.5;
}
void offmsd()
{
if (buffer[0] == 0x3f)
buffer[0] = 0x00;
if((P3&0x10)==0)//判断3位是否显示完
key=0;
digit> > =1; //循环右移1位
}
}
void timeToBuffer() //转换段码功能模块
{
xm0=s/100;
xm1=(s-100*xm0)/10;
xm2=s-100*xm0-10*xm1;
buffer[2]=convert[xm2];
void delay(j);//延时函数
void scanLED();//显示函数
void timeToBuffer();//显示转换函数
void keyscan();
void k1cl();
void k2cl();
void k3cl();
void k4cl();
void offmsd();
void main()//主函数
}
{
csbds=0;
cl=1;
}
}
void csbcj()
{
if(cl==1)
{
TR1=0;
TH0=0x00;
TL0=0x00;
i=10;
while(i--)
{
csbout=!csbout;

(完整word版)用51单片机实现HC-SR04超声波测距程序(word文档良心出品)

(完整word版)用51单片机实现HC-SR04超声波测距程序(word文档良心出品)

#include <reg52.h> //包括一个52标准内核的头文件#define uchar unsigned char //定义一下方便使用#define uint unsigned int#define ulong unsigned longsbit Trig = P1^0; //产生脉冲引脚sbit Echo = P3^2; //回波引脚sbit test = P1^1; //测试用引脚uchar code SEG7[10]={~0xC0,~0xF9,~0xA4,~0xB0,~0x99,~0x92,~0x82,~0xF8,~0x80,~0x90};//数码管0-9uint distance[4]; //测距接收缓冲区uchar ge,shi,bai,temp,flag,outcomeH,outcomeL,i; //自定义寄存器bit succeed_flag; //测量成功标志//********函数声明void conversion(uint temp_data);void delay_20us();void main(void) // 主程序{uint distance_data,a,b;uchar CONT_1;i=0;flag=0;test =0;Trig=0; //首先拉低脉冲输入引脚TMOD=0x11; //定时器0,定时器1,16位工作方式TR0=1; //启动定时器0IT0=0; //由高电平变低电平,触发外部中断ET0=1; //打开定时器0中断EX0=0; //关闭外部中断EA=1; //打开总中断0while(1) //程序循环{EA=0;Trig=1;delay_20us();Trig=0; //产生一个20us的脉冲,在Trig引脚while(Echo==0); //等待Echo回波引脚变高电平succeed_flag=0; //清测量成功标志EX0=1; //打开外部中断TH1=0; //定时器1清零TL1=0; //定时器1清零TF1=0; //TR1=1; //启动定时器1EA=1;while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)TR1=0; //关闭定时器1EX0=0; //关闭外部中断if(succeed_flag==1){distance_data=outcomeH*256+outcomeL;distance_data= (distance_data*1.87)/100;} //为什么除以58等于厘米,Y米=(X 秒*344)/2// X秒=(2*Y米)/344 ==》X 秒=0.0058*Y米==》厘米=微秒/58if(succeed_flag==0){distance_data=0; //没有回波则清零test = !test; //测试灯变化}/********************************************每循环3次就显示结果一次*********************************************/a=distance_data;if(b==a) CONT_1=0;if(b!=a) CONT_1++;if(CONT_1>=3){ CONT_1=0;b=a;conversion(b);}}}//***************************************************************//外部中断0,用做判断回波电平INTO_() interrupt 0 // 外部中断是0号{outcomeH =TH1; //取出定时器的值outcomeL =TL1; //取出定时器的值succeed_flag=1; //至成功测量的标志EX0=0; //关闭外部中断}//****************************************************************//定时器0中断,用做显示timer0() interrupt 1 // 定时器0中断是1号{TH0=0xfd; //写入定时器0初始值TL0=0x77;switch(flag){case 0x00:P0=ge; P2=0xfe;flag++;break;case 0x01:P0=shi;P2=0xfd;flag++;break;case 0x02:P0=bai;P2=0xfb;flag=0;break;}}//显示数据转换程序void conversion(uint temp_data){uchar ge_data,shi_data,bai_data ;bai_data=temp_data/100 ;temp_data=temp_data%100; //取余运算shi_data=temp_data/10 ;temp_data=temp_data%10; //取余运算ge_data=temp_data;bai_data=SEG7[bai_data];shi_data=SEG7[shi_data];ge_data =SEG7[ge_data];EA=0; //显示数据的时候不要测量bai = bai_data;shi = shi_data;ge = ge_data ;EA=1;}//****************************************************************** void delay_20us(){ uchar bt ;for(bt=0;bt<100;bt++);}。

51单片机超声波测距源代码

51单片机超声波测距源代码

51单⽚机超声波测距源代码/* 超声波模块的TRIG管脚接在单⽚机的P20⼝,ECHO管脚接在单⽚机的P21⼝其他的电源管脚接在单⽚机开发板上电源⼝即可。

*/#include"reg51.h"#include"intrins.h" //包含的头⽂件,⽤到了intrins.h的_nop_();延时⽂件sbit RX=P2^1; //定义管脚,⽤到的是P2上的两个双向I/O⼝sbit TX=P2^0;unsigned int time=0; //声明变量,注意单⽚机中⼀般都是⽤⽆符号的Unsigned类型变量,在Keil中,char是8位变量,int是16位变量unsigned int timer=0;unsigned char posit=0;unsigned int S=0;bit flag =0; //bit顾名思义,是1位的变量//--定义使⽤的IO--//#define GPIO_DIG P0 //此处定义的I/O是数码管显⽰要⽤到的I/O,若只⽤到串⼝则可以去掉sbit LSA=P2^2; //此处定义的是74LS138译码器的管脚,同理,只⽤到串⼝的话可以去掉sbit LSB=P2^3;sbit LSC=P2^4;//--定义全局变量--//unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显⽰码,也是供数码管显⽰⽤的,可以去掉unsigned char disbuff[4] ={ 0,0,0,0,};/******************************************************************************** 函数名 : DigDisplay* 函数功能 : 使⽤数码管显⽰* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void DigDisplay(){unsigned char i;unsigned int j;for(i=0;i<8;i++){switch(i) //位选,选择点亮的数码管,{case(0):LSA=0;LSB=0;LSC=0; break;//显⽰第0位case(1):LSA=1;LSB=0;LSC=0; break;//显⽰第1位case(2):LSA=0;LSB=1;LSC=0; break;//显⽰第2位case(3):LSA=1;LSB=1;LSC=0; break;//显⽰第3位case(4):LSA=0;LSB=0;LSC=1; break;//显⽰第4位case(5):LSA=1;LSB=0;LSC=1; break;//显⽰第5位case(6):LSA=0;LSB=1;LSC=1; break;//显⽰第6位case(7):LSA=1;LSB=1;LSC=1; break;//显⽰第7位}GPIO_DIG=disbuff[i]; //发送段码j=10; //扫描间隔时间设定while(j--);GPIO_DIG=0x00;//消隐}}/********************************************************/void Conut(void){time=TH0*256+TL0; //根据定时器数据计算时间TH0=0; //初始化定时器TL0=0;S= (int)(time*0.17); //算出来是CMif((S>=4000)||flag==1) //超出测量范围显⽰“ERR0”{flag=0;disbuff[0]=0x3f; //“-”disbuff[1]=0x50; //“-”disbuff[2]=0x50; //“-”disbuff[3]=0x79; //“-”}else //分离各位显⽰的数字{disbuff[3]=DIG_CODE[S%10000/1000];disbuff[2]=DIG_CODE[S%1000/100];disbuff[1]=DIG_CODE[S%100/10];disbuff[0]=DIG_CODE[S%10/1];}}/********************************************************/void zd0() interrupt 1 //T0中断⽤来判断是否超过测距范围{flag=1; //若中断溢出,则超过测距范围,标记量置1。

51单片机红外解码、超声波测距程序(详细解释程序)

51单片机红外解码、超声波测距程序(详细解释程序)

// c51红外解码、超声波测距程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define count 4uchar data IRcode[4]; //定义一个4字节的数组用来存储代码uchar table[4];uchar enled[4]={0x1f,0x2f,0x4f,0x8f};uchar CodeTemp,temp,tt; //编码字节缓存变量uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2; //延时用的循环变量uint distance,distance1,time; //距离,timesbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)sbit come=P3^3;sbit d=P1^1;//发送码sbit BZ=P1^0;sbit s=P3^7;//38ksbit ss=P3^6;//38kuchar m;// 开关控制//sbit n=P2;//电机反转code unsigned charseg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28}; //显示段码/**************************** 定时器0中断************************/void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//tt++;//发送超声波个数}/**************************** 延时0.9ms子程序************************/void Delay0_9ms(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}/***************************延时1ms子程序**********************/void Delay1ms(void){uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);}/***************************延时4.5ms子程序**********************/ void Delay4_5ms(void){uchar i,j;for(i=10;i>0;i--)for(j=225;j>0;j--);}/**************************** 解码延时子程序************************/ void Delay(void){uchar i,j,k;for(i=100;i>0;i--)for(j=100;j>0;j--)for(k=3;k>0;k--);}/**************************** 显示延时子程序************************/ void ledDelay(unsigned int tc) //延时程序{unsigned int i,j;for(i=0;i<10;i++)for(j=0;j<tc;j++);}/************************************************ ****************///定时器1中断,用做超声波测距无回波void timer1() interrupt 3{TR1=0;ET1=0;EX1=0;TH1=0;TL1=0;}/***********************显示程序*********************/ void Led(int date) //显示函数{ int i;table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;date=0;for(i=0;i<120;i++){P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器P0=seg7code[table[i%4]]; //取出千位数,查表,输出。

51单片机的液晶显示超声波测距仪

51单片机的液晶显示超声波测距仪

#include"1602.h"#define uchar unsigned char#define uint unsigned intsbittring = P1^3; //超声波控制端sbit echo = P3^2; //回波必须接在外部中断引脚上sbitledwarn = P2^0; //报警灯,低电平亮sbit beep = P2^1; //报警蜂鸣器uintdisplayCount;//显示计数uint time = 0;//时间unsigned long distance ;//距离float distancef;//浮点型的数据uintflagSucceed = 0; //测量成功标志位uintflagDisplay = 0; //开显示标志位void delay_20us(){uchari ;for(i=0;i<140;i++);}voidinit_shuju(){tring = 0;distance = 0;displayCount = 0;}void init_waibu0(){IT0 = 0; //外部引脚为低时触发中断EX0=0; //关闭外部中断}void timer0_Init(){TMOD = 0x11; //定时器0和1工作在16位方式TH0 = (65535-45872)/256;TL0 = (65535-45872)%6;TR0 = 1; //启动定时器ET0 = 1; //允许定时器0中断}void timer1_Init(){TMOD = 0x11; //定时器0和1工作在16位方式TH1 = 0;TL1 = 0;ET1 = 1; //定时器1中断允许}void wbzd0() interrupt 0//下降沿触发{time =TH1*256+TL1; //取出定时器的值flagSucceed = 1; //置成功测量的标志EX0=0; //关闭外部中断// TR1=0;}void timer0() interrupt 1 // 定时器0{TH0 = (65535-45872)/256;TL0 = (65535-45872)%6;displayCount ++;if (displayCount>= 20) //1秒钟显示一次{flagDisplay = 1; //开显示displayCount = 0;}}void start_csb() //启动csb模块{tring = 1;delay_20us();tring = 0;}void main(){EA=0;init_shuju();init_waibu0();timer0_Init();timer1_Init();L1602_init();L1602_string(1,1,"welcome my ");L1602_string(2,1,"test distance "); delay1(1);while(1){EA=0;//关闭总中断start_csb();while(echo==0);//变高则进入下一步flagSucceed = 0;TR1=1; //启动定时器1开始计数EA = 1;EX0=1;TH1= 0;TL1= 0;TF1= 0; //定时器1溢出标志位while (TH1<90) ; //盲区TR1 = 0; //关闭定时器1EX0 = 0; //关闭外部中断if(flagSucceed==1) //一次测试成功,则计算距离,单位为厘米{distancef = time * 1.085;//微妙为单位distancef /=58;//单位为厘米distance = distancef*10+0.5;//如果距离小于20cm,则声光报警if ((flagSucceed == 1) && (distance <= 200)){ledwarn = 0;beep = 0;delay1(1);beep = 1;delay1(1);}else{ledwarn = 1;beep = 1;}}if (flagDisplay == 1) //1秒显示时间到{if(flagSucceed==0)//没有测试成功{L1602_string(1,1," can't distance ");L1602_string(2,1," ------ ");}else{//LCD显示数据L1602_string(1,1,"distance result:");L1602_string(2,1," cm ");L1602_int(2,5,distance);}flagDisplay = 0;}}}。

单片机源代码-超声波测距

单片机源代码-超声波测距
lcd_en=1;//高电平,数据送入液晶液晶数据RAM
_nop_();//保持一会儿,使显示数据可靠地送入液晶数据RAM
lcd_en=0;//低电平,显示数据
}
void lcd1602_init()//液晶显示初始化操作
{
P0=0x00;
hc573_sg_le=0;//关闭HC573使数码管不显示
if(distance<5)//*本程序最小测量距离为5cm
return 4;//*如果小于5cm将返回一个4
//*的值作为报警处理的判断数据
if(distance>=300)//**本程序最大测量距离为300cm
return 301;//**如果超过300cm将返回一个301
//**的值作为报警处理的判断数据
hc573_bit_le=0;
lcd_en=0;//为0,为实现高脉冲作准备
lcd_write_cmd(0x38);//设置为5x7显示
lcd_write_cmd(0x0c);//打开显示-不显示示光标
lcd_write_cmd(0x6);//地址加一,光标右移,整屏显示不移动
lcd_write_cmd(0x01);//清屏
}
voidlcd_write_data(unsigned chardat) //液晶写数据函数
{
lcd_busy_check();//每次操作之前都要进行忙信号检测
lcd_rs=1;//执行数据操作,为1
lcd_rw=0;//写操作,为0
P0=dat;//送数据到液晶数据端口P0,准备执行数据操作
_nop_();
}
else
{//如果测量距离满足要求
FM=1;//那么蜂鸣器不发声

51单片机超声波模块的C语言程序

51单片机超声波模块的C语言程序

51单⽚机超声波模块的C语⾔程序//超声波模块程序//超声波模块程序//Trig = P2^0//Echo = P3^2#include#define uchar unsigned char#define uint unsigned intint time;int succeed_flag;uchar timeL;uchar timeH;sbit Trig=P1^0;sbit Echo=P3^2;uchar codetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f};uchar code table1[]={0,1,2,3,4,5,6,7};//void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//void delay_20us(){uchar a ;for(a=0;a<100;a++);}//************************************************************ ***//显⽰数据转换程序void display(uint temp){uchar ge,shi,bai;bai=temp/100;shi=(temp%100)/10;ge=temp%10;P2=table1[2];P0=table[ge];delay(1);P2=table1[1];P0=table[shi];delay(1);P2=table1[0];P0=table[bai];delay(1);}//************************************************************ ***void main(){uint distance;// test =0;Trig=0; //⾸先拉低脉冲输⼊引脚EA=1; //打开总中断0TMOD=0x10; //定时器1,16位⼯作⽅式while(1){EA=0; //关总中断Trig=1; //超声波输⼊端delay_20us(); //延时20usTrig=0; //产⽣⼀个20us的脉冲while(Echo==0); //等待Echo回波引脚变⾼电平 succeed_flag=0; //清测量成功标志EA=1;EX0=1; //打开外部中断0TH1=0; //定时器1清零TL1=0; //定时器1清零TF1=0; //计数溢出标志TR1=1; //启动定时器1delay(20); //等待测量的结果TR1=0; //关闭定时器1EX0=0; //关闭外部中断0if(succeed_flag==1){time=timeH*256+timeL;distance=time*0.0172; //厘⽶}if(succeed_flag==0){distance=0; //没有回波则清零// test = !test; //测试灯变化}display(distance);}}//************************************************************ *** //外部中断0,⽤做判断回波电平void exter() interrupt 0 // 外部中断0是0号{EX0=0; //关闭外部中断timeH =TH1; //取出定时器的值timeL =TL1; //取出定时器的值succeed_flag=1;//⾄成功测量的标志}//************************************************************ **** //定时器1中断,⽤做超声波测距计时void timer1() interrupt 3 //{TH1=0;TL1=0;}1602液晶显⽰的超声波模块程序接⼝程序⾥边都有、、#include//#include#define uchar unsigned char#define uint unsigned intsbit lcdrs=P2^3;sbit lcden=P2^2;sbit trig=P2^0; //超声波发送//sbit echo=P3^2; //超声波接受//P0____________DB0-DB7uchar 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/58return dist; //1个机器周期是12个时钟周期 timer*12/(58*11.0592)=timer/53 }void HC_run(){uint tempH=0x00,tempL=0x00;TH0=0;TL0=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) {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);}}。

基于51单片机的超声波测距系统

基于51单片机的超声波测距系统

基于51单片机的超声波测距系统完成日期:2011年2月22日一、设计任务和性能指标31.1设计任务 (3)].2性能指标 (3)二、超声波测距原理概述 (4)2.1超声波传感器 (5)2.1.1超声波发生器 (5)2.1.2压电式超声波发生器原理 (5)2.1. 3单片机超声波测距系统构成 (5)三、设计方案63.1 AT89C2051 单片机 (7)3.2超声波测距系统构成 (8)3.2.1超声波测距单片机系统 (9)图3-1:超声波测距单片机系统 (9)3.2.2超声波发射、接收电路 (9)图3-1:超声波测距发送接收单元 (10)3.2. 3显示电路 (10)四.系统软件设计 (11)4.1主程序设计 (11)4.2超声波测距子程序 (12)4.3超声波测距程.序流程图 (13)4.4超声波测距程子序流程图 (14)五.调试及性能分析 (14)5.1调试步骤 (14)5.2性能分析 (15)六.心得体会 (15)参考文献 (16)附录一超声波测系统原理图 (18)附录二超声波测系统原理图安装图 (19)附录三超声波测系统原理图PCB图 (20)附录四超声波测系统原理图C语肓原程序 (21)参考文献 (26)一、设计任务和性能指标1.1设计任务利用单片机及外圉接口电路(键盘接口和显示接口电路)设计制作一个超声波测距仪器,用LED数码管把测距仪距测出的距离显示出来。

要求用Protel画出系统的电路原理图,印刷电路板,绘出程序流程图,并给出程序清单。

1.2性能指标距离显示:用三位LED数码管进行显示(单位是CM)。

测距范围:25CM到250CM之间。

误差:1%。

二、超声波测距原理概述超声波是山机械振动产生的,可在不同介质中以不同的速度传播。

山于超声波指向 性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如 测距仪和物位测量仪等都可以通过超声波来实现。

超声测距是一种非接触式的检测方 式。

51单片机超声波测距程序

51单片机超声波测距程序

//超声波测距,测距X围2cm-400cm; #include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit trig=P1^0;sbit echo=P3^2;sbit test=P1^1;//测试灯sbit dula=P2^6;sbit wela=P2^7;sbit BEEP=P2^3;uint timeh,timel,distance;uint ge,shi,bai,xiaoshu,flag,time;/*共阴极数码管不带小数点代码表*/ uchar code list[]={0x3f , 0x06 , 0x5b , 0x4f ,0x66 , 0x6d ,0x7d , 0x07 ,0x7f , 0x6f , 0x77 , 0x7c ,0x39 , 0x5e , 0x79 , 0x71 };/*共阴极数码管带小数点代码表*/ uchar code listtwo[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};/*长延时函数*/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=100;y>0;y--); }/*短延时函数*/void delay20us() {uchar a;for(a=0;a<100;a++); }/*报警函数*/ void beer(){//BEEP=0;delay(10);}/*定时器初始化*/ void initime0() {TMOD=0x01;TH0=0;TL0=0;EA=0;ET0=0;EX0=0;}/*外部中断函数*/void estern() interrupt 0{timeh=TH0;timel=TL0;beer();flag=1;//进入中断,标志位就置1 EX0=0;//同时关断外部中断和定时器 TR0=0;}/*显示函数*/void display(distance) {bai=distance/1000;shi=distance%1000/100; ge=distance%100; xiaoshu=distance%10;dula=1;P0=list[xiaoshu];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(2);P0=listtwo[ge]; dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delay(2);dula=1;P0=list[shi]; dula=0;P0=0xff;wela=1;P0=0xfd;delay(1);dula=1;P0=list[bai]; dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delay(1);}/*被调用子函数*/ void diaoyong(){uint i;EA=0;echo=1;//为了检测电平的上下,首先必须拉高trig=1;delay20us();trig=0;while(echo==0);//如果进入中断即接收到超声波就向下执行flag=0;//接收到就去除标志位EA=1;//同时打开总中断EX0=1;//打开外部中断TR0=1;//开定时器TH0=0;//定时器清零TL0=0;for(i=0;i<100;i++)//等待测量的结果{display(distance);//用100次显示循环来延时,解决数码管显示不亮问题}//delay(50);//用延时函数数码管闪烁TR0=0;//延时一段时间后关断定时器EX0=0;//延时一段时间后关断外部中断if(flag==1)//如果进入中断,说明测距已经测好{time=timeh*256+timel;//计算测定距离,并显示distance=time*0.1720;display(distance);}if(flag==0)//如果没有进入中断,距离为0,同时灯闪烁{distance=0;test=!test;}}word/*主函数*/void main(){initime0();test=0;trig=0;EA=1;while(1){diaoyong();display(distance);}}11 / 11。

51单片机超声波测距程序

51单片机超声波测距程序

// 超声波测距,测距范围2cm-400cm;#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned char sbittrig=P1A0;sbit echo二卩3八2;sbit test=P1A1; // 测试灯sbit dula=P2A6;sbit wela=P2A7;sbit BEEP=P2A3;uint timeh,timel,distance;uint ge,shi,bai,xiaoshu,flag,time;/* 共阴极数码管不带小数点代码表*/ uchar code list[]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 ,0x6d ,0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c , 0x39 , 0x5e , 0x79 , 0x71 };/* 共阴极数码管带小数点代码表*/ uchar code listtwo[] ={ 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};/* 长延时函数*/void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=100;y>0;y--);/* 短延时函数*/ void delay20us() {uchar a;for(a=0;a<100;a++); }/* 报警函数*/void beer(){// BEEP=0; delay(10);}/* 定时器初始化*/ void initime0() {TMOD=0x01;TH0=0;EA=0;ET0=0;EX0=0;}/* 外部中断函数*/ void estern() interrupt 0 {timeh=TH0;timel=TL0;beer();flag=1;EX0=0;TR0=0;}/* 显示函数*/void display(distance) bai=distance/1000;shi=distance%1000/100; ge=distance%100; xiaoshu=distance%10; // 进入中断,标志位就置 1 // 同时关断外部中断和定时P0=list[xiaoshu]; dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(2);dula=1;P0=listtwo[ge]; dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delay(2);dula=1;P0=list[shi]; dula=0;wela=1;P0=0xfd; wela=0;delay(1);dula=1;P0=list[bai]; dula=0;P0=0xff;wela=1;P0=0xfe; wela=0;delay(1);}/* 被调用子函数 */ void diaoyong(){ uinti;EA=0;echo=1; // 为了检测电平的高低,首先必须拉高trig=1;delay20us();trig=0;while(echo==0);向下执行flag=0;EA=1;EX0=1;TR0=1;TH0=0;TL0=0;for(i=0;i<100;i++) display(distance); // 用 100 次显示循环来延时, 解决数码管// 如果进入中断 即接收到超声波就 // 接收到就清除标志位 // 同时打开总中断 // 打开外部中断 // 开定时器 // 定时器清零// 等待测量的结果显示不亮问题}// delay(50); // 用延时函数数码管闪烁TR0=0; // 延时一段时间后关断定时器EX0=0; // 延时一段时间后关断外部中断if(flag==1) // 如果进入中断,说明测距已经测好{time=timeh*256+timel;// 计算测定距离,并显示distance=time*0.1720;display(distance);}if(flag==0) // 如果没有进入中断,距离为0,同时灯闪烁{distance=0;test=!test;}}/* 主函数*/void main(){initime0();test=0;trig=0;EA=1;while(1){ diaoyong();display(distance);。

51单片机超声波模块程序

51单片机超声波模块程序

51单片机超声波模块程序//main.c#include#include#include "lcd1602.h"unsigned char TimeH, TimeL;unsigned int time;float distance;char temp[16];sbit Trig = P1^0;sbit Echo = P1^1;void Timer0Init();void main(){Lcd1602Init();Trig = 0; //初始化while(1){Timer0Init();Trig = 1;while(Echo == 0); //当Echo变为高电平时立即启动定时器以减小误差TR0 = 1;while (Echo == 1);//等待捕获Echo从高到低的跳变TimeL = TL0; //当Echo由高到低,立即将TH0,TL0的值记下TimeH = TH0;Trig = 0;TR0 = 0;time = TimeH;time <<= 8;time += TimeL;distance = time * 0.017;//将distance的值以%f的格式,格式输出到字符数组temp中,变成字符串,//便于显示//sprintf在头文件stdio.h中sprintf(temp, "%f", distance);Lcd1602WriteStr(0x80, temp);}}void Timer0Init(){TMOD = 0X01;TH0 = 0;TL0 = 0;TF0 = 0;EA = 1;}void timer0() interrupt 1 //定时器0中断,防止溢出{TH0 = 0;TL0 = 0;}//lcd1602.h#ifndef __LCD1602_H__#define __LCD1602_H__#includesbit Lcd1602E = P2^7;sbit Lcd1602RW = P2^5;sbit Lcd1602RS = P2^6;void Lcd1602WriteCmd (unsigned char cmd);void Lcd1602WriteData (unsigned char dat);void Lcd1602BusyCheck();void Lcd1602WriteStr(unsigned char addr, unsigned char str[]); void Lcd1602Init ();#endif//lcd1602.c#include "lcd1602.h"#include#define Lcd1602DataPort P0#define Busy 0x80unsigned char ix;void Lcd1602Init (){Lcd1602WriteCmd (0x38);Lcd1602WriteCmd (0x0c);Lcd1602WriteCmd (0x06);Lcd1602WriteCmd (0x01);Lcd1602WriteCmd (0x80);}void Lcd1602WriteCmd(unsigned char cmd) {Lcd1602BusyCheck();Lcd1602RS = 0;Lcd1602RW = 0;Lcd1602DataPort = cmd;for (ix = 0xff; ix > 0; --ix);//延时Lcd1602E = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 0;for (ix = 0xff; ix > 0; --ix);Lcd1602RW = 1;}void Lcd1602WriteData (unsigned char dat) {Lcd1602BusyCheck();Lcd1602RS = 1;Lcd1602RW = 0;Lcd1602DataPort = dat;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 0;for (ix = 0xff; ix > 0; --ix);Lcd1602RW = 1;}void Lcd1602BusyCheck() //忙检测{Lcd1602RS = 0;Lcd1602RW = 1;for (ix = 0xff; ix > 0; --ix);Lcd1602E = 1;while ((Lcd1602DataPort & Busy) != 0); Lcd1602E = 0;}void Lcd1602WriteStr(unsigned char addr, unsigned char str[]) {unsigned char i;Lcd1602WriteCmd (addr);for (i = 0; i < strlen(str); i++)Lcd1602WriteData(str[i]);}。

超声波测距51代码

超声波测距51代码

#include<reg52.h>#include<intrins.h>#include<stdio.h>#define uint unsigned int #define uchar unsigned char sbit RS = P2^4; //定义端口sbit RW = P2^5;sbit EN = P2^6;sbit Trig=P3^1;sbit Echo=P3^2;uchar Distance[10]={0}; uchar outh=0,outl=0;float Echo_data=0;bit Echo_Flag=0;bit Start_Flag=0;//bit Error_Flag=0;bit ov=0;sbit test=P1^0;//start测试用sbit test1=P1^4;//溢出ov测试//sbit test2=P1^4;//保留void Timer_init();void Trig_pulse();void Distance_deal();void delay(uchar x){uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}// 判忙函数bit lcd_busy(){P0=0xff;RS=0;RW=1;EN=0;_nop_();EN=1;return(bit)(P0&0x80);}void write_com(char com){while(lcd_busy());RS=0;RW=0;EN=1;P0=com;_nop_();EN=0;}void write_data(char date){while(lcd_busy());RS=1;RW=0;EN=1;P0=date;_nop_();EN=0;}/*void lcd_clear(){write_com(0x01);delay(5);} */void lcd_wstring(uchar x,uchar y,uchar *s) //些字符串函数{if(y==0){write_com(0x80+x);}else{write_com(0xc0+x);}while(*s){write_data(*s);s++;}}/*void lcd_wchar(uchar x,uchar y,uchar s) //些字符函数{if(y==0){write_com(0x80+x);}else{write_com(0xc0+x);}write_data(s);} */void lcd_init(){write_com(0x38);delay(5);write_com(0x38);//显示模式设置write_com(0x08);//显示关闭write_com(0x01);//显示清屏write_com(0x06);//显示光标移动设置delay(5);write_com(0x0c);//显示开及光标设置}void main(){Timer_init();while(1){while(Start_Flag){test=~test;Start_Flag=0;Echo=0;Trig_pulse();while(!Echo);TR0=1;while(Echo);TR0=0;outh=TH0;outl=TL0;TH0=0;TL0=0;lcd_init();delay(1);Distance_deal();delay(5);}}}void Timer_init(){EA=1;TMOD|=0X11;TH0=0;TL0=0;ET0=1;TR0=0;ET1=1;TR1=1;TH1=-10000/256;TL0=-10000%256;}void Trig_pulse(){Trig=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();Trig=0;}void Timer0() interrupt 1{ov=1;test1=~test1;}void Timer3() interrupt 3{uchar cnt;TH1=-10000/256;TL1=-10000%256;cnt++;if(cnt==100){cnt=0;Start_Flag=1;}}void Distance_deal(){// uchar i;uint temp=0;// Error_Flag=0;temp=256*outh+outl;Echo_data=(float)(temp*0.017);sprintf(Distance,"(cm):%6.2f",Echo_data);if((Echo_data)>480+'0'||ov){ov=0;lcd_wstring(0,0,"Erroe Distance");}else{lcd_wstring(0,0,"Current Distance!");lcd_wstring(3,1,Distance);}}。

基于单片机的超声波测距程序

基于单片机的超声波测距程序

LCD程序#include <reg51.h>#include <intrins.h>#define uchar unsigned char #define uint unsigned int sbit lcdrs=P2^0; //定义LCD引脚sbit lcdrw=P2^1;sbit lcden=P2^2;void writelcdcmd(uchar); void writelcddat(uchar);void delayms(uint z)//不精确延时{uchar x;uint y;for(x=z;x>0;x--)for(y=125;y>0;y--);}void LCD_BUSY()//LCD忙检测{ uchar sta;P0=0xff;lcdrs=0;lcdrw=1;do{lcden=1;sta=P0;lcden=0;}while(sta & 0x80);}void writelcdcmd(uchar cmd)//LCD写命令{LCD_BUSY();delayms(1);lcdrs=0;lcdrw=0;lcden=0;P0=cmd;delayms(1);lcden=1;delayms(1);lcden=0;}void writelcddat(uchar dat)//LCD写数据{LCD_BUSY();delayms(1);lcdrs=1;lcdrw=0;lcden=0;P0=dat;delayms(1);lcden=1;delayms(1);lcden=0;}void inilcd() //LCD初始化{ delayms(15);writelcdcmd(0x38);delayms(5);writelcdcmd(0x0c);delayms(5);writelcdcmd(0x06);delayms(5);writelcdcmd(0x01);delayms(5);}void play(unsigned char *p)//显示//{while(*p!='\0'){writelcddat(*p);p++;delayms(1);}}超声波模块程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit BEEP=P1^0; //定义蜂鸣器引脚sbit Trig=P3^5;//定义HC-SR04两个引脚sbit Echo=P3^6 ;sbit ADD=P2^5;//定义加SV按键引脚sbit DUC=P2^4;//定义减SV按键引脚sbit CONTINOUS=P2^6;//定义连续加减SV引脚uint SV=3000;uint value1;float SS,CLOCKCYCLE;uchar code str[]={"PV:"};uchar code str1[]={"cm"};extern voidwritelcdcmd(uchar);extern voidwritelcddat(uchar);extern void play(uchar *p);extern void inilcd();void delayus(uint i) //微秒级延时{while(i--);}void initsr04()//HC-SR04初始化{TMOD=0x11;TH0=0;TL0=0;EA=1;TR0=0;CLOCKCYCLE=12/11. 0592;SS=332+0.607*25;Trig=0;Echo=0;}float mesuringdistance()//测距{TH0=0;TL0=0;Trig=1;delayus(6);//拉高Trig 至少20usTrig=0;while(!Echo);TR0=1;while(Echo);TR0=0;value1=(SS*CLOCKC YCLE*((float)TH0*256+(flo at)TL0))/2/1000;return(value1);}void displaysr04()//1602显示距离{ uchar disdat1[9];ADD=DUC=1;if(ADD==0)//按下一次SV加1{SV++;while(!ADD);}if(DUC==0)//按下一次SV减1{SV=SV-1;while(!DUC);}if(CONTINOUS==0){if(ADD==0)//按下一次SV加1{SV++;}if(DUC==0)//按下一次SV减1{SV--;}}/*******************************************//*************当前值显示******************************/disdat1[0]=value1/1000+0x30;disdat1[1]=value1%1000/100+0x30;disdat1[2]=value1%100/10+0x30;disdat1[3]=value1%10+0x30;writelcdcmd(0x80);play(str);if(disdat1[0]==0x30){disdat1[0]=0x20;if(disdat1[1]==0x30)disdat1[1]=0x20;}writelcdcmd(0x83);writelcddat(disdat1[0]);writelcdcmd(0x84);writelcddat(disdat1[1]);writelcdcmd(0x85);writelcddat(disdat1[2]);writelcdcmd(0x86);writelcddat(0x2e);writelcdcmd(0x87);writelcddat(disdat1[3]);writelcdcmd(0x88);play(str1);/*******************************************************************//***********设定值显示***********************/disdat1[4]=SV/1000+0x30;disdat1[5]=SV%1000/100+0x30;disdat1[6]=SV%100/10+0x30;disdat1[7]=SV%10+0x30;if(disdat1[4]==0x30){disdat1[4]=0x20;if(disdat1[5]==0x30)disdat1[5]=0x20;}writelcdcmd(0xc0);writelcddat('S');writelcdcmd(0xc1);writelcddat('v');writelcdcmd(0xc2);writelcddat(':');writelcdcmd(0xc3);writelcddat(disdat1[4]);writelcdcmd(0xc4);writelcddat(disdat1[5]);writelcdcmd(0xc5);writelcddat(disdat1[6]);writelcdcmd(0xc6);writelcddat(0x2e);writelcdcmd(0xc7);writelcddat(disdat1[7]);writelcdcmd(0xc8);play(str1);}void SOUND(){if(SV>value1)BEEP=0;elseBEEP=1;}主程序#include<reg52.h>sbit BEEP=P2^3;#define uint unsigned int#define uchar unsigned char extern void writelcdcmd(uchar);extern void writelcddat(uchar);extern void play(uchar *p); extern void inilcd();extern void initsr04(); extern float mesuringdistance();extern void delayms(uint); extern void displaysr04(); extern void SOUND();void main(){delayms(2000);inilcd();initsr04();while(1){mesuringdistance();displaysr04();SOUND();delayms(65000);}}。

#用51单片机设计超声波测距系统的设计原理和电路(附源程序)

#用51单片机设计超声波测距系统的设计原理和电路(附源程序)

基于51单片机的超声波测距仪说明书引言超声波测距仪,可使用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于如液位、井深、管道长度的测量等场合。

利用超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量。

利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制。

一、性能要求该超声波测距仪,要求测量范围在0.08-3.00m,测量精度1cm,测量时和被测物体无直接接触,能够清晰稳定地显示测量结果。

二、工作原理及方案论证超声波传感器及其测距原理超声波是指频率高于20KHz的机械波。

用超声波传感器产生超声波和接收超声波,习惯上称为超声波换能器或超声波探头。

超声波传感器有发送器和接收器.超声波传感器是利用压电效应的原理将电能和超声波相互转化,即在发射超声波的时候,将电能转换,发射超声波;而在收到回波的时候,则将超声振动转换成电信号。

超声波测距的原理一般采用渡越时间法TOF(timeofflight)。

首先测出超声波从发射到遇到障碍物返回所经历的时间,再乘以超声波的速度就得到二倍的声源和障碍物之间的距离。

根据要求并综合各方面因素,采用AT89C52单片机作为主控制器,用动态扫描法实现LED数字显示,超声波驱动信号用单片机的定时器完成,超声波测距仪的系统框图如下图所示:图1 超声波测距仪系统设计框图三、系统硬件部分硬件部分主要由单片机系统及显示电路、超声波发射电路和超声波检测接收电路三部分组成。

1.单片机系统及显示电路单片机采用AT89C52来实现对CX20106A红外接收芯片和TCT40-10系列超声波转换模块的控制。

单片机通过P1.1引脚发射脉冲控制超声波的发送,然后单片机不停的检测外中断0口INT0引脚,当INT0引脚的电平由高电平变为低电平时就认为超声波已经返回。

计数器所计的数据就是超声波所经历的时间,通过换算就可以得到传感器和障碍物之间的距离。

显示电路采用简单实用的4位共阳LED数码管,段码用74LS244驱动,位码用PNP三极管驱动。

51单片机驱动超声波测距模块C51程序

51单片机驱动超声波测距模块C51程序

51单片机驱动超声波测距模块C51程序51单片机驱动超声波测距模块C51程序#include;#define uchar unsigned char#define uint unsigned int#define ulong unsigned long//******************* 函数声明**************************void init_T otal(); //总初始化void init_T0(); //初始化定时器T0void init_T1(); //初始化定时器T1void init_inter0();//初始化外部中断1void send_T();void delay(uint z);//延时一段时间void delay_300us();//延时300usvoid delay_100us();//延时100us//*********************************************** *********sbit lcdrs=P1^7;sbit lcdrw=P3^1;sbit lcden=P1^5;//1602液晶控制端sbit send=P1^0;//sbit BEEP=P2^5;sbit wei=P2^6;sbit duan=P2^7;volatile uchar Count_TH ,Count_TL;//分别读计数器T1的高位TH1,低位TL1uchar t0,flag;uint time;uchar code table1[]=" distance "; uchar code table2[]=" ";//初始化显示void write_com(uchar com)//1602写指令函数{lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;void write_data(uchar datb)//1602写数据函数{ lcdrs=1;P0=datb;delay(1);lcden=1;delay(1);lcden=0;}void distance(uchar addr,uint datb){uchar bai,shi,ge ;bai=datb/100;shi=datb%100/10;ge=datb%10;write_com(0x80+0x40+addr);write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);}/************************************************ *************************************** 名称:void init_T otal()* 功能:总初始化* 入口参数:NULL* 全局变量:NULL* 返回值:NULL**************************************************************************************/void init_T otal(){init_T0(); //初始化定时器T0为工作方式2 init_T1(); //初始化定时器T1为工作方式1 init_inter0();//初始化外部中断1EA=1; //开总中断}/*************************************************************************************** 名称:void init_T0()* 功能:初始化定时器T0为工作方式2* 入口参数:NULL* 全局变量:NULL* 返回值:NULL**************************************************************************************/void init_T0(){TMOD=0X12;TH0=0XE7;TL0=0XE7;EA=0;ET0=1;TR0=1;}/************************************************ *************************************** 名称:void init_T1()* 功能:初始化定时器T1为工作方式1* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void init_T1(){TMOD=0X12;TH1=0;TL1=0;EA=0;ET1=1;TR1=1;}/************************************************ *************************************** 名称:void init_inter1()* 功能:初始化外部中断1为低电平触发方式* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void init_inter0(){IT0=0; //低电平触发EA=0;EX0=0; //关外部中断1}/************************************************ *************************************** 名称:void inter_T0() interrupt 1* 功能:定时器T0中断函数产生40KHZ的方波* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void inter_T0() interrupt 1{send=~send;}/************************************************ *************************************** 名称:void inter_T1() interrupt 3* 功能:定时器T1中断函数* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void inter_T1() interrupt 3{TR1=0;EX0=0; //关外部中断0TH1=0;TL1=0;flag=2;}/************************************************ *************************************** 名称:void inter1() interrupt 2* 功能:外部中断1函数* 入口参数:NULL* 全局变量:Count_TH,Count_TL* 返回值:NULL************************************************* *************************************/void inter0() interrupt 0{TR1=0;EX0=0;flag=1;}/************************************************ *************************************** 名称:void send_T()* 功能:发送10个超声波脉冲* 入口参数:NULL* 全局变量:Count* 返回值:NULL************************************************* *************************************/void send_T(){delay_100us();//发送100us的方波TR0=0;//关定时器T0}/************************************************ *************************************** 名称:void delay(uint z)* 功能:延时一段时间* 入口参数:z* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void delay(uint z){uint x,y;for(x=z;x>;0;x--)for(y=1000;y>;0;y--);}/************************************************ *************************************** 名称:void delay_300us()* 功能:延时300us* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void delay_300us(){uint x;for(x=75;x>;0;x--);}/************************************************ *************************************** 名称:void delay_100us()* 功能:延时100us* 入口参数:NULL* 全局变量:NULL* 返回值:NULL************************************************* *************************************/void delay_100us(){uint x;for(x=24;x>;0;x--);}//*********************************************** ****************************************void main(){uint t,s;init_T otal();//总初始化while(1){TR1=1;//启动定时器1TR0=1;//启动定时器0send_T(); //发送100us超声波脉冲delay_300us();//延时300us跳过盲区EX1=1; //开外部中断1while(!flag); //等待回波或定时器T1溢出if(flag==1) //回波{Count_TH=TH1;//读计数器T1的高位TH1 Count_TL=TL1;//读计数器T1的低位TL1 t=Count_TH*256+Count_TL;s=(33140*t)/400000;distance(4,s);//液晶1602显示距离 }/* else //定时器T1溢出{Count_TH=0XFE;Count_TL=0X7F;// P2=Count_TH;P2=Count_TL;}*/delay(150);flag=0;//标志位清0TH1=0; //T1清0重新计时TL1=0;}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
send(void)
{
SCON = 0x50; //REN=1允许串行接受状态,串口工作模式2
TMOD= 0x20; //定时器工作方式2
PCON= 0x80; //波特率提高一倍
{
flag=0;
disbuff[0]=0x3f; //“-”
disbuff[1]=0x50; //“-”
disbuff[2]=0x50; //“-”
disbuff[3]=0x79; //“-”
}
else //分离各位显示的数字
ES = 1; //开串口中断
EA = 1; // 开总中断
P0=0; // 屏蔽干扰
SBUF = S; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
TL1=0x30;
DigDisplay(); //数码管显示对应值
timer++; //记录下来进中断的次数
if(timer>=100) //若重复100次后
{
timer=0; //启动一次扫描
TX=1; //由单片机置高800MS
TH0=0;
TL0=0;
TH1=0xf8; //2MS定时
TL1=0x30;
ET0=1; //允许T0中断
ET1=1; //允许T1中断
TR1=1; //开启定时器
EA=1; //开启总中断
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0; //后置低,等待返回数据
}
}
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码,也是供数码管显示用的,可以去掉
unsigned char disbuff[4] ={ 0,0,0,0,};
/*******************************************************************************
}
GPIO_DIG=disbuff[i]; //发送段码
j=10; //扫描间隔时间设定
while(j--);
GPIO_DIG=0x00;//消隐
}
}
/********************************************************/
}
/********************************************************/
void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8; //初始化定时器
void Conut(void)
{
time=TH0*256+TL0; //根据定时器数据计算时间
TH0=0; //初始化定时器
TL0=0;
S= (int)(time*0.17); //算出来是CM
if((S>=4000)||flag==1) //超出测量范围显示“ERR0”
TH1 = 0xF4; // //baud*2 /* 波特率4800、数据位8、停止位1。效验位无 (12M)
TL1 = 0xF4;
TR1 = 1; //开启定时器1
{
disbuff[3]=DIG_CODE[S%10000/1000];
disbuff[2]=DIG_CODE[S%1000/100];
disbuff[1]=DIG_CODE[S%100/10];
disbuff[0]=DIG_CODE[S%10/1];
}
}
unsigned int timer=0;
unsigned char posit=0;
unsigned int S=0;
bit flag =0; //bit顾名思义,是1位的变量
//--定义使用的IO--//
#define GPIO_DIG P0 //此处定义的I/O是数码管显示要用到的I/O,若只用到串口则可以去掉
sbit LSA=P2^2; //此处定义的是74LS138译码器的管脚,同理,只用到串口的话可以去掉
sbit LSB=P2^3;
sbit LSC=P2^4;
//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
/* 超声波模块的TRIG管脚接在单片机的P20口,ECHO管脚接在单片机的P21口 其他的电源管脚接在单片机
开发板上电源口即可。 */
#include"reg51.h"
#include"intrins.h" //包含的头文件,用到了intrins.h的_nop_();延时文件
TR0=1; //RX有返回数据时开启计数
while(RX); //当RX为1时计数并等待
TR0=0; //关闭计数
Conut(); //计算所对应距离
send(); //通过串口发送
}
}
init(void)
{
TMOD=0x11; //0x11=(00010001)2->开定时器0/1 均为16位定时器模式
/*********************************************************/
void main( void )
{
init(); //初始化
while(1)
{
while(!RX); //当RX为零时等待
void DigDisplay()
{
unsigned char i;
unsigned int j;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
while(TI==0); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sbit RX=P2^1; //定义管脚,用到的是P2上的两个双向I/O口
sbit TX=P2^0;
unsigned int time=0; //声明变量,注意单片机中一般都是用无符号的Unsigned类型变量,在Keil中,char是8位变量,int是16位变量
/********************************************************/
void zd0() interrupt 1 //T0中断用来判断是否超过测距范围
{
flag=1; //若中断溢出,则超过测距范围,标记量置1。
相关文档
最新文档