自学内容网 自学内容网

蓝桥杯单片机学习总结(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)!