一、原理部分
使用超声波需要用跳线帽连接1-3和2-4,实物图如上。原理图如下。
根据原理图可以看到如图所示,P10发射,P11接收
流程:
- 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;
}
}
- 初始化定时器
void waveinit()//初始化定时器1
{
TMOD |= 0x10; //设置定时器1为16位计数器
TL1 = 0; //设置定时初值
TH1 = 0; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 0; //关闭定时器1
}
TMOD 寄存器的配置
- 启动定时器,检查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();
}
}