51单片机超声波模块的C语言程序
用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三极管驱动。
超声波 c语言
#include<reg51.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;//外部中断1,接CX20106的7脚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();//延时100usvoid display(uint dat);//4位数码管显示函数,只用了3位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;//定时器0方式1用于计时TH0=0;TL0=0; /* 设定T0的工作模式为2*/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;//清定时0TR0=1;//开定时0for(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) //中断标志位置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;//关定时器0ET0=0;//关外部中断flag=1; //置位标志位tmp=TH0*256+TL0; //读取定时器的值if((tmp>0)&&(tmp<60000))//判断是否超出范围,此设置的范围为0到10米,实际不能达到10米{high_time=TH0;//把计时值放入缓冲low_time=TL0;}else //超出范围则重新测量{high_time=0;low_time=0;}}。
超声波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#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单片机超声波测距程序
wela=1; P0=0xfe; wela=0; delay(1); }
文档
标准实用文案
/* 被调用子函数 */ void diaoyong()
{ uint i; EA=0; echo=1;
高 trig=1; delay20us(); trig=0; while(echo==0);
{
time=timeh*256+timel;// 计算测定距离,并显示
distance=time*0.1720;
display(distance);
}
if(0,同
时灯闪烁
{
distance=0;
test=!test;
}
}
/* 主函数 */
文档
标准实用文案
// 测试灯
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 };
void main() {
initime0(); test=0; trig=0; EA=1; while(1) {
diaoyong(); display(distance); } }
文档
标准实用文案
// 超声波测距,测距范围 2cm-400cm; #include<reg52.h> #include<intrins.h>
超声波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++);}。
51 超声波 程序
succeed_flag=1; //至成功测量的标志
EX0=0; //关闭外部中断
}
//****************************************************************
case 0x01:P0=shi;P2=0xbf;flag++;break;
case 0x02:P0=bai;P2=0xdf;flag=0;break;
}
}
//显示数据转换程序
void conversion(uint temp_data)
{
ge_data=temp_data;
bai_data=SEG7[bai_data];
shi_data=SEG7[shi_data]&0x7f;
ge_data =SEG7[ge_data];
EA=0;
bai = bai_data;
shi = shi_data;
} //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
//定时器0中断,用做显示
timer0() interrupt 1 // 定时器0中断是1号
{
TH0=0xfd; //写入定时器0初始值
TL0=0x77;
switch(flag)
{case 0x00:P0=ge; P2=0x7f;flag++;break;
i=0;
flag=0;
Tx=0; //首先拉低脉冲输入引脚
基于51单片机控制的超声波测距程序
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文档良心出品)
#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单片机超声波模块的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单片机红外解码、超声波测距程序(详细解释程序)
// 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单片机的超声波测距仪说明书引言超声波测距仪,可应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于如液位、井深、管道长度的测量等场合。
利用超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量。
利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制。
一、性能要求该超声波测距仪,要求测量范围在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单片机超声波温度显示程序加在一起
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuint flag,time;uint i;uint temp;void display_wd();void display_temp1();uchar code digit[10]={"0123456789"};uint bai,shi,ge,S,timer;uchar timeL,timeH;//超声波模块引脚的定义sbit TX=P1^4;sbit beep=P1^2;sbit RX=P1^3;//LCD12864引脚的定义sbit CS=P2^0;sbit SID=P2^1;sbit SCLK=P2^2;sbit PSB=P2^3;sbit DS=P1^1;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}//----------------------------------------以下是LCD12864的程序---------------------------- void send_command(uchar command_data){uchar i;uchar i_data;i_data=0xf8;CS=1;SCLK=0;for(i=0;i<8;i++) //第一字节,发送命令,11111000-些指令{SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data; /*获取命令的高四位,低四位补零*/i_data&=0xf0;for(i=0;i<8;i++) //第二字节{SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data<<=4;for(i=0;i<8;i++) //第三字节{SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;delay(10);}void send_data(uchar command_data) {uchar i;uchar i_data;i_data=0xfa;CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data<<=4;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;delay(10);}void lcd_string(char *strpoint){ register i=0;while(strpoint[i]!=0){send_data(strpoint[i]);i++;}}void start(){ send_command(0x80);lcd_string("前方的距离是:");//C编译系统本省也具有转换功能,所以也可以这样写send_command(0x93);send_data(bai+48);send_data(shi+48);send_data(ge+48);display_wd();display_temp1();}void lcd_init(){ PSB=0;delay(100);send_command(0x30); /*设置8位数据接口,基本指令模式。
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单片机超声波模块程序//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超声波显示程序
write_data(hanzi[13]);
write_data(hanzi[14]);
write_data(hanzi[15]);
// while(1);
write_command(0x80+0x08); //这里L0 =0;
TR0 =0;
ET0 =1; //允许T0中断
EA =1; //开总中断
}
//======================== 启动超声波传感器 ===================================================
}
}
//**********************定时器1中断,用做超声波测距计时******************************************
//void timer0() interrupt 1
//{
// TH0=0;
// TL0=0;
//}
write_data(sudu[13]);
write_data(sudu[14]);
write_data(sudu[15]);
}
void write_distance(unsigned char m,unsigned int i)
{
write_command(0x80+m);
write_data(hanzi[0]);
write_data(hanzi[1]);
write_data(hanzi[2]);
write_data(hanzi[3]);
write_data(hanzi[4]);
51单片机c语言模块化编程的步骤和方法
51单片机c语言模块化编程的步骤和方法
模块化编程是一种编程方法,它将程序划分为独立的、可重用的模块,每个模块执行特定的功能。
对于51单片机来说,C语言是常用的编程语言。
下
面是一般的步骤和方法,以实现C语言的模块化编程:
1. 明确需求和功能模块:首先,你需要明确你的程序需要完成哪些功能。
将这些功能划分为独立的模块,每个模块执行一个特定的任务。
2. 创建模块:为每个功能模块创建一个C文件。
例如,如果你有一个控制LED的模块,你可以创建一个名为``的文件。
3. 编写模块函数:在每个模块的C文件中,编写实现该模块功能的函数。
这些函数应该是模块的一部分,并且应该是模块化的。
4. 编写头文件:为每个模块创建一个头文件。
头文件应该包含该模块的函数声明和任何公共变量。
例如,``可能包含控制LED的函数的声明。
5. 主程序调用模块函数:在主程序中,你需要包含适当的头文件,并调用需要的模块函数。
主程序应该将所有模块组合在一起,以实现所需的功能。
6. 编译和链接:使用适当的编译器将所有C文件编译为目标文件。
然后,
使用链接器将这些目标文件链接在一起,生成最终的可执行文件。
7. 测试和调试:在目标硬件上测试和调试程序。
确保每个模块都按预期工作,并且所有模块都能协同工作。
这只是一个基本的步骤和方法。
具体的实现可能会根据硬件、需求和其他因素有所不同。
不过,基本的模块化编程原则应该是相同的。
用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单片机设计超声波测距系统的设计原理和电路(附源程序)
基于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程序#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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 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回波引脚变高电平 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);
}
}。