超声波模块程序
PIC18F4520单片机超声波测距主要部分程序
PIC18F4520单片机超声波测距主要部分程序测试环境:MPLAB IDE v8.73a单片机型号:PIC18F4520所需器件:超声波模块电路连接图如下:超声波测距子函数:unsigned int chaosheng(){unsigned int temp1,temp2;//定义两个无符号整型的变量用于存储距离值INPUT = 1;delay(50);//延时INPUT = 0;while(!OUTPUT);//当超声波的输出引脚输出高电平时,打开定时器0,开始计时TMR1ON = 1;while(OUTPUT);//当超声波的输出引脚输出低电平时,关闭定时器0,停止计时TMR1ON = 0;//计算超声波测出的距离temp1 = TMR1L;//将TMR1的低8位赋值给temp1变量temp2 = TMR1H;//将TMR1的高8位赋值给temp2变量temp2 = (temp2 << 8) + temp1;//temp2左移8位,加上temp1TMR1H = 0;//TMR1的高8位清零,为下一次测距做准备TMR1L = 0;//TMR1的低8位清零,为下一次测距做准备//距离 = 时间/2 * 速度//距离:distance;时间:temp2/2单位为μs;速度:340m/s//这里注意下单位,需要进行换算让最终距离的单位为cm/sdistance = temp2 * 1.7/100;//有一定的误差,可以软件填补误差,根据实测值,在右侧的表达式上加减一误差数值。
return distance;//返回超声波测得的距离值,这里的distance为全局变量,可以在其他程序中用到,例如液晶显示部分,可以作为实参传递给其对应程序,用于显示。
}最后:很欣赏Google的面试题:用3句话向老太太讲清楚什么是数据库。
乔布斯说:“最好的东西就是关注简单”,因为简单的东西比复杂的东西更难做到。
HC-SR04 超声波模块 DEMO 程序(淳修良)
unsigned int time=0;
unsigned int timer=0;
float S=0;
bit flag =0;
/********************************************************/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.87)/100; //算出来是CM
if(flag==1) //超出测量
{
flag=0;
printf("-----\n");
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
delayms(100); //100MS
}
}
/***********************************************************************************************************/
//HC-SR04 超声波测距模块 DEMO 程序
//晶振:11。0592
//程序
TH1=0xFD;
TL1=0xFD;
TH0=0;
TL0=0;
TR0=1;
ET0=1; //允许T0中断
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
KS103超声波测距模块说明书
工作电压:3.0V~5.5V 直流电源 工作时瞬间最大电流:10.6mA@5.0V, typical 工作电流:1.6-2.7 mA@5.0V, typical 休眠时最大耗电量:500uA@5.0V, typical (串口模式时不休眠) 功耗:使用纳瓦技术省电,5s 未收到 I2C 控制指令自动进入 uA 级休眠,并可随时被主机 I2C 控
位
I2C
(4)
数据。
Note 4: 这种总线钳制探测方式可以为客户获得更大的探测速度及效率,而不是通过定时器延时或 delay 函数延时每次探测都要至少等
待 65ms。换言之,用户大部分时候仅需要快速知晓 1m 范围内是否有障碍物。具体延时时间应大于表 1 所列各指令的最大探测时间。
如果不希望 SCL 线在探测时被拉低,可以通过发送指令 0xc3 指令,之后断电重启 KS101B/KS103/KS103S 后 SCL 线仍然不会拉低。如果想恢复 I2C 钳制及 SCL 拉低功能,发送
Note 1: 要达到最佳的工作状态推荐使用+5V 电源,低于 5V 的电压将影响测距量程。并且,严禁将 VCC 与 GND 接反,否则可能会
损坏电路。超过 3 秒钟的电路反接将可能导致不可恢复的损坏。
具体连线如下图所示(20 个):
VCC VCC
R1
R2
4.7K
4.7K
VCC SDA SCL GND
I2C 地址
寄存器 2
8 位数据指令
延时等待或查询 SCL
否
线是否为高?
3
是
接收 16 位 I2C 数据
多量程探测 探测指令从 0x01 到 0x2f,数值越大,信号增益越大。指令 0x01 对应量程约 100mm,0x02
超声波测距模块+程序
#include <intrins.h>
#define RX P0_1
#defineTX P0_2
unsigned int time=0;
unsigned int timer=0;
unsigned char posit=0;
unsigned long S=0;
TH0=0;
TL0=0;
TH1=0xf8;//2MS定时
TL1=0x30;
ET0=1; //允许T0中断
ET1=1;//允许T1中断
TR1=1;//开启定时器
EA=1;//开启总中断
while(1)
{
while(!RX);//当RX为零时等待
TR0=1;//开启计数
while(RX);//当RX为1计数并等待
bit flag =0;
unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
unsigned charconst positon[3]={ 0xdf,0xef,0xf7};
unsigned char disbuff[4]={ 0,0,0,0,};
/********************************************************/
void Display(void)//扫描数码管
{
if(posit==0)
{P1=(discode[disbuff[posit]])&0x7f;}
//程序QQ:517535000
超声波模块HC-SR04简介以及编程
超声波模块HC-SR04简介以及编程1、本模块性能稳定,测度距离精确,模块高精度,盲区小。
产品应用领域:机器人避障物体测距液位检测公共安防停车场检测。
2、主要技术参数:1:使用电压:DC---5V2:静态电流:小于2mA3:电平输出:高5V4:电平输出:底0V5:感应角度:不大于15度6:探测距离:2cm-450cm7:高精度可达0.2cm实物图接线方式:VCC、trig(控制端)、 echo(接收端)、GND基本工作原理:(1)采用IO口TRIG触发测距,给至少10us的高电平信号;(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
测试距离=(高电平时间*声速(340M/S))/2; 本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以达到你移动测量的值5、操作:初始化时将trig和echo端口都置低,首先向给trig 发送至少10 us的高电平脉冲(模块自动向外发送8个40K的方波),然后等待,捕捉echo端输出上升沿,捕捉到上升沿的同时,打开定时器开始计时,再次等待捕捉echo的下降沿,当捕捉到下降沿,读出计时器的时间,这就是超声波在空气中运行的时间,按照测试距离=(高电平时间*声速(340M/S))/2 就可以算出超声波到障碍物的距离。
6、下面是飞思卡尔XS128单片机测距的程序:while(1){PT1AD0_PT1AD00 = 1;//给超声波模块输入高脉冲PITINTE_PINTE1=1; //打开PIT1定时器while(!(counter0>=4)); //等待20usPITINTE_PINTE1=0;counter0 = 0;//关闭定时器,计数清零PT1AD0_PT1AD00 = 0; //trig管脚拉低PORTB_PB0 = 0; //指示灯0while(!(PT1AD0_PT1AD01 == 1)); //等待echo输出上升沿PORTB_PB1 = 0; //指示灯1PITINTE_PINTE0=1; //打开PIT0定时器while(!(PT1AD0_PT1AD01 == 0)); //等待下降沿distance = counter*17/20; //计算距离,单位CMPITINTE_PINTE0=0; //关闭定时器PORTB_PB2 = 0; //指示灯2PITINTE_PINTE0=1; //打开定时器定时500ms,数码管显示 while(!(counter>=10000)){Showing(distance); //显示距离,精确1cm}PITINTE_PINTE0=0;counter=0; //关闭定时器,清零 }。
超声波模块HC-SR04
//超声波模块HC-SR04显示程序#include <reg52.h> //包括一个52标准内核的头文件#define uchar unsigned char //定义一下方便使用#define uint unsigned int#define ulong unsigned longsbit Tx = P3^2; //产生脉冲引脚sbit Rx = P3^3; //回波引脚uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共阳数码管0-9 uint distance[4]; //测距接收缓冲区//收集4次测量以便取平均值uchar ge,shi,bai,qian,temp,flag,outcomeH,outcomeL,i; //自定义变量bit succeed_flag; //测量成功标志//********函数声明void delay_20us(){ uchar bt ;for(bt=0;bt<60;bt++);}//外部中断1,用做判断回波电平INT1_() interrupt 2 // 外部中断是2号{outcomeH =TH1; //取出定时器的值outcomeL =TL1; //取出定时器的值succeed_flag=1; //置成功测量的标志EX1=0; //关闭外部中断}//****************************************************************//定时器0中断,用做显示timer0() interrupt 1 // 定时器0中断是1号{TH0=0xfd; //写入定时器0初始值TL0=0x77;switch(flag){case 0x00:P0=ge; P2=0xef;flag++;break;case 0x01:P0=shi;P2=0xdf;flag++;break;case 0x02:P0=bai;P2=0xbf;flag++;break;case 0x03:P0=qian;P2=0x7f;flag=0;break;}}//显示数据转换程序void conversion(uint temp_data){EA=0; //计算前关闭总中断ge=temp_data%10; //除以10取余数得个位shi=temp_data/10%10; //除以10,小数点左移1位,再除以10取余数得十位bai=temp_data/100%10; //除以100,小数点左移2位,再除以10取余数得百位qian=temp_data/1000%10; //除以1000,小数点左移3位,再除以10取余数得千位//上面计算数值//下面查表qian=SEG7[qian]; //查询共阳数码管对应元素的值bai=SEG7[bai]; //查询共阳数码管对应元素的值shi=SEG7[shi]&0x7F;//此处并接小数点//查询共阳数码管对应元素的值,这里合并上小数点ge=SEG7[ge]; //查询共阳数码管对应元素的值,前三位是厘米,这一位代表毫米EA=1; //计算结束开启总中断}//******************************************************************void main(void) // 主程序{float distance_data; //定义一个浮点类型的变量i=0; //指针值i为零,即数组SEG7[0] ,第一个元素flag=0;//标志值,赋值为0Tx=0; //首先拉低脉冲输入引脚,做好提供20微秒高电平的准备TMOD=0x11; //两个定时器都要工作,定时器0,定时器1,16位工作方式,可以长时间计时TR0=1;//启动定时器0,以便于显示IT1=0; //中断触发方式:由高电平变低电平,引发外部中断,常讲的“下降沿触发”ET0=1; //打开定时器0中断,每个位按定设定的时间显示,被中断了就显示下一位。
超声波测距程序_代码全
/*----------------------------------超声波子程序1、采用定时器0产生40KHZ的方波,同时也进行时间计数,等待中断;2、若超过30ms后,重新发送方波,重新计数,直到有中断(接收到返回信号)再做显示或其它处理。
3、在处理之后又后重新初始化定器0和中断0,又执行第一步------------------------------------*/#include <reg52.h>//1602已定义了#include "1602.h"#include "delay.h"#include <stdio.h>//包含sprintf函数sbitpwm=P3^7;//40KHZsbit led=P1^3;//接收到后亮灯unsigned intnum=0;//计数float s; //测出的距离bit flag=0;//中断0标志位unsigned char out_time=0;//超时标志位/*---------------------------------------定时器0用于产生40KHZ频率初始化---------------------------------------*/void T0_init(){TMOD=0X02; //定时器0工作在方式2,自动重装数据TL0=256-12; //产生40KHZTH0=256-12; //T=1/40k*1000000=25us即12.5us取反一次EA=1;ET0=1;TR0=1;}/*--------------------------------定时器0中断服务程序//用于工作计时、同时产生40KHZ方波---------------------------------*/void T0_time() interrupt 1{num++;if(num<30) pwm=~pwm;//产生15个40KHZ的方波if(num==2500) {num=0;out_time++;}//30ms后清除标志,同时}/*-----------------------------外部中断0初始化------------------------------*/void INT0_init(){IT0=1;//低电平触发方式EX0=1;//打开外部中断// PX0=1;//外部中断0为高优先级}/*-----------------------------外部中断0中断服务程序------------------------------*/void INT0_d() interrupt 0{EX0=0; //当中断了,证明接收到信号,关闭外断中断TR0=0; //关闭定时器0flag=1; //标志外部中断0产生}/*-------------------------------超声波测距函数//s的值为返回测距值--------------------------------*/void measure(){if(flag==1) //中断0标志,进入{flag=0; //清除标志位out_time=0; //清除超时标志位led=~led; //观察DelayMs(100); //延时,**适用STC12C5A60S2,低速单片机,要减少延时**s=(num*12)/2*0.34*0.001;//测距返回值TH0=256-12; //定时器0重新初始化TL0=256-12;TR0=1; //运行定时器0INT0_init(); //启动外部中断0}}/*-------------------------------超声波显示部分--------------------------------*/void display(){char displaytemp[16];//定义显示区域临时存储数组if(out_time==33) //大约1s的超时时间,再将显示为0.000{out_time=0; //清除标志位s=0; //显示0}sprintf(displaytemp,"distance:% 6.3f",s);//将数字转成字符串LCD_Write_String(0,1,displaytemp);//显示}//*********************主程序***********************//void main(){LCD_Init(); //1602初始化LCD_Clear(); //清屏T0_init(); //定时器0初始化INT0_init(); //启动外部中断0while(1){measure(); //超声波测距函数display(); //显示}}附链接文件程序:/* 1602.c *//*-----------------------------------------------名称:LCD1602引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<intrins.h>#include "1602.h"#include "delay.h"sbit RS = P2^6; //定义端口sbit RW = P2^5;sbit EN = P2^7;#define RS_CLR RS=0#define RS_SET RS=1#define RW_CLR RW=0#define RW_SET RW=1#define EN_CLR EN=0#define EN_SET EN=1#define DataPort P0/*------------------------------------------------判忙函数------------------------------------------------*/ bitLCD_Check_Busy(void){DataPort= 0xFF;RS_CLR;RW_SET;EN_CLR;_nop_();EN_SET;return (bit)(DataPort& 0x80);}/*------------------------------------------------写入命令函数------------------------------------------------*/ voidLCD_Write_Com(unsigned char com) {while(LCD_Check_Busy()); //忙则等待RS_CLR;RW_CLR;EN_SET;DataPort= com;_nop_();EN_CLR;}/*------------------------------------------------写入数据函数------------------------------------------------*/ voidLCD_Write_Data(unsigned char Data){while(LCD_Check_Busy()); //忙则等待RS_SET;RW_CLR;EN_SET;DataPort= Data;_nop_();EN_CLR;}/*------------------------------------------------清屏函数------------------------------------------------*/voidLCD_Clear(void){LCD_Write_Com(0x01);DelayMs(5);}/*------------------------------------------------写入字符串函数------------------------------------------------*/voidLCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) {if (y == 0){LCD_Write_Com(0x80 + x); //表示第一行}else{LCD_Write_Com(0xC0 + x); //表示第二行}while (*s){LCD_Write_Data( *s);s ++;}}/*------------------------------------------------写入字符函数------------------------------------------------*//* void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) {if (y == 0){LCD_Write_Com(0x80 + x);}else{LCD_Write_Com(0xC0 + x);}LCD_Write_Data( Data);}*//*------------------------------------------------初始化函数------------------------------------------------*/voidLCD_Init(void){LCD_Write_Com(0x38); /*显示模式设置*/DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);LCD_Write_Com(0x08); /*显示关闭*/LCD_Write_Com(0x01); /*显示清屏*/LCD_Write_Com(0x06); /*显示光标移动设置*/DelayMs(5);LCD_Write_Com(0x0C); /*显示开及光标设置*/}/* 1602.h *//*-----------------------------------------------名称:LCD1602.h引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK ------------------------------------------------*/#ifndef __1602_H__#define __1602_H__bitLCD_Check_Busy(void) ;voidLCD_Write_Com(unsigned char com) ;voidLCD_Write_Data(unsigned char Data) ;voidLCD_Clear(void) ;voidLCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ; voidLCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) ; voidLCD_Init(void) ;#endif/* delay.c*/#include "delay.h"/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned int t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/voidDelayMs(unsigned int t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/* delay.h*/#ifndef __DELAY_H__#define __DELAY_H__/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned int t);/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/voidDelayMs(unsigned int t);#endif。
超声波程序
本人收藏的的一些超声波程序,希望对大家有用(还有原理图,需要的话去我空间去下):程序一:#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; // 编码字节缓存变量uchar i,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2;// 延时用的循环变量uint distance,distance1,time; /距/ 离,timesbit IRsignal=P3T; //HS0038 接收头OUT 端直接连P3.2(INT0)sbit come=P3A3;sbit d=P1A1;// 发送码sbit BZ=P1A0;sbit s=P3A7;//38ksbit ss=P3A6;//38k uchar m;// 开关控制codeunsignedchar定时器 0 中断************************/ 延时0.9ms 子程序延时1ms 子程序//sbit n=P2;// 电机反转Seg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28显示段码void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;S=~S;// 产生 38K 信号SS=~SS;//tt++;// 发送超声波个数void Delay0_9mS(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}}void Delay1ms(void)延时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) // 延时程序uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);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]]; //取出千位数,查表,输出。
超声波模块的工作原理
超声波模块的工作原理
超声波模块是一种常用的测距和避障设备。
其工作原理是利用超声波的传播特性进行测距,从而实现距离的测量和障碍物的检测。
超声波模块通常由发射器和接收器组成。
发射器通过电信号激励压电陶瓷晶片产生超声波信号,并向周围空间发射出去。
当超声波遇到物体时,会发生声波的反射。
反射的声波会被接收器接收到,并通过信号处理电路进行处理。
接收器部分的工作原理是将接收到的超声波信号转化为电信号。
当超声波信号被接收到时,压电陶瓷晶片会产生电压信号。
这个电压信号经过放大和滤波处理后,可以输出给后续的电子设备进行距离测量或障碍物检测。
超声波的传播速度是已知的,因此可以利用发射和接收到超声波的时间差来计算距离。
通常,超声波模块会测量从发射器发射超声波到接收器接收到反射超声波的时间间隔。
通过将时间间隔乘以超声波的传播速度,即可得到距离的估计值。
此外,超声波模块还可以通过测量接收到的超声波信号的强度来识别相对强度的障碍物。
根据反射超声波信号的强弱,可以推断出距离模块的距离和障碍物的大致大小。
这对于避障和环境感知等应用非常有用。
总结来说,超声波模块利用超声波的传播特性实现距离的测量和障碍物的检测。
通过发射器产生超声波信号,接收器接收并
处理反射的超声波信号,最终利用时间差和信号强度来计算距离和检测障碍物。
cx20106a超声波程序(正确)
void xianshi(unint qian,unint bai,unint shi,unint ge);
void chushihua();
void delay(void);
unchar code table[]={
{
qian=tempp/1000; //把数的千位分离出来
bai=tempp%1000/100; //把数的百位分离出来
shi=tempp%100/10; //把数的十位分离出来
ge=tempp%10; //把数的个位分离出来
P2=0xfe;
{
chushihua(); //初始化程序
while(1) //使程序进入死循环
{
fa=1;
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
P0=table[qian];
delay1(1);
P2=0xfd;
P0=table[bai];
delay1(1);
P2=0xfb;
P0=table[shi];
delay1(1);
P2=0xf7;
#include <reg52.h> #inclu源自e<intrins.h>
#define unchar unsigned char //定义两个全局变量
#define unint unsigned int
sbit fa=P1^0; //位申明
hcsr04超声波模块工作频率
hcsr04超声波模块工作频率
摘要:
1.HCSR04超声波模块简介
2.HCSR04超声波模块的工作原理
3.HCSR04超声波模块的引脚功能
4.HCSR04超声波模块的使用注意事项
正文:
HCSR04超声波模块是一款常用的测距模块,具有高精度、盲区超近、稳定测距等特点。
它的工作电压为DC 5V,工作电流为15ma,工作频率为
40kHz。
最远射程可达4m,最近射程为2cm,测量角度为15度。
HCSR04超声波模块的工作原理如下:首先,给超声波模块接入电源和地,然后给脉冲触发引脚(trig)输入一个长为20us的高电平方波。
输入方波后,模块会自动发射8个40khz的声波,与此同时回波引脚echo端的电平会由0变为1。
当超声波返回被模块接收到时,回波引脚端的电平会由1变为0,此时应停止定时器计数。
定时器记录的时间就是超声波从发射到返回的时间,根据这个时间可以计算出距离。
HCSR04超声波模块的引脚功能如下:VCC接5V电源,GND接地线,TRIG接脉冲触发信号,ECHO接回响信号。
在使用HCSR04超声波模块时,有一些注意事项:
1.确保模块工作电压稳定,避免电压波动影响测量精度。
2.避免模块长时间连续工作,以免过热损坏。
3.确保触发引脚和回响引脚的连接稳定,避免信号干扰。
4.在测量过程中,保持探头清洁,避免灰尘或污垢影响测量结果。
5.探头应垂直于被测物体,避免因角度不准确导致测量误差。
超声波测距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 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;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 = 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;}}}/****************************************************************************** ******/。
超声波测距程序_代码全
/*----------------------------------超声波子程序1、采用定时器0产生40KHZ的方波,同时也进行时间计数,等待中断;2、若超过30ms后,重新发送方波,重新计数,直到有中断(接收到返回信号)再做显示或其它处理。
3、在处理之后又后重新初始化定器0和中断0,又执行第一步------------------------------------*/#include <reg52.h>//1602已定义了#include "1602.h"#include "delay.h"#include <stdio.h>//包含sprintf函数sbitpwm=P3^7;//40KHZsbit led=P1^3;//接收到后亮灯unsigned intnum=0;//计数float s; //测出的距离bit flag=0;//中断0标志位unsigned char out_time=0;//超时标志位/*---------------------------------------定时器0用于产生40KHZ频率初始化---------------------------------------*/void T0_init(){TMOD=0X02; //定时器0工作在方式2,自动重装数据TL0=256-12; //产生40KHZTH0=256-12; //T=1/40k*1000000=25us即12.5us取反一次EA=1;ET0=1;TR0=1;}/*--------------------------------定时器0中断服务程序//用于工作计时、同时产生40KHZ方波---------------------------------*/void T0_time() interrupt 1{num++;if(num<30) pwm=~pwm;//产生15个40KHZ的方波if(num==2500) {num=0;out_time++;}//30ms后清除标志,同时}/*-----------------------------外部中断0初始化------------------------------*/void INT0_init(){IT0=1;//低电平触发方式EX0=1;//打开外部中断// PX0=1;//外部中断0为高优先级}/*-----------------------------外部中断0中断服务程序------------------------------*/void INT0_d() interrupt 0{EX0=0; //当中断了,证明接收到信号,关闭外断中断TR0=0; //关闭定时器0flag=1; //标志外部中断0产生}/*-------------------------------超声波测距函数//s的值为返回测距值--------------------------------*/void measure(){if(flag==1) //中断0标志,进入{flag=0; //清除标志位out_time=0; //清除超时标志位led=~led; //观察DelayMs(100); //延时,**适用STC12C5A60S2,低速单片机,要减少延时**s=(num*12)/2*0.34*0.001;//测距返回值TH0=256-12; //定时器0重新初始化TL0=256-12;TR0=1; //运行定时器0INT0_init(); //启动外部中断0}}/*-------------------------------超声波显示部分--------------------------------*/void display(){char displaytemp[16];//定义显示区域临时存储数组if(out_time==33) //大约1s的超时时间,再将显示为0.000{out_time=0; //清除标志位s=0; //显示0}sprintf(displaytemp,"distance:% 6.3f",s);//将数字转成字符串LCD_Write_String(0,1,displaytemp);//显示}//*********************主程序***********************//void main(){LCD_Init(); //1602初始化LCD_Clear(); //清屏T0_init(); //定时器0初始化INT0_init(); //启动外部中断0while(1){measure(); //超声波测距函数display(); //显示}}附链接文件程序:/* 1602.c *//*-----------------------------------------------名称:LCD1602引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<intrins.h>#include "1602.h"#include "delay.h"sbit RS = P2^6; //定义端口sbit RW = P2^5;sbit EN = P2^7;#define RS_CLR RS=0#define RS_SET RS=1#define RW_CLR RW=0#define RW_SET RW=1#define EN_CLR EN=0#define EN_SET EN=1#define DataPort P0/*------------------------------------------------判忙函数------------------------------------------------*/ bitLCD_Check_Busy(void){DataPort= 0xFF;RS_CLR;RW_SET;EN_CLR;_nop_();EN_SET;return (bit)(DataPort& 0x80);}/*------------------------------------------------写入命令函数------------------------------------------------*/ voidLCD_Write_Com(unsigned char com) {while(LCD_Check_Busy()); //忙则等待RS_CLR;RW_CLR;EN_SET;DataPort= com;_nop_();EN_CLR;}/*------------------------------------------------写入数据函数------------------------------------------------*/ voidLCD_Write_Data(unsigned char Data){while(LCD_Check_Busy()); //忙则等待RS_SET;RW_CLR;EN_SET;DataPort= Data;_nop_();EN_CLR;}/*------------------------------------------------清屏函数------------------------------------------------*/voidLCD_Clear(void){LCD_Write_Com(0x01);DelayMs(5);}/*------------------------------------------------写入字符串函数------------------------------------------------*/voidLCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) {if (y == 0){LCD_Write_Com(0x80 + x); //表示第一行}else{LCD_Write_Com(0xC0 + x); //表示第二行}while (*s){LCD_Write_Data( *s);s ++;}}/*------------------------------------------------写入字符函数------------------------------------------------*//* void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) {if (y == 0){LCD_Write_Com(0x80 + x);}else{LCD_Write_Com(0xC0 + x);}LCD_Write_Data( Data);}*//*------------------------------------------------初始化函数------------------------------------------------*/voidLCD_Init(void){LCD_Write_Com(0x38); /*显示模式设置*/DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);LCD_Write_Com(0x08); /*显示关闭*/LCD_Write_Com(0x01); /*显示清屏*/LCD_Write_Com(0x06); /*显示光标移动设置*/DelayMs(5);LCD_Write_Com(0x0C); /*显示开及光标设置*/}/* 1602.h *//*-----------------------------------------------名称:LCD1602.h引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK ------------------------------------------------*/#ifndef __1602_H__#define __1602_H__bitLCD_Check_Busy(void) ;voidLCD_Write_Com(unsigned char com) ;voidLCD_Write_Data(unsigned char Data) ;voidLCD_Clear(void) ;voidLCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) ; voidLCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) ; voidLCD_Init(void) ;#endif/* delay.c*/#include "delay.h"/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned int t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/voidDelayMs(unsigned int t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/* delay.h*/#ifndef __DELAY_H__#define __DELAY_H__/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned int t);/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/voidDelayMs(unsigned int t);#endif。
水位控制远端(hc-sr04)
/*数码管显示*/
void Display(void)
{
if(posit==0)
{
seg1=0;
P0=dist_code[dist_buf[posit]]; //0x7f为小数点,第一位加小数点
unsigned int timer=0; //多任务计时
unsigned char posit=0; //数码管位选
unsigned long S=0; //超声波距离
bit dist_flag =0; //超声波计时溢出标识
unsigned char const dist_code[10] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //P0控制共阳极数码管0,1,2,3,4,5,6,7,8,9
//接线:模块TRIG接 P2.7 TX ECH0 接P2.6 RX
//数码管:共阳数码管P0接数据口,P2.2 P2.1 P2.0接选通数码管
/***********************************************************************************************************/
sbit RX=P2^6; //超声波接收口
sbit TX=P2^7; //超声波控制口
sbit seg1=P2^1; //数码管1位选
sbit seg2=P2^2; //数码管2位选
unsigned int time=0; //超声波计时
/***********************************************************************************************************/
HC-SR04超声波测距模块及程序(坤)
char Del20us=0;//延时变量,在超声波脉冲引脚中产生 20us 的方波 char RxBack=1;//超声波返回标志位
TMOD=0x01;//定时器工作方式 1:16 位,初值不能重装
Tx=0;//将超声波脉冲引脚电位拉低 Th0=0;//初始化变量值 Tl0=0;//初始化变量值 TimeUp=0;//初始化
程序:
#include<reg52.h>
#define uint unsigned int #define uchar unsigned char
sbit Tx=P3^2;//产生脉冲引脚,延时 20us sbit Rx=P3^3;//回波引脚,进入外部中断 1。这些引脚可随意改ቤተ መጻሕፍቲ ባይዱ。
bit TimeUp=0;//定时器溢出标志位 long Th0,Tl0; unsigned long time0=0; uint Measureresult=0;
函数中调用了单片机的定时器所以单片机的一个定时器资源已经被占用但是没有使用外部中断而是软件查询引脚电平的方式判断回波信号目的是方便于再接入几个超声波模块因为单片机的外部中断资源有限
超声波模块 HC-SR04 简介以及编程
说明:我编写了一个超声波测距模块(HC-SR04)的程序,主 要把测距的程序写成函数形式,函数的返回值为所测的距离(为十进 制数),单位为毫米(mm)。便于大家嵌入自己开发的主程序中,方 便随时调用。函数中调用了单片机的定时器,所以单片机的一个定时 器资源已经被占用,但是没有使用外部中断,而是软件查询引脚电平 的方式判断回波信号,目的是方便于再接入几个超声波模块,因为单 片机的外部中断资源有限。
效果:可在 3CM-90CM 范围内测量,但是远距离误差较大 (1cm-2cm),但近距离误差较小。可以根据不同的模块作简单的修 正。
超声波检测的程序
本人刚刚接触单片机,不得不从基础学起,由于要完成一个任务,小车避障,所以我就买了一个超声波模块直接用来测距测距原理:超声波模块工作原理:(1)采用IO触发测距,给至少10us的高电平信号;(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;(3)有信号返回,通过IO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2;然后我就用单片机的P1.3与模块的发射端Trig相连,P3. 3作为外部中断1检测回波信号下降沿产生中断测距,P3.3与Echo相连。
测距后由四位一体的数码管显示并将测得距离(用厘米表示)发送给PC机。
本来一切进行的很顺利,但是出现了一个问题,想了几天还是不知道怎么回事,希望大家帮忙解决一下,我将不胜感激。
当测距距离显示65cm后,大于65后数码管就重新从0开始显示,比如实际距离为80CM时,它就显示15CM,不知道问题所在。
急死我了。
单片机晶振11.0592Mhz。
程序代码:#include <reg51.h>#include <intrins.h>#include <math.h>#define LED P0#define uint unsigned int#define uchar unsigned char//#define v 340sbit No1 = P1^4; //动态显示控制位sbit No2 = P1^5;sbit No3 = P1^6;sbit No4 = P1^7;sbit trig=P1^3; //超声波发射端sbit echo=P3^3; //超声波接收端/*********宏定义,定义数码管显示第几位***********/ #define DIS_NO1 No1=0; No2=1; No3=1; No4=1#define DIS_NO2 No1=1; No2=0; No3=1; No4=1#define DIS_NO3 No1=1; No2=1; No3=0; No4=1#define DIS_NO4 No1=1; No2=1; No3=1; No4=0uint t,distance;uchar i,j,flag;void delay(uint time);void display(uint num);void initial(void);void send_signal(void);void send(uint m);code uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x 82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xb f,0x7f,0xff};/*************************************************** *********************************//*TRIG端口发一个10US高电平,当TRIG变成0时,超声波模块开始发射超声波,主控制 *//*板就可以在ECHO等待0输出.从TRIG=1到ECHO=0的时间就为此次测距的时间,可算出距离 *//*************************************************** *********************************/void main(void){delay(50); //去抖动initial(); //初始化trig=0;delay(50);while(1){send_signal();while(!flag); //等待外部中断或定时器0溢出中断if(flag==1) //外部中断,测距{display(distance); //显示距离send(distance); //发送数据给PC机//send(0);}else //定时器0溢出中断{display(0);send(0);//send(1);}delay(10); //延时TL0=0x00; //定时器0重新设置值TH0=0x00;flag=0; //测试标志位置0}}//*延时程序void delay(uint time){while(time--);}//初始化void initial(void){TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1SCON = 0x50; // uart 模式1 (8 bit), REN=1;TL1 = 0xfd; //波特率9600TH1 = 0xfd;TL0 = 0x00; //初始值;TH0 = 0x00;TR1=1;EA=1;}/*************************************************** ***********//*产生超声波并计时等待中断************************** ***********//*************************************************** ***********/void send_signal(void){trig=1;for(i=0;i<10;i++) _nop_();trig=0;for(j=0;j<65;j++) _nop_(); //避免发射波对回波产生干扰,延时TR0=1; //启动定时器1计时ET0=1; //定时器1允许中断EA=1; //开总中断EX1=1; //外部中断1开中断IT1=1; //下降沿触发}/*************************************************** *********//********定时器0溢出中断*************************** **********//*************************************************** ***********/void timer0(void) interrupt 1{TR0=0;EX1=0;ET0=0;flag=2;}/*************************************************** ***********//*******外部中断1中断测距************************** ************/void test(void) interrupt 2{TR0=0; //停止计数ET0=0; //关定时器0中断EX1=0; //关外部中断EA=0; //关总中断flag=1; //测距成功标志t=TH0; //读取测试时间t<<=8;t+=TL0;distance=17*t/1000; //声速340m/s,结果用cm表示}/*************************************************** ***********//*************************显示********************** *************//*************************************************** ***********/void display(uint num){// DIS_NO1; //选中第一只灯// LED=table[num/1000]; //指针指向下一位数据// delay(50);DIS_NO2; //选中第二只灯LED=table[num/100];delay(100);2011-05-04,19:38:47 资料邮件回引用回↓↓编辑删除2011-05-05,14:资料邮件回复引用回复编辑删除2011-05-06,13:资料邮件回复引用回复编辑删除2011-05-09,15:资料邮件回复引用回复编辑删除积分:2242011-05-09,18:资料邮件回复引用回复编辑删除ulong t;float distance; //很重要,防止溢出,距离计算出错uchar i,j,flag;const uint v=340;void delay(uint time);void display(uint num);void initial(void);void send_signal(void);void send(float m);code uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f,0xff};/********************************************************************* ***************//*TRIG端口发一个10US高电平,当TRIG变成0时,超声波模块开始发射超声波,主控制 *//*板就可以在ECHO等待0输出.从TRIG=1到ECHO=0的时间就为此次测距的时间,可算出距离 *//********************************************************************* ***************/void main(void){delay(50); //去抖动initial(); //初始化trig=0;delay(50);while(1){send_signal();while(!flag); //等待外部中断或定时器0溢出中断if(flag==1) //外部中断,测距{display(distance); //显示距离send(distance);//if(distance<=1000&&distance>=400) send(0);//else send(1); //发送指令给PC机}else //定时器0溢出中断{display(0);send(0);}TL0=0x00; //定时器0重新设置值TH0=0x00;delay(50); //延时flag=0; //测试标志位置0}}//*延时程序void delay(uint time){while(time--){_nop_();}}//初始化void initial(void){TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1 SCON = 0x50; // uart 模式1 (8 bit), REN=1;TL1 = 0xfd; //波特率9600TH1 = 0xfd;TL0 = 0x00; //初始值;TH0 = 0x00;TR1=1;EA=1;}/**************************************************************/ /*产生超声波并计时等待中断*************************************/ /**************************************************************/ void send_signal(void){trig=1;//for(i=0;i<10;i++) _nop_();delay(10);trig=0;while(echo==0); //等待Echo回波引脚变高电平//for(j=0;j<50;j++) _nop_(); //避免发射波对回波产生干扰,延时delay(30);flag=0; //清测量成功标志TR0=1; //启动定时器0计时ET0=1; //定时器0允许中断EA=1; //开总中断EX1=1; //外部中断1开中断IT1=1; //下降沿触发}/************************************************************/ /********定时器0溢出中断*************************************//**************************************************************/ void timer0(void) interrupt 1{TR0=0;EX1=0;ET0=0;flag=2;}/**************************************************************/ /*******外部中断1中断测距**************************************/ void test(void) interrupt 2{delay(50); //不能太长时间,有可能是2次中断if(echo==0){TR0=0; //停止计数ET0=0; //关定时器0中断EX1=0; //关外部中断EA=0; //关总中断flag=1; //测距成功标志t=TH0; //读取测试时间t<<=8;t+=TL0;distance=v*t/2000.0; //声速340m/s,结果用mm表示}}/**************************************************************/ /*************************显示***********************************/ /**************************************************************/ void display(uint num){DIS_NO1; //选中第一只灯LED=table[num/1000]; //指针指向下一位数据delay(50);DIS_NO2; //选中第二只灯LED=table[num/100];delay(50);DIS_NO3; //选中第三只灯LED=table[(num%100)/10];delay(50);2011-05-09,21:资料邮件回复引用回复编辑删除。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//超声波模块程序
//超声波模块程序
//Trig = P2^0
//Echo = P3^2
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
int time;
int succeed_flag;
uchar timeL;
uchar timeH;
sbit Trig=P1^0;
sbit Echo=P3^2;
uchar code table[]={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; //打开总中断0
TMOD=0x10; //定时器1,16位工作方式
while(1)
{
EA=0; //关总中断
Trig=1; //超声波输入端
delay_20us(); //延时20us
Trig=0; //产生一个20us的脉冲
while(Echo==0); //等待Echo回波引脚变高电平while(Echo == 0); 这////个句子就是说,当Echo的值为0的时候,程序停在这里,不再向下执行。
///一般与中断有关的程序会用这个中语句。
如果在中断中放入可以改变echo这//个变量的程序,当中断执行时,echo不再为0,这个语句自然就过去了。
succeed_flag=0; //清测量成功标志
EA=1;
EX0=1; //打开外部中断0
TH1=0; //定时器1清零
TL1=0; //定时器1清零
TF1=0; //计数溢出标志
TR1=1; //启动定时器1
delay(20); //等待测量的结果
TR1=0; //关闭定时器1
EX0=0; //关闭外部中断0
if(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<reg52.h>
//#include<delay.h>
#include <intrins.h>
#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);
}
}。