超声波测距C语言源程序代码
超声波测距程序

超声波测距程序超声波程序如下:/**********************************包含头文件**********************************/#include#include "1602.h"/************************************宏定义************************************/#define VELOCITY_30C 3495 //30摄氏度时的声速,声速V= 331.5 + 0.6*温度;#define VELOCITY_23C 3453 //23摄氏度时的声速,声速V= 331.5 + 0.6*温度;/************************************位定义************************************/sbit INPUT = P3^2; //回声接收端口sbit OUTPUT = P1^0; //超声触发端口sbit Beep = P2^0 ; // 蜂鸣器/********************************定义变量和数组********************************/long int distance=0; //距离变量uchar table[]=" Welcome to ";uchar table0[]=" chaoshengbo ";uchar table1[]="There's no echo.";uchar table2[]=" csbcj ";uchar table3[]="Distance:";uchar count;/***********************************函数声明***********************************/extern void initLCD();extern void write_date(uchar date);extern void write_com(uchar com);extern void delay(uint x);/************************************************************** ****************//* 函数名称 : Delay_xMs *//* 函数描述 : 延时函数 *//* 输入参数 : x *//* 参数描述 : 延时时间 *//* 返回值 : 无 *//************************************************************** ****************/void Delay_xMs(unsigned int x){unsigned int i,j;for(i = 0;i < x;i++ ){for(j = 0;j < 3;j++ ){;}}}/************************************************************** ****************//* 函数名称 : Alarm *//* 函数描述 : 蜂鸣器发声函数 *//* 输入参数 : t *//* 参数描述 : 发声的次数 *//* 返回值 : 无 *//************************************************************** ****************/void Alarm(uchar t){uchar i;for(i = 0;i < t;i++){Beep = 1;Delay_xMs(1000);Beep = 0;Delay_xMs(1000);}}/************************************************************** ****************//* 函数名称 : delayt *//* 函数描述 : 延时函数 *//* 输入参数 : x*//* 参数描述 : 延时时间数据 *//* 返回值 : 无 *//************************************************************** ****************/void delayt(uint x){uchar j;while(x-- > 0){for(j = 0;j < 125;j++){;}}}/************************************************************** ****************//* 函数名称 : Init_MCU *//* 函数描述 : 初始化单片机函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void Init_MCU(void){TMOD = 0x01; //定时器2初始化,设置为16位自动重装模式TL0 = 0x66;TH0 = 0xfc; //1msET0 = 1; //开定时器2EA = 1; //总中断使能}/************************************************************** ****************//* 函数名称 : Init_Parameter *//* 函数描述 : 初始化参数和IO口函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//******************************************************************************/void Init_Parameter(void){OUTPUT =1;INPUT = 1;count = 0;distance = 0;}/************************************************************** ****************//* 函数名称 : display_char *//* 函数描述 : 显示字符串函数 *//* 输入参数 : point,address *//* 参数描述 : 写入的字符串的地址指针 1602显示对应的地址 */ /* 返回值 : 无 *//************************************************************** ****************/void display_char(uchar *point,uchar address){uchar i;write_com(0x80 + address);for(i = 0;i < 16; i++){write_date(*point);point++;}}/************************************************************** ****************//* 函数名称 : display *//* 函数描述 : 显示数字*//* 输入参数 : number,address *//* 参数描述 : number写入的数据,address地址 *//* 返回值 : 无 *//************************************************************** ****************/void display(int number,uchar address){uchar b,c,d,e;b= (number / 1000);c= (number / 100) % 10;d = (number / 10) % 10;e = number % 10;write_com(0x80 + address);write_date(b + 48);write_date(c + 48);write_date(d + 48);write_date(46); //小数点的ASCIIwrite_date(e + 48);write_date(99); //"c"的ASCIIwrite_date(109); //"m"的ASCII}/************************************************************** ****************//* 函数名称 : Trig_SuperSonic *//* 函数描述 : 发出声波函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void Trig_SuperSonic(void)//出发声波{OUTPUT = 1;delayt(1);OUTPUT = 0;}/************************************************************** ****************//* 函数名称 : Measure_Distance *//* 函数描述 : 计算距离函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void Measure_Distance(void){uchar l;uint h,y;TR0 = 1;while(INPUT){;}TR0 = 0;l = TL0;h = TH0;y = (h << 8) + l;y = y - 0xfc66;//us部分distance = y + 1000 * count;//计算总时间TL0 = 0x66;TH0 = 0xfc;delayt(30);distance = VELOCITY_30C * distance / 20000;}/************************************************************** ****************//* 函数名称 : main *//* 函数描述 : 主函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void main(void){Beep = 0;rw = 0;initLCD();Init_MCU();Init_Parameter();Alarm(2);display_char(table,0x00);display_char(table0,0x40);Delay_xMs(30000);display_char(table2,0x00);display_char(table1,0x40);while(1){Trig_SuperSonic(); //触发超声波发射while(INPUT == 0) //等待回声{;}Measure_Distance(); //计算脉宽并转换为距离display_char(table3,0x40);display(distance,0x49); //显示距离Init_Parameter(); // 参数重新初始化delayt(100); //延时,两次发射之间要至少有10ms间隔}}/************************************************************** ****************//* 函数名称 : timer0 *//* 函数描述 : T0中断处理函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void timer0 (void) interrupt 1{TF0 = 0;TL0 = 0x66;TH0 = 0xfc;count++;if(count == 18)//超声波回声脉宽最多18ms{TR0 =0;TL0 = 0x66;TH0 = 0xfc;count = 0;}}/************************************************************** ****************/1602程序如下:/************************************宏定义************************************/#define uchar unsigned char#define uint unsigned int/************************************位定义************************************/sbit dula = P2^6;sbit wela = P2^7;sbit rs = P2^3;sbit rw = P2^4;sbit lcden = P2^5;/************************************************************** ****************//* 函数名称 : delay *//* 函数描述 : 延时函数 *//* 输入参数 : x *//* 参数描述 : 延时时间 *//* 返回值 : 无 *//************************************************************** ****************/void delay(uint x){uint a,b;for(a = x;a > 0;a--){for(b = 10;b > 0;b--){;}}}/************************************************************** ****************//* 函数名称 : write_com *//* 函数描述 : 1602写命令函数 *//* 输入参数 : com*//* 参数描述 : 控制命令 *//* 返回值 : 无 *//************************************************************** ****************/void write_com(uchar com){P0 = com;rs = 0;lcden = 0;delay(10);lcden = 1;delay(10);lcden = 0;}/************************************************************** ****************//* 函数名称 : write_date *//* 函数描述 : 1602写数据函数 *//* 输入参数 : date *//* 参数描述 : 要写入的数据 *//* 返回值 : 无 *//******************************************************************************/void write_date(uchar date){P0 = date;rs = 1;lcden = 0;delay(10);lcden = 1;delay(10);lcden = 0;}/************************************************************** ****************//* 函数名称 : initLCD *//* 函数描述 : 1602初始化函数 *//* 输入参数 : 无 *//* 参数描述 : 无 *//* 返回值 : 无 *//************************************************************** ****************/void initLCD(void){dula = 0;wela = 0;write_com(0x38);delay(20);write_com(0x0f);delay(20);write_com(0x06);delay(20);write_com(0x01);delay(20);}/************************************************************** ****************/51程序如下:#ifndef __REG51_H__#define __REG51_H__/* BYTE Register */ sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B;sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98; sfr SBUF = 0x99;/* BIT Register */ /* PSW */sbit CY = 0xD7; sbit AC = 0xD6; sbit F0 = 0xD5;sbit RS1 = 0xD4; sbit RS0 = 0xD3; sbit OV = 0xD2; sbit P = 0xD0;/* TCON */sbit TF1 = 0x8F; sbit TR1 = 0x8E; sbit TF0 = 0x8D; sbit TR0 = 0x8C; sbit IE1 = 0x8B; sbit IT1 = 0x8A; sbit IE0 = 0x89; sbit IT0 = 0x88;/* IE */sbit EA = 0xAF; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; sbit ET0 = 0xA9; sbit EX0 = 0xA8;/* IP */sbit PS = 0xBC; sbit PT1 = 0xBB; sbit PX1 = 0xBA; sbit PT0 = 0xB9; sbit PX0 = 0xB8;/* P3 */sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0;/* SCON */sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98;#endif。
C语言超声波测距程序 亲测可运行! 附代码数据

