一个单片机同时控制三个超声波测距模块,程序怎样实现呢

一个单片机同时控制三个超声波测距模块,程序怎样实现呢,第1张

只不过是单片机上接了三个模块,是不可能同时控制的,写程序时,分别对三个模块进行测量,因单片机的速度是非常快的,从外观上看就好像是同时测量的,可程序是不可能同时执行的,只是互相间隔的时间极短,表面上就同时了。确切说,从微观上是分时控制,从宏观上看是同时了。

//晶振=8M

//MCU=STC10F04XE

//P00-P06共阳数码管引脚

//Trig = P1^0

//Echo = P3^2

#include <reg52h> //包括一个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;

sfr P2M1 = 0X95;

sfr P2M0 = 0X96;

//

sbit Trig = P1^0; //产生脉冲引脚

sbit Echo = P3^2; //回波引脚

sbit test = P1^1; //测试用引脚

uchar codeSEG7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管0-9

uint distance[4]; //测距接收缓冲区

uchar ge,shi,bai,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);//等待测量的结果,周期65535毫秒(可用中断实现)

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秒=( 2Y米)/344 ==》X秒=00058Y米 ==》厘米=微秒/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=bai;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,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()

{ ucharbt ;

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;} /交换值

}

/

hc--sr04模块制作的超声波测距,我在电子乐屋上看到过两篇文章,一篇介绍的是用数码管显示,另外一篇介绍的是用LCD1602显示并带有温度补偿,而且还有仿真,文章介绍的比较好,你可以去看看,可能才你有帮助。

//超声波模块程序

//Trig = P2^0

//Echo = P3^2

#include <reg52h>

#define uchar unsigned char

#define uint unsigned int

//

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;

wela=1;

P0=0xf7;

wela=0;

dula=1;

P0=table[bai];

dula=0;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

wela=1;

P0=0xef;

wela=0;

dula=1;

P0=table[shi];

dula=0;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

dula=1;

P0=table[ge];

dula=0;

wela=1;

P0=0xdf;

wela=0;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

}

//

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=timeH256+timeL;

distance=time0172; //厘米

display(distance);

}

if(succeed_flag==0)

{

distance=0; //没有回波则清零

test = !test; //测试灯变化

}

}

}

//

//外部中断0,用做判断回波电平

void exter() interrupt 0 // 外部中断0是0号

{

timeH =TH1; //取出定时器的值

timeL =TL1; //取出定时器的值

succeed_flag=1;//至成功测量的标志

EX0=0; //关闭外部中断

}

//

//定时器1中断,用做超声波测距计时

void timer1() interrupt 3 //

{

TH1=0;

TL1=0;

}

转>

at89c2051制作的超声波测距源程序

· 文件版本: V10

· 开发商: 本站原创

· 文件来源: 本地

· 界面语言: 简体中文

· 授权方式: 免费

at89c2051制作的超声波测距源程序

关键词: 超声波测距

at89c2051制作的超声波测距源程序

#include <REG2051H>

#define k1 P3_4

#define csbout P3_5 //超声波发送

#define csbint P3_7 //超声波接收

#define csbc=0034

#define bg P3_3

unsigned char csbds,opto,digit,buffer[3],xm1,xm2,xm0,key,jpjs;//显示标识

unsigned char convert[10]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9段码

unsigned int s,t,i, xx,j,sj1,sj2,sj3,mqs,sx1;

bit cl;

void csbcj();

void delay(j); //延时函数

void scanLED(); //显示函数

void timeToBuffer(); //显示转换函数

void keyscan();

void k1cl();

void k2cl();

void k3cl();

void k4cl();

void offmsd();

void main() //主函数

