蓝桥杯单片机学习总结(Day15 超声波测距)
开启超声波模块测距方法:
X20106A是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。当CX20106A接收到40KHz的信号时(第五脚200K的电阻决定了其频率为40KHz),会在OUT脚输出一个低电平下降脉冲。这个信号甚至可以接到单片机的外部中断引脚,作为中断信号的输入,若需要发送超声波信号,那么我们就需要产生8个40KHz的信号(40KHz周期就是25us,由于是个奇数,所以取周期为24us,半个周期12us);
sbit TX=P1^0; //超声波发送端
sbit RX=P1^1; //超声波接收端
void Send_Wave()
{
int i;
for(i=0;i<=7;i++) //发送8个脉冲
{
TX=1; //发送
Delay12us();
TX=0;
Delay12us();
}
}
实例代码与解释:
#include <STC15F2K60S2.H>
#include "intrins.h"
#include "absacc.h"
sbit TX = P1 ^ 0; //发射引脚
sbit RX = P1 ^ 1; //接收引脚
code unsigned char tab[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff};
unsigned char buf[8] = {10, 10, 10, 10, 10, 10, 10, 10}; //段
bit flag;//更新标志位
void send_wave(void);
void display(void);
//12us延时,@11.0592MHz
void Delay12us()
{
unsigned char i;
_nop_();
_nop_();
_nop_();
i = 30;
while (--i);
}
//定时器0初始化+开启中断
void Timer0Init(void)//2毫秒@11.0592MHz
{
AUXR |= 0x80;//定时器时钟1T模式
TMOD &= 0xF0;//设置定时器模式
TL0 = 0x9A;//设置定时初值
TH0 = 0xA9;//设置定时初值
TF0 = 0;//清除TF0标志
TR0 = 1;//定时器0开始计时
EA = 1;
ET0 = 1; //打开定时器0中断
}
void main(void)
{
unsigned int dist;
unsigned int time = 0;
Timer0Init();
TH1 = 0;
TL1 = 0;//计时器1计时,此处定时器0为定时扫描的作用
while(1)
{
if(flag)
{
flag = 0;
send_wave(); //发送方波信号
//计算接收所发送的方波信号的时间
TR1 = 1; //启动计时
while((RX == 1) && (TF1 == 0)); //等待收到脉冲,没有计满溢出
TR1 = 0; //关闭计时
//发生溢出
if(TF1 == 1)
{
TF1 = 0;
dist=9999; //无返回
}
else
{
/** 计算时间方法 */
time = TH1;
time <<= 8;
time |= TL1;
dist= (unsigned int)(time * 0.017); //计算距离
}
TH1 = 0;//初始化
TL1 = 0;
}
/** 数据处理*/
buf[5] = dist/ 100;
buf[6] = dist% 100 / 10;
buf[7] = dist% 10;
}
}
//定时器0中断服务函数
void Timer0_Proc() interrupt 1
{
static unsigned int ms = 0;
display(); //2ms执行一次
if(++ms== 200)
{
flag = 1;
ms = 0;
}
}
//显示函数
void display(void)
{
static unsigned char com = 0;
P2 = ((P2 & 0x1f) | 0xe0);
P0 = 0xff;
P2 &= 0x1f;
P2 = ((P2 & 0x1f) | 0xc0);
P0 = (1 << com);
P2 &= 0x1f;
P2 = ((P2 & 0x1f) | 0xe0);
P0 = tab[buf[com]];
P2 &= 0x1f;
P2 = ((P2 & 0x1f) | 0xA0);
P0 = 0x00;
P2 &= 0x1f;
if(++com == 8)
{
com = 0;
}
}
//TX引脚发送40KHz方波信号驱动超声波发送探头
//使用软件延时注意RC振荡器频率
void send_wave(void)
{
unsigned char i = 8; //发送8个脉冲
do
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
while(i--);
}
实验总结:
需要持续接收信号的、持续扫描的已经可以总结出一个模板,那就是使用Timer0定时器的定时扫描,中断函数内的定时扫描标志flag,主函数内判断等操作共同构成。
原文地址:https://blog.csdn.net/2302_80724534/article/details/140614780
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!