导航:首页 > 操作系统 > 32单片机超声波测距程序代码

32单片机超声波测距程序代码

发布时间:2023-02-27 09:55:49

㈠ 帮忙详细解答一下基于单片机的超声波测距仪的汇编源程序(急求啊)

我可以负责的告诉你,用C吧,完全可以胜任。
2003年的时候我们为了确保MCU的效率(时效性),强制使用汇编写的超声波程序,结果程序写不大,汇编你也知道,写百八十行可以,代码多了,这程序就没法看了,更谈不上程序升级和维护了。因此,那一代超声波产品的功能很弱。
2006年,我们要重新设计第二代超声波产品,要求可靠性好、功能强大,自然的代码量也要多了,当时我们仍然固执的使用汇编、绝不用C,可汇编的代码仍然写不长,为了方便技术人员管理和后续的产品升级,我把这一套复杂的系统代码分成了4级,也就是4套汇编代码,分别在32个MCU里运行(同一个设备里),这4套代码分别交给4个人来编写和维护,这4个人中若有人跳槽走了,由于他掌握的代码量小,功能又单一,接替他的人也很容易接手。(否则,这4套汇编程序,集中在一个冗长的代码里,那么这套代码将很难维护,而且几乎只能有1个人才能完全看懂它,一旦这个人走了,别人很难接手这套‘烂’程序,这对于产品的持续改进非常不利)
2008年,我们试探性的,在DSP(TMS320F28335)上用C完成了所有的功能,而且程序量比汇编要少得多,可读性、可维护性也要好得多。后来,我们在单片机上,也用C完成了绝大部分功能,原来担心的时效性问题从没有发生,这才领悟:2003-2008这5年,我们绕了一个大圈。
从此以后,我们就不再用汇编了,用C写超声波程序一直至今(偶尔嵌入汇编代码),算一下也有5年了,从没觉得C有任何局限性。
那么,你是还觉得必须要用汇编么?

㈡ 1602显示超声波测距的C语言程序和Proteus仿真图

#include"reg52.h"
#include"intrins.h"

#define uchar unsigned char //无符号8位
#define uint unsigned int //无符号16位
#define ulong unsigned long //无符号32位

sbit K1=P1^0; //按下K1后,开始测距
sbit LEDRed=P1^1; //测距指示灯,亮表示正在测距,灭表示测距完成
//sbit BEEP=P1^2; //报警测量超出范围

sbit Trig=P2^5; //HC-SR04触发信号输入
sbit Echo=P2^6; //HC-SR04回响信号输出

float xdata DistanceValue=0.0; //测量的距离值
float xdata SPEEDSOUND; //声速
float xdata XTALTIME; //单片机计数周期
uchar xdata stringBuf[6]; //数值转字符串缓冲

//LCD1602提示信息
uchar code Prompts[][16]=
{
{"Measure Distance"}, //测量距离
{"- Out of Range -"}, //超出测量范围
{"MAX range 400cm "}, //测距最大值400cm
{"MIN range 2cm "}, //测距最小值2cm
{" "}, //清屏
{" Press K1 Start "} //按键开始测量
};
uchar xdata DistanceText[]="Range: "; //测量结果字符串
uchar xdata TemperatureText[]="Temperature: ";//测量温度值

extern void LCD_Initialize(); //LCD初始化
extern void LCD_Display_String(uchar *, uchar); //字符串显示
extern void ReadTemperatureFromDS18B20(); //从DS18B20读取温度值
extern int xdata CurTempInteger;

//毫秒延时函数
void DelayMS(uint ms);
//20微秒延时函数
void Delay20us();
//HCSR04初始化
void HCSR04_Initialize();
//测量距离
float MeasuringDistance();
//测距的数值排序求平均
float DistanceStatistics();
//输出距离值到LCD1602上
void DisplayDistanceValue(float dat);
//将无符号的整数转成字符串,返回字符串长度,不包括'\0'结束符
uchar UnsigedIntToString(uint value);
//蜂鸣器
//void Beep(uchar time);
//显示温度值
void DisplayTemperatureValue();

void main()
{
LCD_Initialize();//LCD1602初始化
LCD_Display_String(Prompts[0],0x00);
LCD_Display_String(Prompts[5],0x40);
ReadTemperatureFromDS18B20(); //测温度
HCSR04_Initialize(); //HC-SR04初始化
while(1)
{
if(K1==0)
{
DelayMS(5);
if(K1==0)
{
//Beep(1);
while(K1==0);
LEDRed=0;
ReadTemperatureFromDS18B20();//测温度
DisplayTemperatureValue();
if(CurTempInteger<14)
CurTempInteger=14;
else if(CurTempInteger>26)
CurTempInteger=26;
SPEEDSOUND=334.1+CurTempInteger*0.61;//计算声速
DistanceValue=DistanceStatistics(); //测距并返回距离值
DisplayDistanceValue(DistanceValue); //显示距离值
LEDRed=1;
}
}
}
}

