1、带温度补偿的超声波测距程序/* 程序:基于HC-SR04的超声波测距系统* 单片机型号:STC90C516 12MHz* 说明:开始连续进行7次超声波测距,每次测距间隔80ms,* 完成后对7次结果排序并将最大的2个数值和最小的2个数值去除,对剩余的* 3个数值取平均值。完成后指示灯灭,输出结果到LCD1602上。测量超出范围则发出报警声。* 使用两个IO端口控制HC-SR04触发信号输入和回响信号输出,* 以及一个T0定时器用于时间计数。* 使用DS18B20测量环境温度,声速公式:V=334.1m/s+Temperature*0.61,* 单片机晶振为12Mhz(11.953M),计数时为
2、T=1us* 计算公式:S=(334.1m/s+Temperature*0.61)*N*T/2,N为计数值=TH0*256+TL0*/*包含头文件*/#include #include #define Delay4us()_nop_();_nop_();_nop_();_nop_();/*宏定义*/#define uchar unsigned char /无符号8位#define uint unsigned int /无符号16位#define ulong unsigned long /无符号32位/*全局变量定义*/sbit BEEP=P15; /报警测量超出范围sbit Trig=P34;
3、 /HC-SR04触发信号输入sbit Echo=P32; /HC-SR04回响信号输出float xdata DistanceValue=0.0; /测量的距离值float xdata SPEEDSOUND; /声速float xdata XTALTIME; /单片机计数周期uchar xdata stringBuf6; /数值转字符串缓冲 /LCD1602提示信息uchar code Prompts16= Measure Distance, /测量距离 - Out of Range -, /超出测量范围 MAX range 400cm , /测距最大值400cm MIN range 2cm
4、 , /测距最小值2cm , /清屏;uchar xdata DistanceText=Range: ;/测量结果字符串uchar xdata TemperatureText=Temperature: ;/测量温度值/*外部函数声明*/extern void LCD_Initialize(); /LCD初始化extern void LCD_Display_String(uchar *, uchar);extern void ReadTemperatureFromDS18B20();extern int xdata CurTempInteger; void DelayMS(uint ms); /
5、毫秒延时函数void Delay20us(); /20微秒延时函数void HCSR04_Initialize(); /HCSR04初始化float MeasuringDistance(); /测量距离float DistanceStatistics(); /测距的数值排序求平均void DisplayDistanceValue(float dat); /输出距离值到LCD1602上uchar UnsigedIntToString(uint value); /将无符号的整数转成字符串,返回字符串长度,不包括0结束符void Beep(uchar time); /蜂鸣器void DisplayT
6、emperatureValue(); /显示温度值/*测量距离*/float MeasuringDistance() /最大定时时间约65ms TH0=0; TL0=0; /生成20us的脉冲宽度的触发信号 Trig=1; Delay20us(); Trig=0; while(!Echo);/等待回响信号变高电平 TR0=1; /启动定时器0 while(Echo);/等待回响信号变低电平 TR0=0; /关闭定时器0 return (SPEEDSOUND*XTALTIME*(float)TH0*256+(float)TL0)/2000; /返回距离值(mm)/*HCSR04初始化*/void
7、 HCSR04_Initialize() XTALTIME=12/12; /计算单片机计数周期 晶振=12M 单位us SPEEDSOUND=334.1+25*0.61; /温度25度时声速的值 Trig=0; Echo=0; TMOD=0x01;/*输出距离值到LCD1602上*/void DisplayDistanceValue(float dat) uchar i=0,j=0,len; uint value; value=(uint)dat; /范围检查大于4000mm和小于20mm都为超出测量范围 if(value4000) LCD_Display_String(Prompts1,0x
8、00); LCD_Display_String(Prompts2,0x40); Beep(2); else if(value20) LCD_Display_String(Prompts1,0x00); LCD_Display_String(Prompts3,0x40); Beep(2); else len=UnsigedIntToString(value); /将数值转换成字符串 /保留1位小数 while(stringBufi!=0) if(len-j=1) DistanceText6+j=.; j+; else DistanceText6+j=stringBufi; i+; j+; Dis
9、tanceText6+j=c; j+; DistanceText6+j=m; i=7+j; /剩余位置补空格 while(i16) DistanceTexti= ; i+; LCD_Display_String(DistanceText,0x40); /LCD_Display_String(Prompts0,0x00); /*显示温度值*/void DisplayTemperatureValue() TemperatureText13=CurTempInteger/10+0; TemperatureText14=CurTempInteger%10+0; TemperatureText15=C;
10、 LCD_Display_String(TemperatureText,0x00); /*将无符号的整数转成字符串,返回字符串长度*/uchar UnsigedIntToString(uint value) uchar i=0,t,length; /从个位开始转换 do stringBufi=0+value%10; value=value/10; i+; while(value!=0); length=i; /将字符串颠倒顺序 for(i=0;i(length/2);i+) t=stringBufi; stringBufi=stringBuflength-i-1; stringBuflengt
11、h-i-1=t; stringBuflength=0; return length;/*蜂鸣器*/void Beep(uchar time) uchar i; for(i=0;i100;i+) BEEP=!BEEP; DelayMS(time); BEEP=0; DelayMS(100);/*延时函数 毫秒 12.000MHz*/void DelayMS(uint ms) uchar i, j; while(ms-) _nop_(); i=2; j=239; do while (-j); while (-i); /*延时函数 20微秒 12.000MHz*/void Delay20us() u
12、char i; _nop_(); i=7; while (-i);/*定时器0中断*/void Timer0() interrupt 1 /DS18B20代码:/*-* 程序功能: DS18B20温度检测程序* 单片机型号:STC89C52 12MHz* 晶振: 12Mhz-*/*包含头文件*/#include #include /*宏定义*/#define uchar unsigned char /无符号8位#define uint unsigned int /无符号16位sbit DS18B20_DQ = P33; /定义DS18B20端口DS18B20_DQint xdata CurTe
13、mpInteger; /当前采集的温度值整数部分int xdata CurTempDecimal; /当前采集的温度值小数部分/*功能:延时函数 STC89C52 12MHz 12T模式 参数:无 返回:无*/void Delayus(uint count) while (-count); /*功能:DS18B20复位及状态检测 参数:无 返回:0或1,1表示未准备好,0表示准备好*/uchar Reset_DS18B20() uchar status; DS18B20_DQ=1; Delayus(1); /开始复位过程 DS18B20_DQ=0; /数据线拉低 Delayus(100); /
14、延时480us-960us DS18B20_DQ=1; /数据线拉高 Delayus(10); /延时15us-60us status=DS18B20_DQ; /读取数据线上的状态 Delayus(120); return status;/*功能:写一字节到DS18B20中 参数:dat=数据 返回:无*/void WriteByteToDS18B20(uchar dat) uchar i; for(i=0;i=1; /准备下一位数据 /*功能:从DS18B20中读一字节 参数:无 返回:读取的数据*/uchar ReadByteFromDS18B20() uchar i,dat=0; for
15、(i=0;i=1; DS18B20_DQ=1; /释放总线,准备读1位数据 Delayus(2); /延时4us if(DS18B20_DQ) dat|=0x80; /合并每位数据 Delayus(15); /延时60us DS18B20_DQ=1; /拉高总线,准备读下1位数据 return dat;/*功能:读取温度值并转换成有符号的数值形式 参数:无 返回:无*/void ReadTemperatureFromDS18B20() uchar flag=0;/正负符号标志 /存储当前采集的温度值 uchar TempValue=0,0; if(Reset_DS18B20() /DS18B2
16、0复位 CurTempInteger=255; CurTempDecimal=0; else WriteByteToDS18B20(0xCC);/跳过ROM命令 WriteByteToDS18B20(0x44);/温度转换命令 Reset_DS18B20();/复位 WriteByteToDS18B20(0xCC);/跳过ROM命令 WriteByteToDS18B20(0xBE);/读取温度暂存器命令 TempValue0=ReadByteFromDS18B20();/先读低字节温度值 TempValue1=ReadByteFromDS18B20();/后读高字节温度值 Reset_DS18
17、B20();/复位 /计算温度值:先进行正温度与负温度判断,高5位全为1(0xF8)则为负数 if(TempValue1&0xF8)=0xF8) /负温度计算:取反加1,低字节为0时,高字节取反加1,否则不需要。 TempValue1=TempValue1; TempValue0=TempValue0+1; if(TempValue0=0x00) TempValue1+; flag=1;/负数标志 /将温度值分为整数和小数两部分存储(默认为12位精度) CurTempInteger=(TempValue1&0x07)4); if(flag) CurTempInteger=-CurTempInt
18、eger; CurTempDecimal=(TempValue0&0x0F)*625; / LCD1602程序代码:/* 程序功能:1602液晶显示程序 单片机型号:STC90C160 12MHz*/*1602液晶显示器控制端口分配,数据使用P0端口*/sbit LCD_RS=P20;sbit LCD_RW=P21;sbit LCD_EN=P22;/* 功能:毫秒级延时函数 参数:ms=毫秒数值 返回:无*/void LCDDelay(uint ms) uchar i, j; while(ms-) _nop_(); i = 2; j = 239; do while (-j); while (-
19、i); /*功能:1602液晶忙状态检测 参数:无返回:0或1,1表示状态忙,0表示状态闲*/bit LCD_Busy_Check() bit result; LCD_RS=0; LCD_RW=1; LCD_EN=1; Delay4us(); result=(bit)(P0&0x80); LCD_EN=0; return result;/*功能:1602液晶写指令 参数:cmd=1602LCD指令 返回:无*/void Write_LCD_Command(uchar cmd) while(LCD_Busy_Check(); LCD_RS=0; LCD_RW=0; LCD_EN=0; _nop_(); _nop_(); P0=cmd; Delay4us(); LCD_EN=1; Delay4us(); LCD_EN=0;/*功能:1602液晶写数据 参数:dat=一个字节数据 返回:无*/void Write_LCD_Data(uchar dat)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1