蓝桥杯——超声波模块

一、原理部分

在这里插入图片描述
使用超声波需要用跳线帽连接1-3和2-4,实物图如上。原理图如下。
在这里插入图片描述
根据原理图可以看到如图所示,P10发射,P11接收
流程:

  1. TX发送8个40KHZ的超声波信号
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
sbit TX = P1^0;	//发送
sbit RX = P1^1;	//接收
void sent_wave()
{
	uchar i;
	for(i=0;i<8;i++)
	{
		TX = 1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		TX = 0;	
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	}
}
  1. 初始化定时器
void waveinit()//初始化定时器1
{
	TMOD |= 0x10;	//设置定时器1为16位计数器
	TL1 = 0;		//设置定时初值
	TH1 = 0;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//关闭定时器1
}

TMOD 寄存器的配置

在这里插入图片描述
在这里插入图片描述

  1. 启动定时器,检查RX == 0(超声波返回RX低电平)和TF1== 1
    time获取定时器的时间,距离=(时间×340÷2÷1000)cm
    若RX == 0:停止定时器,计算距离distance = time*0.017
    若TF1 == 1:溢出,清除TF1
void return_dis()
{
	 sent_wave();
	 TR1 = 1;//打开定时器1
	 while(RX == 1&&TF1 == 0);//等待收到返回信号或者溢出
	 TR1 = 0;//
	 if(RX == 1&&TF1 == 1)//溢出
	 {
	 	dis = 999;
		TF1 = 0;
	 }
	 else if(RX == 0&&TF1 == 0)//收到返回信号,计算时间
	 {
			time = TH1*256+TL1;
			dis = (uint)time*0.017;
			TH1 = 0;             //清零
			TL1 = 0;
	 }
}

标志位

位数据类型:bit
通常用来做标志位,只有0和1两个状态。可以简单的理解为当标志位为1时执行某些操作,执行完后对标志位清零,可以联系各个模块。下面这篇博客的代码使用了标志位控制蜂鸣器和继电器。
标志位控制蜂鸣器和继电器

二、代码部分

二、代码部分
实验平台:CT107D
实验芯片:stc15f2k60s2
实验现象:数码管实时显示超声波测得的距离
代码如下

#include<stc15f2k60s2.h>
#include<intrins.h>

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

sbit buzz = P0^6;
sbit TX = P1^0;	//发送
sbit RX = P1^1;	//接收
bit wave_flag = 0;

uchar code duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};//定义段码数组
uchar disbuff[8];//定义显示数字数字
uint time,dis;

void closebuzz()
{
	P2 = 0xa0;
	buzz = 0;
	P2 = 0x00;
}

void waveinit()//初始化定时器1
{
	TMOD |= 0x10;	//设置定时器1为16位计数器
	TL1 = 0;		//设置定时初值
	TH1 = 0;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//关闭定时器1
}

void sent_wave()
{
	uchar i;
	for(i=0;i<8;i++)
	{
		TX = 1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		TX = 0;	
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	}
}

void return_dis()
{
	 sent_wave();
	 TR1 = 1;//打开定时器1
	 while(RX == 1&&TF1 == 0);//等待收到返回信号或者溢出
	 TR1 = 0;//
	 if(RX == 1&&TF1 == 1)//溢出
	 {
	 	dis = 999;
		TF1 = 0;
	 }
	 else if(RX == 0&&TF1 == 0)//收到返回信号,计算时间
	 {
			time = TH1*256+TL1;
			dis = (uint)time*0.017;//时间转化为距离
			TH1 = 0;             //清零
			TL1 = 0;
	 }
}

void shownum()//显示数字函数
{
	disbuff[0]=10;
	disbuff[1]=10;
	disbuff[2]=10;
	disbuff[3]=10;
	disbuff[4]=10;
	disbuff[5]=dis/100;
	disbuff[6]=dis%100/10;
	disbuff[7]=dis%10;
}

void display()//数码管扫描函数
{
	static uchar index = 0;
	P2 = 0xe0;
	P0 = 0xff;
	P2 = 0x00;

	P2 = 0xc0;
	P0 = 1<<index;
	P2 = 0x00;

	P2 = 0xe0;
	P0 = ~duan[disbuff[index]];
	P2 = 0x00;

	index++;
	index &= 0x07;

}

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1 ; 
}

void time0() interrupt 1
{
	static uchar count;
	display();
	if(count++ >= 200)//每200ms读取一次距离
	{
		wave_flag = 1; 
	}
}


void main()
{
	closebuzz();
	Timer0Init();
	waveinit();
	while(1)
	{
		if(wave_flag == 1)
		{
			 return_dis();
			 wave_flag = 0;
		}
		shownum();
	}

}


发布了16 篇原创文章 · 获赞 26 · 访问量 5733

猜你喜欢

转载自blog.csdn.net/FuckerGod/article/details/104044875
今日推荐