找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2823|回复: 2
收起左侧

52单片机超声波测距数码管显示四位数

[复制链接]
ID:397287 发表于 2018-9-28 18:27 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include<intrins.h>  //包涵了_nop_()函数声明

typedef unsigned int unint;
typedef unsigned char unchar;

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

sbit dula = P2^6;
sbit wela = P2^7;
//TRIG 为控制端
sbit TRIG = P1^6; //超声波的 TRIG端  插在了P1.6口
//ECHO 为接收端
sbit ECHO = P1^7; //超声波的 ECHO端  插在了P1.7口
/*还有vcc,gnd 就直接插在了单片机 vcc 和gnd 端口了
*也可以将其插在I/O引脚中 将插 vcc的引脚置高电平,gnd置低电平*/

unchar flag = 0; //标志定时器是否溢出

void delayed(unsigned int x); //延时xmS
void delay_50us(); // 延时20ms
void init_time();  //初始化定时器的函数
void display(int num); //数码管显示函数

void main()
{
    int x;  //用到就知道干什么用了  
            //写程序时也不用急着将所有变量都定义了  用到一个定义一个
    unint time_data,out_TH0,out_TL0;

    TRIG = 0; // 先给控制端初始化为0

    while(1)
    {
    /*超声波传感器的使用方法:
    控制口发一个10US 以上的高电平,就可以在接收口等待高电平输出.
    一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的,
    此时就为此次测距的时间,方可算出距离.如此不断的周期测,
    就可以达到你移动测量的值了*/
        init_time(); //初始化定时器
        flag = 0;    //置溢出标志位为0
        //控制口发一个10US 以上的高电平
        TRIG = 1;   
        delay_50us();
        TRIG = 0;
        //等待接收端出现高电平
        while(!ECHO);
        TR0 = 1; //启动计时器 开始计时
        while(ECHO); //等待高电平结束
        TR0 = 0; //关闭低电平

        out_TH0 = TH0; //取定时器的值
        out_TL0 = TL0;
        out_TH0 <<= 8;  //右移8位
        time_data = out_TH0 | out_TL0; //合并为16位的值  
        time_data /= 58/10; // 微秒/58 = 厘米
        /*    为什么微秒/58 = 厘米
        *     Y米 = (X秒 * 344) 2
        *     X秒 = (2 * Y米) / 344
        *     X秒 = 0.0058*Y米
        *     厘米 = 微秒/58     */
        if(flag == 1) //如果定时器溢出 则超出超声波测量范围
        {
            display(-1);
        }
        else
        {
            for(x =5; x >=0; x--)//加此循环只是为了将结果在数码管上停留时间长点便于观察
            {
                display(time_data);
            }
        }   
    }

}

void timer0() interrupt 1 //中断函数
{
    flag=1; //溢出标志位置1
}

void delayed(unsigned int x) //延时xmS
{
    unsigned int i,j;
    for(i = x; i > 0; i--)
    {
        for(j = 113; j >0; j--);
    }
}

void init_time()
{
    TMOD = 0x01; //选择定时器0工作 工作方式为方式1
    TH0 = 0; //装初值0
    TL0 = 0;

    TF0 = 0; //中断溢出标志位
    ET0 = 1; //开定时器中断
    EA = 1; // 开总中断
}

void display(int num) //显示函数
{
    if(num == -1) //当超出范围 显示999
    {
        dula = 1;
        P0 = table[6];
        dula = 0;
        P0 = 0xff;
        wela = 1;
        P0 = 0xc0;
                wela=1;
                  P0 = 0xf7;
      wela = 0;
    }
    else  //显示到前三个数码管上  因为测距范围为2-400cm 故3位即可
    {
        unchar t;
                  t = num / 1000; //取百位

        dula = 1;
        P0 = table[t];
        dula = 0;
        P0 = 0xff;
        wela = 1;
        P0 = 0xfe;
        wela = 0;
        delayed(10);
        t = num / 100; //取百位

        dula = 1;
        P0 = table[t];
        dula = 0;
        P0 = 0xff;
        wela = 1;
        P0 = 0xfd;
        wela = 0;
        delayed(10);

        t = num/10%10;  //取十位
        dula = 1;
        P0 = table[t];
        dula = 0;
        P0 = 0xff;
        wela = 1;
        P0 = 0xfb;
        wela = 0;
        delayed(10);

        t = num %10;
        dula = 1;
        P0 = table[t]; //取个位
        dula = 0;
        P0 = 0xff;
        wela = 1;
        P0 = 0xf7;
        wela = 0;
        delayed(10);
…………限于本文篇幅 余下代码请从51黑下载附件…………

此仿真为

此仿真为

cj.rar

17.45 KB, 下载次数: 48, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:397622 发表于 2018-12-24 04:03 | 显示全部楼层
浪费了5个币
回复

使用道具 举报

ID:3802 发表于 2019-1-23 15:50 | 显示全部楼层
浪费了5个币
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表