找回密码
 立即注册
查看: 63|回复: 0

写了一个超声波测距程序,为什么测量不准确?

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2026-04-10 01:15:45
已绑定手机

12

主题

8

回帖

98

积分

注册会员

积分
98
发表于 2026-4-9 21:57:55 | 显示全部楼层 |阅读模式


大佬帮我看看,哪里出了问题,超声波测距测量不准确。感觉每次测量结果显示的数字是随机数。


/*******************************************************
*  STC32G12K128 超声波测距 + 4位共阴数码管显示
*  HC-SR04 + 内部IRC 33.1776MHz
******************************************************/

#include "STC32G.H"
#include <intrins.h>

#define SYSCLK          33177600     // 内部IRC频率
#define SOUND_SPEED     0.0343       // cm/us

/*---------------- 全局变量 ----------------*/
bit     echo_flag = 0;  // 回波标志
sbit   P3_3 = P3^3;
unsigned long time_us = 0;           // 回波高电平时间(us)
float   distance_cm = 0.0;           // 距离(cm)

/*---------------- 数码管段码(共阴) ----------------*/
unsigned char code seg_tab[10] =
{
    0x3f, // 0
    0x06, // 1
    0x5b, // 2
    0x4f, // 3
    0x66, // 4
    0x6d, // 5
    0x7d, // 6
    0x07, // 7
    0x7f, // 8
    0x6f  // 9
};

/*---------------- 延时函数 ----------------*/
void DelayMs(unsigned int ms)
{
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 110; j++);
}

/*---------------- IO 初始化 ----------------*/
void IO_Init(void)
{
    /* P1:数码管段选 */
    P2M0 = 0xFF;
    P2M1 = 0x00;        // 推挽输出
    P2 = 0xFF;

    /* P2:数码管位选(低有效) */
    P1M0 = 0x00;
    P1M1 = 0x00;
    P1 = 0xFF;

    /* P3.3 Trig */
    P3M0 &= ~(1 << 3);
    P3M1 &= ~(1 << 3);
    P3_3 = 0;

    /* P3.2 Echo (INT0) */
    P3M0 &= ~(1 << 2);
    P3M1 |=  (1 << 2);  // 仅输入
}

/*---------------- 定时器0(1us基准) ----------------*/
void Timer0_Init(void)
{
    TMOD |= 0x01;       // 模式1
    TH0 = 0;
    TL0 = 0;
   ET0 = 1;
   EA  = 1;
}

/*---------------- INT0 外部中断(Echo) ----------------*/
void Int0_Init(void)
{
    IT0 = 1;            // 下降沿触发
    EX0 = 1;
}

void Int0_ISR(void) interrupt 0
{
    if(echo_flag)
    {
        TR0 = 0;
        time_us = TH0 * 256 + TL0;
        echo_flag = 0;
    }
}

/*---------------- 超声波触发 ----------------*/
void HC_SR04_Trigger(void)
{
    TR0 = 0;
    TH0 = 0;
    TL0 = 0;

    P3_3 = 1;
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_(); _nop_();
          _nop_(); _nop_(); _nop_(); _nop_();
          _nop_(); _nop_(); _nop_(); _nop_();
          _nop_(); _nop_(); _nop_(); _nop_();
    P3_3 = 0;

    echo_flag = 1;
    TR0 = 1;
}

/*---------------- 距离计算 ----------------*/
void Distance_Calc(void)
{
    if(time_us > 0)
    {
        distance_cm = (time_us * SOUND_SPEED) / 2.0;
    }
}

/*---------------- 数码管显示(动态扫描) ----------------*/
void Display(unsigned int num)
{
    unsigned char i;
    unsigned int disp[4];

    disp[0] = num / 1000;
    disp[1] = num / 100 % 10;
    disp[2] = num / 10 % 10;
    disp[3] = num % 10;

    for(i = 0; i < 4; i++)
    {
        P1 = ~(4 << i);          // 位选
        P2 = seg_tab[disp];   // 段选
        DelayMs(1);
        P2 = 0x00;               // 消隐
    }
}

/*---------------- 主函数 ----------------*/
void main(void)
{
    IO_Init();
    Timer0_Init();
    Int0_Init();
    EA = 1;

    while(1)
    {
        HC_SR04_Trigger();      // 触发测距
        DelayMs(1);                          // 等待回波
                       
        Distance_Calc();         // 计算距离

        Display((unsigned int)distance_cm);

        DelayMs(5);            // 刷新周期
    }
}

1.jpg
2.jpg
3.jpg
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-9 05:41 , Processed in 0.110160 second(s), 49 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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