#include<reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit rs=P2^0; //1602的数据/指令选择控制线sbit rw=P2^1; //1602的读写控制线sbit en=P2^2; //1602的使能控制线sbit trig=P2^5; //超声波测距模块Trigsbit echo=P3^2; //超声波测距模块Echobit flag1; //触发信号标志位//uchar count; //中断累加变量long int distance; //测量所得距离unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字/*------------------------------------------------延时函数------------------------------------------------*/void delay(uint n){uint x,y;for(x=n;x>0;x--)for(y=110;y>0;y--);}/*------------------------------------------------延时函数------------------------------------------------*/void delayt(uint x){uchar j;while(x-- > 0){for(j = 0;j < 125;j++){;}}}/*------------------------------------------------1602写命令函数------------------------------------------------*/void lcd_wcom(uchar com){rs=0; //选择指令寄存器rw=0; //选择写P0=com; //把命令字送入P0delay(5); //延时一小会儿,让1602准备接收数据en=1; //使能线电平变化,命令送入1602的8位数据口,这点非常重要en=0;}/*------------------------------------------------1602写数据函数------------------------------------------------*/void lcd_wdat(uchar dat){rs=1; //选择数据寄存器rw=0; //选择写P0=dat; //把要显示的数据送入P0delay(5); //延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非常重要。
超声波C语言程序

