A. 求一个51 超声波测距 c语言的完整程序,高分求
//晶振=8M
//MCU=STC10F04XE
//P0.0-P0.6共阳数码管引脚
//Trig = P1^0
//Echo = P3^2
#include <reg52.h> //包括一个52标准内核的头文件
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
//***********************************************
sfr CLK_DIV = 0x97; //为STC单片机定义,系统时钟分频
//为STC单片机的IO口设置地址定义
sfr P0M1 = 0X93;
sfr P0M0 = 0X94;
sfr P1M1 = 0X91;
sfr P1M0 = 0X92;
sfrP2M1 = 0X95;
sfrP2M0 = 0X96;
//***********************************************
sbit 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-9
uint distance[4]; //测距接收缓冲区
uchar ge,shi,,temp,flag,outcomeH,outcomeL,i; //自定义寄存器
bit succeed_flag; //测量成功标志
//********函数声明
void conversion(uint temp_data);
void delay_20us();
//void pai_xu();
void main(void) // 主程序
{ uint distance_data,a,b;
uchar CONT_1;
CLK_DIV=0X03; //系统时钟为1/8晶振(pdf-45页)
P0M1 = 0; //将io口设置为推挽输出
P1M1 = 0;
P2M1 = 0;
P0M0 = 0XFF;
P1M0 = 0XFF;
P2M0 = 0XFF;
i=0;
flag=0;
test =0;
Trig=0; //首先拉低脉冲输入引脚
TMOD=0x11; //定时器0,定时器1,16位工作方式
TR0=1; //启动定时器0
IT0=0; //由高电平变低电平,触发外部中断
ET0=1; //打开定时器0中断
//ET1=1; //打开定时器1中断
EX0=0; //关闭外部中断
EA=1; //打开总中断0
while(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; //启动定时器1
EA=1;
while(TH1 < 30);//等待测量的结果,周期65.535毫秒(可用中断实现)
TR1=0; //关闭定时器1
EX0=0; //关闭外部中断
if(succeed_flag==1)
{
distance_data=outcomeH; //测量结果的高8位
distance_data<<=8; //放入16位的高8位
distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
distance_data*=12; //因为定时器默认为12分频
distance_data/=58; //微秒的单位除以58等于厘米
} //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
if(succeed_flag==0)
{
distance_data=0; //没有回波则清零
test = !test; //测试灯变化
}
/// distance[i]=distance_data; //将测量结果的数据放入缓冲区
/// i++;
/// if(i==3)
/// {
/// distance_data=(distance[0]+distance[1]+distance[2]+distance[3])/4;
/// pai_xu();
/// distance_data=distance[1];
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);
}
/// i=0;
///}
}
}
//***************************************************************
//外部中断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=0xfd;flag++;break;
case 0x01:P0=shi;P2=0xfe;flag++;break;
case 0x02:P0=;P2=0xfb;flag=0;break;
}
}
//*****************************************************************
/*
//定时器1中断,用做超声波测距计时
timer1() interrupt 3 // 定时器0中断是1号
{
TH1=0;
TL1=0;
}
*/
//******************************************************************
//显示数据转换程序
void conversion(uint temp_data)
{
uchar ge_data,shi_data,_data ;
_data=temp_data/100 ;
temp_data=temp_data%100; //取余运算
shi_data=temp_data/10 ;
temp_data=temp_data%10; //取余运算
ge_data=temp_data;
_data=SEG7[_data];
shi_data=SEG7[shi_data];
ge_data =SEG7[ge_data];
EA=0;
= _data;
shi = shi_data;
ge = ge_data ;
EA=1;
}
//******************************************************************
void delay_20us()
{ uchar bt ;
for(bt=0;bt<100;bt++);
}
/*
void pai_xu()
{ uint t;
if (distance[0]>distance[1])
{t=distance[0];distance[0]=distance[1];distance[1]=t;} /*交换值
if(distance[0]>distance[2])
{t=distance[2];distance[2]=distance[0];distance[0]=t;} /*交换值
if(distance[1]>distance[2])
{t=distance[1];distance[1]=distance[2];distance[2]=t;} /*交换值
}
*/
这是个用过的程序,引脚和参数你自己调一下吧,附件里有1602显示的内容,希望对你有用。
B. 基于单片机超声波测距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; //数码管位选定义
答案: 是
C. 帮忙做一个超音波测距仪程序,c语言和汇编语言都行
这里有一个超声波测距程序,供参考:
#include<reg52.H>//器件配置文件
#include<intrins.h>
//传感器接口
sbitRX=P3^2;
sbitTX=P3^3;
//按键声明
sbitS1=P1^4;
sbitS2=P1^5;
sbitS3=P1^6;
//蜂鸣器
sbitFeng=P2^0;
sbitW1=P1^0;
sbitW2=P1^1;
sbitW3=P1^2;
sbitW4=P1^3;
//变量声明
unsignedinttime=0;
unsignedinttimer=0;
unsignedcharposit=0;
unsignedlongS=0;
unsignedlongBJS=50;//报警距离80CM
//模式0正常模式1调整
charMode=0;
bitflag=0;
bitflag_KEY=0;
unsignedcharconstdiscode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff/*-*/}; //数码管显示码0123456789-和不显示
//unsignedcharconstpositon[4]={0xfd,0xfb,0xf7,0xfe}; //位选
unsignedchardisbuff[4] ={0,0,0,0}; //数组用于存放距离信息
unsignedchardisbuff_BJ[4] ={0,0,0,0};//报警信息
voidDisplay();
//延时20ms(不精确)
voiddelay(void)
{
unsignedchara,b,c;
for(c=2;c>0;c--)
for(b=38;b>0;b--)
for(a=60;a>0;a--);
}
//按键扫描
voidKey_()
{
if(flag_KEY==0)
{
if(Mode!=0)
{
//+
if(S1==0)
{
delay(); //延时去抖
if(S1==0)
{
BJS++; //报警值加
flag_KEY=1;
if(BJS>=151)//最大151
{
BJS=0;
}
// while(S1==0)
// Display();
}
}
//-
if(S2==0)
{
delay();
if(S2==0)
{
BJS--; //报警值减
flag_KEY=1;
if(BJS<=1) //最小1
{
BJS=150;
}
// while(S2==0)
// Display();
}
}
}
//功能
if(S3==0) //设置键
{
delay();
if(S3==0)
{
Mode++; //模式加
flag_KEY=1;
if(Mode>=2) //加到2时清零
{
Mode=0;
}
// while(S3==0)
// Display();
}
}
}
if((P1&0x70)==0x70)
{
flag_KEY=0;
}
}
/**********************************************************************************************************/
//扫描数码管
voidDisplay(void)
{
//正常显示
if(Mode==0)
{
P0=0x00;//关闭显示
if(posit==1)//数码管的小数点
{
P0=(discode[disbuff[posit]])|0x80;//按位或,最高位变为1,显示小数点
}
elseif(posit==0)
{
P0=~discode[11];
}
else
{
P0=discode[disbuff[posit]];
}
switch(posit)
{
case0:W1=0;W2=1;W3=1;W4=1;break;
case1:W1=1;W2=0;W3=1;W4=1;break;
case2:W1=1;W2=1;W3=0;W4=1;break;
case3:W1=1;W2=1;W3=1;W4=0;break;
}
posit++;
if(posit>3) //每进一次显示函数,变量加1
posit=0; //加到3时清零
}
//报警显示
else
{
P0=0x00;
if(posit==1)//数码管的小数点
{
P0=(discode[disbuff_BJ[posit]])|0x80;
}
elseif(posit==0)
{
P0=0x76; //显示字母
}
else
{
P0=discode[disbuff_BJ[posit]];
}
switch(posit)
{
case0:W1=0;W2=1;W3=1;W4=1;break;
case1:W1=1;W2=0;W3=1;W4=1;break;
case2:W1=1;W2=1;W3=0;W4=1;break;
case3:W1=1;W2=1;W3=1;W4=0;break;
}
posit++;
if(posit>3)
posit=0;
}
}
/**********************************************************************************************************/
//计算
voidConut(void)
{
time=TH0*256+TL0; //读出T0的计时数值
TH0=0;
TL0=0; //清空计时器
S=(time*1.7)/100;//算出来是CM
//声音的速度是340m/s,时间的单位是us,计算到秒需要将时间数据/1000000,
//长度=速度*时间,340*time/1000000,长度数据单位是m转换成cm需要乘以100得到340*time/10000,
//小数点都向左移两位得到3.4*time/100,因为超声波是往返了,所以再除以2,得到距离数据(time*1.7)/100
if(Mode==0) //非设置状态时
{
if((S>=700)||flag==1)//超出测量范围显示“-”
{
Feng=0; //蜂鸣器报警
flag=0;
disbuff[1]=10; //“-”
disbuff[2]=10; //“-”
disbuff[3]=10; //“-”
}
else
{
//距离小于报警距
if(S<=BJS)
{
Feng=0; //报警
}
else//大于
{
Feng=1; //关闭报警
}
disbuff[1]=S%1000/100; //将距离数据拆成单个位赋值
disbuff[2]=S%1000%100/10;
disbuff[3]=S%1000%10%10;
}
}
else
{
Feng=1;
disbuff_BJ[1]=BJS%1000/100;
disbuff_BJ[2]=BJS%1000%100/10;
disbuff_BJ[3]=BJS%1000%10%10;
}
}
/**********************************************************************************************************/
//定时器0
voidzd0()interrupt1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/**********************************************************************************************************/
//定时器1
voidzd3()interrupt3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8;
TL1=0x30; //定时2ms
Key_(); //扫描按键
Display(); //扫描显示
timer++; //变量加
if(timer>=400) //400次就是800ms
{
timer=0;
TX=1; //800MS启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
/**********************************************************************************************************/
//主函数
voidmain(void)
{
TMOD=0x11; //设T0为方式1
TH0=0;
TL0=0;
TH1=0xf8; //2MS定时
TL1=0x30;
ET0=1; //允许T0中断
ET1=1; //允许T1中断
TR1=1; //开启定时器
EA=1; //开启总中断
while(1)
{
while(!RX); //当上次接收完波后,RX引脚是低电平,取反就是1,此while成立,反复判断RX状态。当RX没有接收到返回波时是高电平,取反就是0,此while不成立,跳出
TR0=1; //开启计数
while(RX); //当RX没有接收到返回波,此while成立,程序停在这里一直判断RX状态。当RX接收到返回波,RX引脚变为低电平,此while不成立,跳出
TR0=0; //停止计数
Conut(); //计算
}
}
D. 单片机超声波雷达测距的C语言程序设计,具体要求看问题补充
你到网络文库中找找,会找到很多的。你也可到淘宝网上找一下:“单片机超声波测距模块电子设计制作C程序”这是一款比较好的程序,附的资料比较多,有Protel格式原理图、PCB图,有源程序、设计论文报告、元件清单等,制作非常容易,只要按图焊接好元件,基本不需要调试,最远可测量到6.99米,报警距离还可调节。 这里还有制作调试好的实物,你找找看。
E. 51单片机 HC-SR04超声波测距 我写的C语言代码,请问
1、HC-SR04使用方法:给触发端子trig一个10us以上的高电平即可触发,触发后echo端子将接受到高电平,高电平的持续时间就是测距的往返时间。
2、例程:
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
/*位定义*/
sbitCHUFA=P0^1;//位定义超声波触发端(10us以上高电平触发)
sbitJIESHOU=P0^3;//接收端(接受高电平)
sbitBEEP=P2^0;//蜂鸣器
sbitOUT0=P3^2;//外部中断0
ucharJS_FLAG;//接收标志
uintCF_TIME,t0,t1,shu;
/*函数声明*/
voidtimer0();
voidint0();
voiddisplay(uint);
main(){
CHUFA=0;//初始化拉低触发端和接收端电平
JIESHOU=0;
JS_FLAG=0;
CF_TIME=15;//初始化触发时间(大于10us)
TMOD=0x11;//定时器方式选择
EA=1;//开总中断
ET0=1;//开定时器0中断
EX0=1;//开外部中断0
IT0=0;//外部中断选择下降沿触发
//JIESHOU=1;
while(1){
OUT0=JIESHOU;//外部中断0被赋值为接收端信号,当出现下降沿是触发外部中断0
if(JS_FLAG==0){//如果没有接收到高电平则触发
CHUFA=1;
while(CF_TIME--);//10us以上高电平触发传感器
}
if(JIESHOU==1){
TR0=1;//如果接收端收到高电平则启动定时器
JS_FLAG=1;//并且标志位置1
BEEP=0;//蜂鸣器响
}
display(t1);//显示测量时间(秒)
}
}
/*定时器0中断程序*/
voidtimer0()interrupt1{
TH0=(65536-10000)/256;//装初值10ms
TL0=(65536-10000)%256;
t0++;//每进入一次中断t0加1
}
/*外部中断0中断程序*/
voidint0()interrupt0{
TR0=0;//一旦进入外部中断0,说明接收端收到下降沿信号。关闭定时器0
JS_FLAG=0;//接收标志位置0
BEEP=1;//关闭蜂鸣器
t1=t0*10/1000;//测量时间为进入定时器中断次数t0乘以每次时间10ms,除以1000化为秒为单位
t0=0;//t0清零
}
/*数码管显数函数*/
voiddisplay(uintshu){
//数码管显示函数
}