{

EA=1; //开中断

TMOD=0x11; //设定时器0为计数,设定时器1定时

ET0=1; //定时器0中断允许

ET1=1; //定时器1中断允许

TH0=0x00;

TL0=0x00;

TH1=0x9E;

TL1=0x57;

csbds=0;

csbint=1;

csbout=1;

cl=0;

ōpto=0xff;

jpjs=0;

sj1=45;

sj2=200;

sj3=400;

k4cl();

TR1=1;

while(1)

{

keyscan();

if(jpjs<1)

{

csbcj();

if(s>sj3)

{

buffer[2]=0x76;

buffer[1]=0x76;

buffer[0]=0x76;

}

else if(s<sj1)

{

buffer[2]=0x40;

buffer[1]=0x40;

buffer[0]=0x40;

}

else timeToBuffer();

}

else timeToBuffer(); //将值转换成LED段码

offmsd();

scanLED(); //显示函数

if(s<sj2)

bg=0;

bg=1;

}

}

void scanLED() //显示功能模块

{

digit=0x04;

for( i=0; i<3; i++) //3位数显示

{

P3=~digit&opto; //依次显示各位数

P1=~buffer; //显示数据送P1口

delay(20); //延时处理

P1=0xff; //P1口置高电平(关闭)

if((P3&0x10)==0) //判断3位是否显示完

key=0;

digit>>=1; //循环右移1位

}

}

void timeToBuffer() //转换段码功能模块

{

xm0=s/100;

xm1=(s-100xm0)/10;

xm2=s-100xm0-10xm1;

buffer[2]=convert[xm2];

buffer[1]=convert[xm1];

buffer[0]=convert[xm0];

}

void delay(i)

{

while(--i);

}

void timer1int (void) interrupt 3 using 2

{

TH1=0x9E;

TL1=0x57;

csbds++;

if(csbds>=40)

{

csbds=0;

cl=1;

}

}

void csbcj()

{

if(cl==1)

{

TR1=0;

TH0=0x00;

TL0=0x00;

i=10;

while(i--)

{

csbout=!csbout;

}

TR0=1;

i=mqs; //盲区

while(i--)

{

}

i=0;

while(csbint)

{

i++;

if(i>=2450) //上限值

csbint=0;

}

TR0=0;

TH1=0x9E;

TL1=0x57;

t=TH0;

t=t256+TL0;

s=tcsbc/2;

TR1=1;

cl=0;

}

}

void keyscan() //健盘处理函数

{

xx=0;

if(k1!=1) // 判断开关是否按下

{

delay(400); //延时去抖动

if(k1!=1) // 判断开关是否按下

{

while(!k1)

{

delay(30);

xx++;

}

if(xx>2000)

{

jpjs++;

if(jpjs>4)

jpjs=0;

}

xx=0;

switch(jpjs)

{

case 1: k1cl();break;

case 2: k2cl();break;

case 3: k3cl();break;

case 4: k4cl();break;

}

}

}

}

void k1cl()

{

sj1=sj1+5;

if(sj1>100)

sj1=30;

s=sj1;

}

void k2cl()

{

sj2=sj2+5;

if(sj2>500)

sj2=40;

s=sj2;

}

void k3cl()

{

sj3=sj3+10;

if(sj3>500)

sj3=100;

s=sj3;

}

void k4cl()

{

sx1=sj1-1;

sx1=sx1/csbc;

mqs=sx1/45;

}

void offmsd()

{

if (buffer[0] == 0x3f)

buffer[0] = 0x00;

}

这个是这样的 定时器记得数有十六位 前面八位叫高八位 也就是TH0 后面八位是第八位 也就是TL0 你取数的时候肯定要把十六位的都取出来 time=TH0; 这一行是取高八位赋给time 接下来time=(time<<8)|TL0;这一行 是把先取出来得八位左移 然后或上低八位构成了十六位 这样的数据才是准确的 举个例子 如果计数器记得数是 01100010 11010101

time=01100010后 进行左移 此时time=01100010 00000000(左移后补零)然后进行或运算

01100010 11010101 或上

01100010 00000000就等到了你想要的结果了 对吧 如果 希望能帮到你 谢谢

以上就是关于一个单片机同时控制三个超声波测距模块,程序怎样实现呢全部的内容,包括:一个单片机同时控制三个超声波测距模块,程序怎样实现呢、求个51单片机超声波测距(距离+报警)的c程序、超声波测距程序问题,下面一段程序,我打开开关时,是可以测量的,当p0.0的灯两以后就不能工作了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10078630.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存