功能:从串口发送一个数据包
入口参数:指向要发送的数据包地址
************************************************************************/
void Send_Bao( char *Data)
{
char j=0;
超声波测距C程序
#include<reg51.h>
#include"MAX485.h"
#define uint unsigned int
#define uchar unsigned char
long int time,l; /*时间*/
bit CLflag; /*测量标志*/
sbit Trig=P2^0; /*发射*/
{
/*外部中断0,用于检测接收信号*/
TR0=0; /*关闭定时器0 */
EX0=0; /*关中断*/
time=TL0;
time+=TH0*256;
l=time*ss;
l=l/2;
CLflag=1;
}
/********************主程序*************************/
TMOD=TMOD|0x20; //定时器T1工作在模式2,即八位自动重装模式
TH1=0xFD;
TL1=0xFD; //波特率为9600,在11.0592M的时钟下
TR1=1*********************************************************************
for(i=0;i<j;)
i++;
超声波测距C语言源程序代码

/*{HZ即单位s的倒数}本晶振为12MHZ,因此外部的时钟频率为12MHZ,所以部的时钟频率为(12MHZ)/12=1MH即1000000HZ,而机械频率为1/(1MHZ),即每完成一次计算(即定时器的值加一)用时0.000001s,即1us(微秒).*//***********************************************************************************///具有模式选择.*include<reg52.h>*define UC unsigned char*define UI unsigned intvoid delay(UI); //延时9.56us程序sbit beep = P1^3; //用于声音报警sbit Lv = P1^7; //用于光报警sbit Hong = P1^6;sbit QD = P3^7;//K8 //P3^7口(K8)为确定键,sbit G* = P3^1;//K7 //P3^3口(K2)为修改键,sbit S* = P3^6;//K6 //P3^2(K3)为测量键.sbit B* = P3^0;//K5 //个(K7),十(K6),百(K5),三位修改键sbit a = P1^2;//百位//数码管位选sbit b = P1^1;//十位sbit c = P1^0;//个位sbit trig = P1^4; //方波发射端sbit echo = P1^5; //超声波接收端void IntConfiguration(); //用来"设置中断"的函数,P3^3口(K2)为修改键,P3^2(K3)为测量键.void TimeConfiguration(); //用来"设置定时器"的函数sbit K1 = P3^4;//动态sbit K4 = P3^5;//静态//用于进展模式切换(K1、K4键)void *ia*ian(); //修改函数,用来修改下限void shang*ian(); //修改函数,用来修改上限UI min[3]={0,5,0}; //报警极限,拆分为"百十个"三位UI ma*[3]={3,0,0}; //MIN,MA* 用来存储最大和最小值void MIN*ianshi(UI); //最小围和最大围的显示void MA**ianshi(UI);UC code CharacterCode[10] = {0*3f,0*06,0*5b,0*4f,0*66,0*6d,0*7d,0*07,0*7f,0*6f};//数码管数字字符(P2口)/********************************主函数*********************************************/ void main(){TimeConfiguration(); //设置定时器0IntConfiguration(); //设置中断允许,K4键为修改键,K8键为确定键while(1){MIN*ianshi(40); //1.50169000sMA**ianshi(40); //1.50098300s}}/*******************************超声波测距函数********************************************/void zhongduan_0() interrupt 0 //测量中断函数(外部中断0){UI moshi = 0;UI juli = 0;UI time = 0;UI MA*, MIN;UI TT = 0;//用于第一次测量时给P1^5口置一,以便正确读取数值UI t1, t2, t3;UI GE = 0, SHI = 0, BAI = 0; //先定义三个变量,用来显示测量的距离.a = 0;b = 0;c = 0;P2 =~ 0*00; //防止最后显示的那个数码管一直亮MA* = ma*[0]*100 + ma*[1]*10 + ma*[2]; //计算最大与最小值MIN = min[0]*100 + min[1]*10 + min[2];while(1)//下面进展测量{while(1) /*先进展模式判断*/{if(0 == K1){moshi = 1;break; //模式1为动态测量}if(0 == K4){moshi = 2;break; //模式2为静态测量}if(0 == QD)return; //完毕测量函数}/********************************************计算距离************************************************/loop: beep = 1;//关掉定时器Lv = 1;Hong = 1;//关掉灯a = 0;b = 0;c = 0;P2 =~ 0*00;//防止最后显示的那个数码管一直亮if( (0 == QD)&&(1 == moshi) )break;if( (0 == QD)&&(2 == moshi) ){delay(55500);if(0 == QD){delay(55500);if(0 == QD)break;}}t1 = 35,t2 = 35;t3 = 35;trig = 0;echo = 0;delay(2); //初始化拉低两个端口trig = 1;delay(2);trig = 0; //输出端输出27us的高电压,并将输出端口拉低while(echo == 0); //判断是否有回波返回,有则开启定时器TR0 = 1; //当有高电平输出时,开启定时器while(echo == 1);TR0 = 0; //当高电平变成低电平时,关闭定时器++TT; //测量值加一,记录测量次数if(1 == TT){delay(55500);TH0 = 0*00;TL0 = 0*00; //定时器的初值,定时器的定时为65536us.goto loop;}time = TL0 + TH0*256; //接下来显示测量的距离TH0 = 0*00;TL0 = 0*00; //定时器的初值,定时器的定时为65536us.juli = ( int )( (time*0.034)/2 );BAI = ( (juli%1000)/100 ); SHI = ( (juli%100)/10 ); GE = ( juli%10 );/******************************************两种模式的距离显示********************************************/if(juli > MA*){Hong = 0;Lv = 1;while( t1-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(400);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(400);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(390);beep = 0;if( (1 == moshi)&&(0 == t1) )goto loop;if(moshi == 2){t1 = 2;if(0 == QD)goto loop;}}}else if(juli < MIN){Lv = 0;Hong = 1;while( t2-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(400);beep = 0;delay(100);beep = 1;if( (1 == moshi)&&(0 == t2) )goto loop;if(2 == moshi){t2 = 2;if(0 == QD)goto loop;}}}else{beep = 1;Lv = 1;Hong = 1;while( t3-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(600);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(600);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(600);if( (1 == moshi)&&(0 == t3) )goto loop;if(2 == moshi){t3 = 2;if(0 == QD)goto loop;}}}//显示完毕}}/***********************************************************************************/ void zhongduan_1() interrupt 1 //定时器溢出时的中断,显示测得的距离(定时器中断0){TH0 = 0*00;//定时器的初值,定时器的定时为65536us,TL0 = 0*00;}/***********************************************************************************/ void zhongduan_2() interrupt 2 //修改键(K4)的中断函数(外部中断1){*ia*ian();while(QD==0);shang*ian();}/**********************************************************************************/ void MIN*ianshi(UI TT) //显示最小距离{while(TT--){a = 0;b = 1;c = 1;P2 =~ CharacterCode[min[0]];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[min[1]];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[min[2]];delay(500);}P2 =~ 0*00;delay(55500);}void MA**ianshi(UI TT) //显示最大距离{while(TT--){a = 0;b = 1;c = 1;P2 =~ CharacterCode[ma*[0]];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[ma*[1]];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[ma*[2]];delay(500);}P2 =~ 0*00;delay(55500);}/***********************************************************************************/ void delay(UI T) //延时程序{while(T--);}/***********************************************************************************/ void IntConfiguration() //设置中断函数{//优先级设置PT2 = 0;PS = 0;PT1 = 0;P*1 = 0;PT0 = 1;P*0 = 0;IT1 = 1; //外部中断0为跳变沿触发E*1 = 1; //P3^3口(K4键)修改键,中断允许开启IT0 = 1; //外部中断1为跳变沿触发E*0 = 1; //P3^2口(K1键)测量键,中断允许开启ET0 = 1; //定时器0的中断允许开启EA = 1;}void TimeConfiguration() //设置定时器,以及定时器的初值{TMOD = 0*01;//设定只使用0号定时器; 模式:定时器; 工作方式:1号工作方式.//下面是定时器的初始值, TR0,TR1是用来开启定时器的TH0 = 0*00;//定时器的初值,定时器的定时为50us.TL0 = 0*00;/*1号定时器不用,所以没有TH1,TL1*/}/***********************************************************************************/ void *ia*ian() //修改下限{while(1){if(B*==0)//百位{P2=~0*00;min[0]++;if(min[0]==10)min[0]=0;delay(60000);}a = 0;b = 1;c = 1;P2 =~ CharacterCode[min[0]];delay(100);if(S*==0)//十位{P2=~0*00;min[1]++;if(min[1]==10)min[1]=0;delay(60000);}a = 1;b = 0;c = 1;P2 =~ CharacterCode[min[1]];delay(100);if(G*==0)//个位{P2=~0*00;min[2]++;if(min[2]==10)min[2]=0;delay(60000);}a = 1;b = 1;c = 0;P2 =~ CharacterCode[min[2]];delay(100);if(QD==0){a = 0;b = 0;c = 0;P2 = 0*ff;break;}}}void shang*ian() //修改上限{while(1){if(B*==0)//百位{P2=~0*00;ma*[0]++;if(ma*[0]==10)ma*[0]=0;delay(60000);}a = 0;b = 1;c = 1;P2 =~ CharacterCode[ma*[0]];delay(100);if(S*==0)//十位{P2=~0*00;ma*[1]++;if(ma*[1]==10)ma*[1]=0;delay(60000);}a = 1;b = 0;c = 1;P2 =~ CharacterCode[ma*[1]];delay(100);if(G*==0)//个位{P2=~0*00;ma*[2]++;if(ma*[2]==10)ma*[2]=0;delay(60000);}a = 1;b = 1;c = 0;P2 =~ CharacterCode[ma*[2]];delay(100);if(QD == 0){a = 0;b = 0;c = 0;P2 = 0*ff;while(QD == 0);break;}}}/************************************************************************************/。
单片机课程设计超声波测距设计代码注释

尊敬的读者:感谢您对本篇文章的关注和阅读。
在本篇文章中,我将为您介绍单片机课程设计中超声波测距设计代码的注释。
希望这些注释能够帮助您更好地理解超声波测距的原理和代码实现。
注释一:引入头文件```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后再次进行测距。
超声波C语言程序

#include"reg51.h"#include"intrins.h"#include"math.h"#define uchar unsigned char#define uint unsigned int#define Lcd_Data P0 //定义LCD数据端口//定义显示缓冲uchar code dispbuf[33]={"Temperature: `CDistance: mm "};uchar numcode[10]={'0','1','2','3','4','5','6','7','8','9'};uint num[29]={0};uchar jsh,jsl; //计数器的高低位uchar count=0; //10秒计次数uint distance; //距离sbit RS=P2^0; //LCD RSsbit RW=P2^1; //LCD RWsbit E =P2^2; //LCD Esbit Busy = P0^7; //LCD 忙uchar bdata flag; //DS18B20存在标准sbit DQ =P2^7; //DS18B20数字端口uint temp; //温度变量void delay(void); //延时函数void Init_LCD(void); //初始化LCDvoid Write_Comm(uchar); //写入LCD命令void Write_Data(uchar); //写入LCD数据void Read_Busy(void); //检查LCD是否忙void Init_18B20(void); //初始化18B20uchar ReadOneChar(void); //读取一个字节void WriteOneChar(uchar dat) ;//写入一个字节void testtemp(void); //启动温度转换,启动后750MS才能读取到温度uint wd(void); //读取温度void Delay(uint time); //延时函数sbit sta_flag =flag^0; //10MS到标准位sbit fuhao =flag^1; //温度的符号位sbit START =P1^0; //启动测距sbit CNT =P2^5; //发射超声波sbit CSBIN =P2^6; //返回信号sbit BUZZER=P3^7;void timer1(void) ;void delay1ms(void); //延时1MSvoid sys_init(void); //系统初始化void display(void); //显示函数void computer(void); //计算void hextobcd(void); //转换成BCDvoid bm(void); //求补码void delay15(uchar us); //延时15US/************************************************************************ 系统主函数*************************************************************************/ void main(void){uchar i,j;for(i=0;i<255;i++)for(j=0;j<255;j++); //延时sys_init(); //初始化display(); //显示sta_flag=0; //标准复位waitforstarting: //检测按键while(START);for(i=0;i<20;i++)delay1ms();if(START)goto waitforstarting;BUZZER=0; //蜂鸣器鸣音提升按键按下i=100000;while(i--);BUZZER=1;i=100000;while(i--);TR0=1; //启动定时器0ET0=1;testtemp(); //启动温度转换while(1){if(sta_flag) //10MS到了{while(0==CSBIN); //收到回波TR1=0;jsh=TH1;jsl=TL1;if(15==count) //900MS到检测温度{temp=wd(); //读取温度count=0;testtemp(); //重新启动转换display(); //刷新显示}computer(); //就算距离hextobcd(); //转换成BCD码sta_flag=0;}}}//******************定时器1溢出*************************** void timer1(void)interrupt 2 using 1{TR1=0;}/*****************************************************定时器0溢出中断函数,每60MS溢出*****************************************************/void timer0(void)interrupt 1 using 0{TH0=0x15;TL0=0xA0;TH1=0;TL1=0;sta_flag=1;count++;_nop_(); //开始发送40KHz的超声波_nop_();_nop_();_nop_();CNT=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();CNT=0;_nop_();_nop_();_nop_();_nop_();TR1=1;delay15(50); //延时避开直达信号}/****************************************************系统初始化*******************************************************/ void sys_init(void){uchar i;for(i=0;i<29;i++) //显示清零{ num[i]=0;}TMOD=0x11;TH0=0x15;TL0=0xA0;P0=0;CNT=0;CSBIN=1;EA=1;}/****************************************距离计算****************************************/void computer(void){float c,d,s;uint t;if(temp<0x8000) //温度为负c=331.4+0.61*temp*0.0625;elsec=331.4-0.61*temp*0.0625;t=jsh*256+jsl-120; //计算计数值d=(c*t*0.001)/2;d*=d;s=d-7.98;distance=sqrt(s); //修正后的值}/**************************************数据转换函数**************************************/void hextobcd(void){float tp;unsigned long int tmp;fuhao=0;if(temp<0x8000)tp=temp*0.0625;else //温度为负则求补码的到原码{bm();tp=temp*0.0625;fuhao=1;}tp*=10;tmp=tp;num[12]=tmp/100;if(fuhao)num[12]=num[12]|0x80; //加上符号位num[13]=tmp/10-(tmp/100)*10;tmp=distance;num[25]=tmp/1000;tmp%=1000;num[26]=tmp/100;tmp%=100;num[27]=tmp/10;tmp%=10;num[28]=tmp/1;}/*************************************温度转换函数*************************************//**************启动温度转换*************************/void testtemp(void){Init_18B20();//初始化18B20if(flag){WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换}}/***********读取温度函数**************/uint wd(void){unsigned int a = 0, b = 0, t = 0;Init_18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器a = ReadOneChar(); //读取字节b = ReadOneChar();t = b;t <<= 8;t = t | a;return (t);}/***************18B20复位函数**********************DS18B20复位函数*/void Init_18B20(void) //初始化18B20{DQ = 1; //DQ复位Delay(10);DQ = 0; //单片机将DQ拉低Delay(80); //480usDQ = 1; //拉高总线Delay(10);//稍做延时后如果x=0则初始化成功x=1则初始化失败if(DQ)flag=0;elseflag=1;Delay(20);/*******************读取一个字节******************************/ uchar ReadOneChar(void){uchar i = 0;uchar dat = 0;for (i = 8; i > 0; i--){DQ = 0; // 给脉冲信号dat >>= 1;DQ = 1; // 给脉冲信号if(DQ)dat |= 0x80; //拼装Delay(15);}return (dat);}/*********************写入一个字节****************************/ void WriteOneChar(unsigned char dat){unsigned char i = 0;for (i = 8; i > 0; i--){DQ = 0;DQ = dat&0x01;Delay(5);DQ = 1;dat>>=1;}}/********************************************对温度的转换,得到原码********************************************/void bm(void){temp=~temp;temp+=1;/***************************显示函数********************************/void display(void){{uchar a,b,d;Init_LCD();Write_Comm(0x01); //清显示Write_Comm(0x80); //写首地址for(a=0;a<16;a++){d=dispbuf[a];if((a>11)&&(a<14)) //如果是结果位到num[]里面读取{d=numcode[num[a]];}if(14==a) //显示°{d=0xdf;}Write_Data(d);}Write_Comm(0xc0); //--------------???????????for(b=16;b<33;b++){d=dispbuf[b];if((b>24)&&(b<29)){d=numcode[num[b]];}Write_Data(d);}}}void Read_Busy(void) //读忙信号判断{do{Lcd_Data = 0xff;RS = 0;RW = 1;E = 0;delay();E = 1;}while(Busy); //如果忙则等待}/*******************写指令函数******************************/ void Write_Comm(uchar lcdcomm){Lcd_Data = lcdcomm;RS = 0;RW = 0;E = 0;Read_Busy();E = 1;}/*********************写数据函数****************************/ void Write_Data(uchar lcddata)//写数据函数{Lcd_Data = lcddata;RS = 1;RW = 0;E = 0;Read_Busy(); //判断是否忙状态E = 1;}/*********************初始化LCD****************************/ void Init_LCD(void){delay();//稍微延时,等待LCD进入工作状态Write_Comm(0x01);//清显示// Write_Comm(0x02);//光标归位Write_Comm(0x38);//8位2行5*8Write_Comm(0x06);//文字不动,光标右移Write_Comm(0x0c);//显示开/关,光标开闪烁开// Write_Comm(0x18);//左移}/***************************延时n*15US函数****************************/void delay15(uchar us){do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();us--;}while(us);}/**********************************18b20延时函数*************************************/void Delay(uint time){while( time-- );}/****************************************************延时1MS*******************************************************/ void delay1ms(void){uchar i,j;for(i=0;i<2;i++)for(j=0;j<255;j++);}/****************************************显示延时函数*************************************/void delay(){uchar y;for(y=0;y<0xff;y++);}。
超声波测距C程序

#include<AT89X51.H>#include<intrins.h>/***************************数码管为共阴数码管***************************/sbit s0=P2^7;//个位选通sbit s1=P2^6;//十位选通sbit s2=P2^5;//百位选通sbit s3=P2^4;//千位选通sbit dp=P0^7;//小数点sbit in=P3^2;//外部中断,接CX20106的脚sbit csb=P3^3;//40KHz方波输出脚#define seg P0 //数码管的数据口为P1口#define uchar unsigned char#define uint unsigned int#define nop _nop_()/****************************/void init(void);//初始化void delay_nms(uint n);//延时nmsvoid delay100us();//延时usvoid display(uint dat);//4位数码管显示函数,只用了位void tran(void);//超声波测量函数/***************************/uint dis,H=100,L=20;uchar flag=0,high_time,low_time,m=0;uchar leddata[]={0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x77, //"A"0x7C, //"B"0x39, //"C"0x5E, //"D"0x79, //"E"0x71, //"F"0x76, //"H"0x38, //"L"0x37, //"n"0x3E, //"u"0x73, //"P"0x5C, //"o"0x40, //"-"0x00, //熄灭0x00 //自定义};void delay100us(){uchar i;for(i=0;i<50;i++);}/********************************** 函数名称:主函数修改日期:入口参数:无返回值: 无**********************************/ void main(void){init();while(1) //循环测量并显示{tran();//发送超声波信号测距display(dis);//显示距离}}/********************************** 函数名称:初始化函数修改日期:入口参数:无返回值: 无**********************************/ void init(void){TMOD=0x01;//定时器方式用于计时TH0=0;TL0=0; /* 设定T0的工作模式为*/EA=1;IT0=1;//下降沿有效,左传感器}/********************************** 函数名称:延时函数修改日期:入口参数:n返回值: 无**********************************/ void delay_nms(uint n){uchar i;while(n--){for(i=123;i>0;i--);}}/********************************** 函数名称:显示函数修改日期:入口参数:data返回值: 无**********************************/ void display(uint dat){uchar i,j,k;//分别为百十个位的缓存i=dat/100;//百位j=dat%100/10;//十位k=dat%100%10;//个位s3=1;s2=0;s1=1;s0=1;seg=~leddata[i];dp=0;delay_nms(2);dp=1;s2=1;s3=1;s2=1;s1=0;s0=1;seg=~leddata[j];delay_nms(2);s1=1;s3=1;s2=1;s1=1;s0=0;seg=~leddata[k];delay_nms(2);s0=1;}/**********************************函数名称:超声波测量函数修改日期:入口参数:无返回值: 无**********************************/ void tran(void){uchar i;float temp;TH0=0;TL0=0;//清定时TR0=1;//开定时for(i=8;i>0;i--){csb=!csb;nop;nop;nop;nop;nop;nop;nop;nop;nop;}csb=1;delay_nms(1);EX0=1;//开中断if(flag==1) //中断标志位置,说明有回波{ //以下为路程计算temp=high_time*256+low_time;temp=(temp/1000)/2;temp*=340;temp=temp/10;dis=(unsigned int)temp;flag=0;}}/********************************** 函数名称:中断函数修改日期:入口参数:无返回值: 无**********************************/void TT() interrupt 0{uint tmp;TR0=0;//关定时器ET0=0;//关外部中断flag=1; //置位标志位tmp=TH0*256+TL0; //读取定时器的值if((tmp>0)&&(tmp<60000))//判断是否超出范围,此设置的范围为到米,实际不能达到米{high_time=TH0;//把计时值放入缓冲low_time=TL0;}else//超出范围则重新测量{high_time=0;low_time=0;}}。
单片机源代码-超声波测距

_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;//那么蜂鸣器不发声
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*{HZ即单位s的倒数}本晶振为12MHZ,因此外部的时钟频率为12MHZ,所以内部的时钟频率为(12MHZ)/12=1MH即1000000HZ,而机械频率为1/(1MHZ),即每完成一次计算(即定时器的值加一)用时0.000001s, 即1us(微秒).*//****************************************************************************** *****///具有模式选择.#include<reg52.h>#define UC unsigned char#define UI unsigned intvoid delay(UI); //延时9.56us程序sbit beep = P1^3; //用于声音报警sbit Lv = P1^7; //用于光报警sbit Hong = P1^6;sbit QD = P3^7;//K8 //P3^7口(K8)为确定键,sbit GX = P3^1;//K7 //P3^3口(K2)为修改键,sbit SX = P3^6;//K6 //P3^2(K3)为测量键.sbit BX = P3^0;//K5 //个(K7),十(K6),百(K5),三位修改键sbit a = P1^2;//百位//数码管位选sbit b = P1^1;//十位sbit c = P1^0;//个位sbit trig = P1^4; //方波发射端sbit echo = P1^5; //超声波接收端void IntConfiguration(); //用来"设置中断"的函数,P3^3口(K2)为修改键,P3^2(K3)为测量键.void TimeConfiguration(); //用来"设置定时器"的函数sbit K1 = P3^4;//动态sbit K4 = P3^5;//静态//用于进行模式切换(K1、K4键)void xiaxian(); //修改函数,用来修改下限void shangxian(); //修改函数,用来修改上限UI min[3]={0,5,0}; //报警极限,拆分为"百十个"三位UI max[3]={3,0,0}; //MIN,MAX 用来存储最大和最小值void MINxianshi(UI); //最小范围和最大范围的显示void MAXxianshi(UI);UC code CharacterCode[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管数字字符(P2口)/********************************主函数*********************************************/void main(){TimeConfiguration(); //设置定时器0IntConfiguration(); //设置中断允许,K4键为修改键,K8键为确定键while(1){MINxianshi(40); //1.50169000sMAXxianshi(40); //1.50098300s}}/*******************************超声波测距函数********************************************/void zhongduan_0() interrupt 0 //测量中断函数(外部中断0){UI moshi = 0;UI juli = 0;UI time = 0;UI MAX, MIN;UI TT = 0;//用于第一次测量时给P1^5口置一,以便正确读取数值UI t1, t2, t3;UI GE = 0, SHI = 0, BAI = 0; //先定义三个变量,用来显示测量的距离.a = 0;b = 0;c = 0;P2 =~ 0x00; //防止最后显示的那个数码管一直亮MAX = max[0]*100 + max[1]*10 + max[2]; //计算最大与最小值MIN = min[0]*100 + min[1]*10 + min[2];while(1)//下面进行测量{while(1) /*先进行模式判断*/{if(0 == K1){moshi = 1;break; //模式1为动态测量}if(0 == K4){moshi = 2;break; //模式2为静态测量}if(0 == QD)return; //结束测量函数}/********************************************计算距离************************************************/loop: beep = 1;//关掉定时器Lv = 1;Hong = 1;//关掉灯a = 0;b = 0;c = 0;P2 =~ 0x00;//防止最后显示的那个数码管一直亮if( (0 == QD)&&(1 == moshi) )break;if( (0 == QD)&&(2 == moshi) ){delay(55500);if(0 == QD){delay(55500);if(0 == QD)break;}}t1 = 35,t2 = 35;t3 = 35;trig = 0;echo = 0;delay(2); //初始化拉低两个端口trig = 1;delay(2);trig = 0; //输出端输出27us的高电压,并将输出端口拉低while(echo == 0); //判断是否有回波返回,有则开启定时器TR0 = 1; //当有高电平输出时,开启定时器while(echo == 1);TR0 = 0; //当高电平变成低电平时,关闭定时器++TT; //测量值加一,记录测量次数if(1 == TT){delay(55500);TH0 = 0x00;TL0 = 0x00; //定时器的初值,定时器的定时为65536us.goto loop;}time = TL0 + TH0*256; //接下来显示测量的距离TH0 = 0x00;TL0 = 0x00; //定时器的初值,定时器的定时为65536us.juli = ( int )( (time*0.034)/2 );BAI = ( (juli%1000)/100 ); SHI = ( (juli%100)/10 ); GE = ( juli%10 );/******************************************两种模式的距离显示********************************************/if(juli > MAX){Hong = 0;Lv = 1;while( t1-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(400);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(400);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(390);beep = 0;if( (1 == moshi)&&(0 == t1) )goto loop;if(moshi == 2){t1 = 2;if(0 == QD)goto loop;}}else if(juli < MIN){Lv = 0;Hong = 1;while( t2-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(400);beep = 0;delay(100);beep = 1;if( (1 == moshi)&&(0 == t2) )goto loop;if(2 == moshi){t2 = 2;if(0 == QD)goto loop;}}}else{beep = 1;Hong = 1;while( t3-- ){a = 0;b = 1;c = 1;P2 =~ CharacterCode[BAI];delay(600);a = 1;b = 0;c = 1;P2 =~ CharacterCode[SHI];delay(600);a = 1;b = 1;c = 0;P2 =~ CharacterCode[GE];delay(600);if( (1 == moshi)&&(0 == t3) )goto loop;if(2 == moshi){t3 = 2;if(0 == QD)goto loop;}}}//显示结束}}/****************************************************************************** *****/void zhongduan_1() interrupt 1 //定时器溢出时的中断,显示测得的距离(定时器中断0) {TH0 = 0x00;//定时器的初值,定时器的定时为65536us,TL0 = 0x00;}/****************************************************************************** *****/void zhongduan_2() interrupt 2 //修改键(K4)的中断函数(外部中断1){xiaxian();while(QD==0);shangxian();}/****************************************************************************** ****/void MINxianshi(UI TT) //显示最小距离{while(TT--){a = 0;b = 1;c = 1;P2 =~ CharacterCode[min[0]];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[min[1]];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[min[2]];delay(500);}P2 =~ 0x00;delay(55500);}void MAXxianshi(UI TT) //显示最大距离{while(TT--){a = 0;b = 1;c = 1;P2 =~ CharacterCode[max[0]];delay(500);a = 1;b = 0;c = 1;P2 =~ CharacterCode[max[1]];delay(500);a = 1;b = 1;c = 0;P2 =~ CharacterCode[max[2]];delay(500);}P2 =~ 0x00;delay(55500);}/****************************************************************************** *****/void delay(UI T) //延时程序{while(T--);}/****************************************************************************** *****/void IntConfiguration() //设置中断函数{//优先级设置PT2 = 0;PS = 0;PT1 = 0;PX1 = 0;PT0 = 1;PX0 = 0;IT1 = 1; //外部中断0为跳变沿触发EX1 = 1; //P3^3口(K4键)修改键,中断允许开启IT0 = 1; //外部中断1为跳变沿触发EX0 = 1; //P3^2口(K1键)测量键,中断允许开启ET0 = 1; //定时器0的中断允许开启EA = 1;}void TimeConfiguration() //设置定时器,以及定时器的初值{TMOD = 0x01;//设定只使用0号定时器; 模式:定时器; 工作方式:1号工作方式.//下面是定时器的初始值, TR0,TR1是用来开启定时器的TH0 = 0x00;//定时器的初值,定时器的定时为50us.TL0 = 0x00;/*1号定时器不用,所以没有TH1,TL1*/}/****************************************************************************** *****/void xiaxian() //修改下限{while(1){if(BX==0)//百位{P2=~0x00;min[0]++;if(min[0]==10)min[0]=0;delay(60000);}a = 0;b = 1;c = 1;P2 =~ CharacterCode[min[0]];delay(100);if(SX==0)//十位{P2=~0x00;min[1]++;if(min[1]==10)min[1]=0;delay(60000);}a = 1;b = 0;c = 1;P2 =~ CharacterCode[min[1]];delay(100);if(GX==0)//个位{P2=~0x00;min[2]++;if(min[2]==10)min[2]=0;delay(60000);}a = 1;b = 1;c = 0;P2 =~ CharacterCode[min[2]];delay(100);if(QD==0){a = 0;b = 0;c = 0;P2 = 0xff;break;}}}void shangxian() //修改上限{while(1){if(BX==0)//百位{P2=~0x00;max[0]++;if(max[0]==10)max[0]=0;delay(60000);}a = 0;b = 1;c = 1;P2 =~ CharacterCode[max[0]];delay(100);if(SX==0)//十位{P2=~0x00;max[1]++;if(max[1]==10)max[1]=0;delay(60000);}a = 1;b = 0;c = 1;P2 =~ CharacterCode[max[1]];delay(100);if(GX==0)//个位{P2=~0x00;max[2]++;if(max[2]==10)max[2]=0;delay(60000);}a = 1;b = 1;c = 0;P2 =~ CharacterCode[max[2]];delay(100);if(QD == 0){a = 0;b = 0;c = 0;P2 = 0xff;while(QD == 0);break;}}}/****************************************************************************** ******/11 / 11。