基于STC8G/H单片机HCSR04超声波模块测距,并通过串口字符串打印(RC频率12MHZ)
当下载完程序后,就可以在串口中看到超声波测试的距离距离。非常棒!!!!
STC8单片机简介:
STC8G/H系列是宏晶科技推出的高性能8位单片机,基于增强型8051内核,主频可达35MHz,单周期指令执行效率高。该系列集成丰富外设,如12位ADC、PWM、SPI、I2C、UART等,适用于工业控制、智能家居、消费电子等领域。STC8G/H支持宽电压工作(2.0V-5.5V),内置高精度RC振荡器,部分型号提供硬件USB接口。存储资源灵活,Flash容量从8KB到64KB可选,SRAM最高4KB,部分型号支持EEPROM。抗干扰能力强,符合工业级温度范围(-40℃~85℃)。
HCSR04模块简介:
HCSR04是一款常见的超声波测距模块,通过发射和接收超声波信号计算物体距离。其测量范围通常为2cm至400cm,精度可达3mm,工作电压为5V,
HCSR04引脚定义:
| 序号 | 针脚名称 | 功能描述 |
|---|---|---|
| 1 | VCC | 模块供电正极,典型工作电压(3.3~5)VDC。 |
| 2 | Trig | 触发端。 |
| 3 | Echo | 接收端,当接收到反射信号时,引脚产生一个脉冲。脉冲的长度与检测发射信号所需的时间成正比。 |
| 4 | GND | 模块供电负极。 |
HCSR04工作原理:
首先,先要发送一个触发信号(Trig端口)至少为10us。当有信号回来时信号输入口会有一个高电频的跳变,使用单片机内部定时器来计时看高电频持续时间有多长,用这个就能算出距离。
超声波距离计算公式:
distance = (float)time * 0.017;(单位cm)
这个乘法操作是在依据超声波传播的时间来计算距离。超声波在空气中的传播速度大约是 340m/s,也就是 34000cm/s。
因为超声波从发射到遇到障碍物再反射回来,所经过的路程是实际距离的两倍,所以计算实际距离时需要除以 2。
1 个机器周期的时间是 1/12000000 秒(假定单片机晶振频率为 12MHz),那么距离计算公式为 distance = (34000 * time * (1/12000000)) / 2,经过化简后得到 distance = time * 0.017这里的 0.017 就是经过化简后的系
电路连接 :
上面电路非常简单,接了一个二极管和一个超声波探头。比起STC89C52单片机,STC8无需外部复位电路,和外部晶振,也无需上拉电阻,可以直接使用dip封装的芯片。
完整代码:
#include <stc8.h>
#include <stdio.h>
// 类型定义
#define uchar unsigned char
#define uint unsigned int
// 引脚定义
sbit Trig = P3^5; // 超声波触发引脚
sbit Echo = P3^4; // 超声波接收引脚
sbit LED = P1^2; // 状态指示LED
// 全局变量
uint g_distance_cm; // 距离(厘米)
uint g_distance_mm; // 距离(毫米)
uint distance_array[6]; // 存储6次测量结果
#define DISTANCE_THRESHOLD 100 // 距离阈值(毫米)
// 函数声明
void Delay10ms(unsigned int c);
void Delay10us(unsigned int c);
void Uart1_Init(void);
void UART1_Send(unsigned char dat);
void UART1_SendString(char *str);
void main_Init();
void GetDistanceInMM();
uint GetDistanceSixTimesAndCalculateAverage();
// 延时10ms函数
void Delay10ms(unsigned int c) {
unsigned char i, j, k;
for (k = c; k > 0; k--) {
i = 156;
j = 213;
do {
while (--j);
} while (--i);
}
}
// 延时10us函数
void Delay10us(unsigned int c) {
unsigned char i, k;
for (k = c; k > 0; k--) {
i = 38;
while (--i);
}
}
// 串口1初始化(9600bps@12MHz)
void Uart1_Init(void) {
SCON = 0x50; // 8位数据,可变波特率
AUXR |= 0x40; // 定时器时钟1T模式
AUXR &= 0xFE; // 串口1选择定时器1为波特率发生器
TMOD &= 0x0F; // 设置定时器1为模式1
TL1 = 0xC7; // 设置定时初始值
TH1 = 0xFE; // 设置定时初始值
ET1 = 0; // 禁止定时器1中断
TR1 = 1; // 启动定时器1
}
// 串口发送一个字符
void UART1_Send(unsigned char dat) {
SBUF = dat; // 将数据写入串口发送缓冲区
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
}
// 串口发送字符串
void UART1_SendString(char *str) {
while (*str) { // 遍历字符串直到结束符
UART1_Send(*str++); // 发送当前字符并指向下一个
}
}
// 主初始化函数
void main_Init() {
P1M0 = 0x00; P1M1 = 0x00; // 设置P1口为准双向口
P3M0 &= ~0x30; P3M1 &= ~0x30; // 设置P3.4和P3.5为准双向口
Uart1_Init(); // 初始化串口
}
// 超声波测距函数(单位:毫米)
void GetDistanceInMM() {
unsigned int time;
// 触发超声波模块
Trig = 0;
Delay10us(1);
Trig = 1;
Delay10us(2);
Trig = 0;
// 等待回声信号
while (!Echo);
TR0 = 1; // 启动定时器0
while (Echo);
TR0 = 0; // 停止定时器0
// 计算时间(单位:机器周期)
time = TH0 * 256 + TL0;
TH0 = 0; // 重置定时器0
TL0 = 0;
// 计算距离(单位:毫米)
// 距离 = 时间 × 声速(340m/s) ÷ 2 = time × 17 / 1000 (cm) × 10 = time × 17 / 100 (mm)
g_distance_mm = (uint)time * 17 / 100;
g_distance_cm = g_distance_mm / 10; // 转换为厘米
}
// 进行6次测量并计算平均值
uint GetDistanceSixTimesAndCalculateAverage() {
uint i;
uint sum = 0;
for (i = 0; i < 6; i++) {
GetDistanceInMM(); // 执行单次测量
distance_array[i] = g_distance_cm; // 保存测量结果
sum += g_distance_cm; // 累加测量值
Delay10ms(100); // 间隔1秒
}
return sum / 6; // 返回平均值
}
void main() {
char str[30];
uint average_distance;
main_Init(); // 初始化系统
Trig = 0; // 初始状态下关闭超声波触发
TMOD &= 0xF0; // 配置定时器0为模式1
TMOD |= 0x01;
TH0 = 0;
TL0 = 0;
while (1) {
// 执行6次测量并计算平均值
average_distance = GetDistanceSixTimesAndCalculateAverage();
// 发送平均值到串口
sprintf(str, "Average Distance: %u cm\r\n", average_distance);
UART1_SendString(str);
// 根据平均值控制LED
if (average_distance * 10 < DISTANCE_THRESHOLD) {
LED = 0; // 距离小于阈值,点亮LED
sprintf(str, "Warning: Distance is less than %u mm!\r\n", DISTANCE_THRESHOLD);
UART1_SendString(str);
} else {
LED = 1; // 距离大于阈值,熄灭LED
}
Delay10ms(1000); // 每10秒测量一次
}
}
P1M0 = 0x00; P1M1 = 0x00; // 设置P1口为准双向口
P3M0 &= ~0x30; P3M1 &= ~0x30; // 设置P3.4和P3.5为准双向口
为端口模式定义,在STC89c52单片机是不需要定义的,只有P0口为开漏输出,其他口都是准双向口。但STC8有多种端口模式可以选,所以需要定义端口模式(直接在stc-isp软件中I/O口配置工具,选择端口和模式就会生成c代码)。
程序下载
打开stc-isp软件,根据自己的芯片选择型号,选择串口。特别注意:IRC频率选择12MHZ,如果选择别的,串口字符串接收的时候就会乱码。串口接收时 要在接收缓冲区中勾选文本模式,波特率设置为9600。如果发现还是乱码,选择更多设置将接收数据的编码方式选择ansi。
实验现象
把程序下载完后,按照上面设置,就能看到测量的距离。