//测距的数值排序求平均
float DistanceStatistics()
{
uchar i,j;
float disData[7],t;
//连续测距
for(i=0;i<7;i++)
{
disData=MeasuringDistance();
DelayMS(80);
}
//排序
for(j=0;j<=6;j++)
{
for(i=0;i<7-j;i++)
{
if(disData>disData[i+1])
{
t=disData;
disData=disData[i+1];
disData[i+1]=t;
}
}
}
return (disData[2]+disData[3]+disData[4])/3;
}

//测量距离
float MeasuringDistance()
{
//最大定时时间约65ms
TH0=0;
TL0=0;

//生成20us的脉冲宽度的触发信号
Trig=1;
Delay20us();
Trig=0;

//等待回响信号变高电平
while(!Echo);
TR0=1; //启动定时器0

//等待回响信号变低电平
while(Echo);
TR0=0; //关闭定时器0

//返回距离值(mm)
return (SPEEDSOUND*XTALTIME*((float)TH0*256+(float)TL0))/2000;
}

//HCSR04初始化
void HCSR04_Initialize()
{
//计算单片机计数周期 晶振=11.953M 单位us
XTALTIME=12/11.953;
//温度25度时声速的值
SPEEDSOUND=334.1+25*0.61;
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(value>4000)
{
LCD_Display_String(Prompts[1],0x00);
LCD_Display_String(Prompts[2],0x40);
//Beep(2);
}
else if(value<20)
{
LCD_Display_String(Prompts[1],0x00);
LCD_Display_String(Prompts[3],0x40);
//Beep(2);
}
else
{
//将数值转换成字符串
len=UnsigedIntToString(value);
//保留1位小数
while(stringBuf!='\0')
{
if(len-j==1)
{
DistanceText[6+j]='.';
j++;
}else
{
DistanceText[6+j]=stringBuf;
i++;
j++;
}
}
DistanceText[6+j]='c';
j++;
DistanceText[6+j]='m';
i=7+j;
//剩余位置补空格
while(i<16)
{
DistanceText=' ';
i++;
}
//LCD_Display_String(Prompts[0],0x00);
LCD_Display_String(DistanceText,0x40);
}
}

//显示温度值
void DisplayTemperatureValue()
{
TemperatureText[13]=CurTempInteger/10+'0';
TemperatureText[14]=CurTempInteger+'0';
TemperatureText[15]='C';
LCD_Display_String(TemperatureText,0x00);
}

//将无符号的整数转成字符串,返回字符串长度
uchar UnsigedIntToString(uint value)
{
uchar i=0,t,length;
//从个位开始转换
do
{
stringBuf='0'+value;
value=value/10;
i++;
}while(value!=0);
length=i;
//将字符串颠倒顺序
for(i=0;i<(length/2);i++)
{
t=stringBuf;
stringBuf=stringBuf[length-i-1];
stringBuf[length-i-1]=t;
}
stringBuf[length]='\0';
return length;
}

//蜂鸣器

//延时函数 毫秒 @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()
{
uchar i;
_nop_();
i = 7;
while (--i);
}

//定时器0中断
void Timer0() interrupt 1
{

}

//DS18B20代码:

#include
#include

#define uchar unsigned char //无符号8位
#define uint unsigned int //无符号16位

//定义DS18B20端口DS18B20_DQ
sbit DS18B20_DQ = P2^7;

//当前采集的温度值整数部分
int xdata CurTempInteger;
//当前采集的温度值小数部分
int xdata CurTempDecimal;

void Delayus(uint count)
{
while (--count);
}

uchar Reset_DS18B20()
{
uchar status;
DS18B20_DQ=1;
Delayus(1);
//开始复位过程
DS18B20_DQ=0; //数据线拉低
Delayus(100); //延时480us-960us
DS18B20_DQ=1; //数据线拉高
Delayus(10); //延时15us-60us
status=DS18B20_DQ; //读取数据线上的状态
Delayus(120);
return status;
}

void WriteByteToDS18B20(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DS18B20_DQ=0;
DS18B20_DQ=dat&0x01; //发送1位数据
Delayus(15); //延时60us以上
DS18B20_DQ=1; //释放总线,等待总线恢复
dat>>=1; //准备下一位数据
}
}

