- 打卡等级:偶尔看看I
- 打卡总天数:11
- 最近打卡:2026-04-10 01:15:45
已绑定手机
注册会员
- 积分
- 98
|
大佬帮我看看,哪里出了问题,超声波测距测量不准确。感觉每次测量结果显示的数字是随机数。
/*******************************************************
* 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); // 刷新周期
}
}
|
|