uchar ReadByteFromDS18B20()
{
uchar i,dat=0;
for(i=0;i<8;i++)
{

DS18B20_DQ=0; //拉低总线,产生读信号
dat>>=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())
{
CurTempInteger=255;
CurTempDecimal=0;
}
else
{
WriteByteToDS18B20(0xCC);//跳过ROM命令
WriteByteToDS18B20(0x44);//温度转换命令
Reset_DS18B20();//复位
WriteByteToDS18B20(0xCC);//跳过ROM命令
WriteByteToDS18B20(0xBE);//读取温度暂存器命令
TempValue[0]=ReadByteFromDS18B20();//先读低字节温度值
TempValue[1]=ReadByteFromDS18B20();//后读高字节温度值
Reset_DS18B20();//复位

//计算温度值
//先进行正温度与负温度判断,高5位全为1(0xF8)则为负数
if((TempValue[1]&0xF8)==0xF8)
{
//负温度计算:取反加1,低字节为0时,高字节取反加1,否则不需要。
TempValue[1]=~TempValue[1];
TempValue[0]=~TempValue[0]+1;
if(TempValue[0]==0x00) TempValue[1]++;
flag=1;//负数标志
}
//将温度值分为整数和小数两部分存储(默认为12位精度)
CurTempInteger=((TempValue[1]&0x07)<<4)|((TempValue[0]&0xF0)>>4); if(flag) CurTempInteger=-CurTempInteger;
CurTempDecimal=(TempValue[0]&0x0F)*625;
}
}

//LCD1602程序代码:

#include
#include

#define uchar unsigned char
#define uint unsigned int
#define Delay4us(){_nop_();_nop_();_nop_();_nop_();}

sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;

void LCDDelay(uint ms)
{
uchar i, j;
while(ms--)
{
_nop_();
i = 2;
j = 239;
do
{
while (--j);
}while (--i);
}
}

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;
}

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;
}

void Write_LCD_Data(uchar dat)
{
while(LCD_Busy_Check());
LCD_RS=1;LCD_RW=0;LCD_EN=0;
P0=dat;Delay4us();
LCD_EN=1;Delay4us();LCD_EN=0;
}

void LCD_Set_POS(uchar pos)
{
Write_LCD_Command(pos|0x80);
}

void LCD_Initialize()
{
Write_LCD_Command(0x01); LCDDelay(5);
Write_LCD_Command(0x38); LCDDelay(5);
Write_LCD_Command(0x0C); LCDDelay(5);
Write_LCD_Command(0x06); LCDDelay(5);
}

void LCD_Display_String(uchar *str, uchar LineNo)
{
uchar k;
LCD_Set_POS(LineNo);
for(k=0;k<16;k++)
{
Write_LCD_Data(str[k]);
}
}

void LCD_Display_OneChar(uchar Dat, uchar X, uchar Y)
{
Y &= 0x01; //限制Y不能大于1(2行,0-1)
X &= 0x0F; //限制X不能大于15(16个字符,0-15)
if(Y) {X |= 0x40;} //当要在第二行显示时地址码+0x40;
X |= 0x80; //算出指令码
Write_LCD_Command(X);
Write_LCD_Data(Dat);
}

㈢ 51单片机超声波测距代码是多少

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);
}
}

㈣ 基于单片机超声波测距c语言程序求解释

//上面这段什么意思?
//上下面这段什么意思? 没有code为什么也可以存16进制?
uchar dis_smg[8] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};

有code和没有code的区别在于 dis_smg变量的存储的存储方式上
我记得有code的适合 dis_smg的数组元素不能改变的吧 记得不清楚了
你可以网络去

//下面是不是数码管引脚和单片机引脚对应?
//数码管位选定义
sbit smg_we1 = P3^4; //数码管位选定义

答案: 是

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

1602液晶显示 的超声波模块程序
接口程序里边都有、、

#include
//#include
#include

#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);
}
}

㈥ 单片机汇编语言程序解读(超声波测距)越详细越好

这是几个子程序被 堆砌到一起了 ,没有主程序不能实现功能

㈦ 单片机超声波雷达测距的C语言程序设计,具体要求看问题补充

你到网络文库中找找,会找到很多的。你也可到淘宝网上找一下:“单片机超声波测距模块电子设计制作C程序”这是一款比较好的程序,附的资料比较多,有Protel格式原理图、PCB图,有源程序、设计论文报告、元件清单等,制作非常容易,只要按图焊接好元件,基本不需要调试,最远可测量到6.99米,报警距离还可调节。 这里还有制作调试好的实物,你找找看。

阅读全文

与32单片机超声波测距程序代码相关的资料

热点内容
波形分析算法 浏览:526
php论坛实训报告 浏览:403
java日期字符串转换成日期 浏览:135
linuxsftp连接 浏览:934
光伏日发电量算法 浏览:125
小肚皮app怎么才有vip 浏览:616
php全角转换半角 浏览:927
java字符序列 浏览:539
杭州编译分布式存储区块链 浏览:575
材料压缩曲线 浏览:247
linux命令排序 浏览:151
手机热点加密为啥连接不上电脑 浏览:979
编译器合并计算 浏览:959
android音频曲线 浏览:343
linuxftp自动登录 浏览:802
运行编译后网页 浏览:70
阅读app怎么使用 浏览:319
centos防火墙命令 浏览:432
命令行变更 浏览:332
linux设备和驱动 浏览:207