xbq202 发表于 2026-4-10 15:22:19

重新写了一个超声波测距程序,测量距离4米以内,验证成功

超声波测距,喜欢的朋友留言,下面是验证照片,用尺子测了很精准


描述:STC32G12K128 + HC-SR04超声波测距 + I2C LCD1602显示程序
* 晶振:24MHz


#include "STC32G.h"   // STC32G系列单片机头文件
#include "intrins.h"    // 包含_nop_()等函数
#include <stdio.h>      // 标准输入输出库
#include <string.h>   // 字符串处理库


/*============================================================================
* 类型定义
*============================================================================*/
typedef unsigned charu8;       // 8位无符号整数
typedef unsigned int   u16;      // 16位无符号整数
typedef unsigned longu32;      // 32位无符号整数


/*============================================================================
* 硬件引脚定义
*============================================================================*/
// HC-SR04超声波模块引脚
sbit TRIG = P1^0;       // 触发信号输出引脚
sbit ECHO = P1^1;       // 回波信号输入引脚


// I2C总线引脚(软件模拟I2C)
sbit SCL = P3^2;      // I2C时钟线
sbit SDA = P3^3;      // I2C数据线


/*============================================================================
* LCD1602 I2C地址定义(PCF8574T扩展芯片)
*============================================================================*/
#define LCD1602_I2C_ADDR   0x4E    // PCF8574T的7位地址为0x27,左移1位后写地址=0x4E
#define LCD_RS               0x01    // RS引脚连接到P0
#define LCD_RW               0x02    // RW引脚连接到P1(实际I2C LCD1602通常R/W接地,始终写)
#define LCD_EN               0x04    // EN引脚连接到P2
#define LCD_BACKLIGHT      0x08    // 背光控制引脚连接到P3


/* 注意:以上引脚映射基于常见的PCF8574与LCD1602连接方式:
* P0 - RS(寄存器选择)
* P1 - R/W(读写选择)
* P2 - EN(使能信号)
* P3 - 背光控制
* P4 - D4(数据线4)
* P5 - D5(数据线5)
* P6 - D6(数据线6)
* P7 - D7(数据线7)
*/


/*============================================================================
* 全局变量定义
*============================================================================*/
floatg_distance = 0.0;      // 测量距离(单位:厘米)
u16    g_pulse_width = 0;       // 高电平脉冲宽度(单位:微秒)
u8   g_display_buf;       // LCD显示缓冲区(16字符+结束符)
u16    g_timer0_overflow_cnt = 0;   // 定时器0溢出次数


// 测量标志位
bit    g_measure_complete = 0;// 测量完成标志
bit    g_timeout_flag = 0;      // 超时标志


/*============================================================================
* 函数声明
*============================================================================*/
// 系统初始化函数
void System_Init(void);                     // 系统时钟及IO口初始化
void Timer0_Init(void);                     // 定时器0初始化(用于脉冲宽度测量)


// 延时函数
void Delay_us(u16 us);                      // 微秒级延时
void Delay_ms(u16 ms);                      // 毫秒级延时
void Delay_10us(u16 n);                     // 10微秒级延时


// I2C底层驱动函数
void I2C_Start(void);                     // I2C起始信号
void I2C_Stop(void);                        // I2C停止信号
void I2C_WriteByte(u8 dat);               // I2C发送一个字节
u8   I2C_ReadByte(u8 ack);                  // I2C读取一个字节
void I2C_Ack(void);                         // I2C应答信号
void I2C_NoAck(void);                     // I2C非应答信号
u8   I2C_WaitAck(void);                     // I2C等待应答


// LCD1602驱动函数
void LCD_WriteCmd(u8 cmd);                  // 写命令到LCD
void LCD_WriteData(u8 dat);               // 写数据到LCD
void LCD_WriteByte(u8 dat, u8 rs);          // 写入字节(带RS控制)
void LCD_Init(void);                        // LCD初始化
void LCD_SetCursor(u8 row, u8 col);         // 设置光标位置
void LCD_ShowString(u8 row, u8 col, u8 *str); // 显示字符串
void LCD_Clear(void);                     // 清屏


// HC-SR04超声波测距函数
void HC_SR04_Start(void);                   // 启动超声波测距
u16HC_SR04_Measure(void);               // 测量并返回脉冲宽度
float HC_SR04_GetDistance(void);            // 获取距离值(厘米)


// 工具函数
void GPIO_Init(void);                     // GPIO端口初始化
void Display_Update(void);                  // 更新LCD显示内容




/******************************************************************************
* 函数名称:main
* 功能描述:主函数
* 输入参数:无
* 输出参数:无
* 返回参数:int(程序返回状态)
******************************************************************************/
void main(void)
{
    // 系统初始化
    System_Init();
   
    // 延时等待外设稳定
    Delay_ms(500);
   
    // LCD1602初始化并显示欢迎信息
    LCD_Init();
    LCD_Clear();
    LCD_ShowString(0, 0, "HC-SR04 Distance");
    LCD_ShowString(1, 0, "System Initial..");
    Delay_ms(2000);
    LCD_Clear();
    LCD_ShowString(0, 0, "Distance:");
    LCD_ShowString(1, 0, "000.0 cm");
   
    // 主循环
    while(1)
    {
      // 获取测量距离
      g_distance = HC_SR04_GetDistance();
      
      // 判断测量是否有效(2cm - 400cm为有效范围)
      if(g_distance >= 2.0 && g_distance <= 400.0)
      {
            // 更新显示内容
            Display_Update();
      }
      else
      {
            // 超出测量范围,显示错误提示
            LCD_ShowString(1, 0, "Out of Range!   ");
      }
      
      // 延时60ms以上,防止发射信号对回响信号的干扰
      Delay_ms(100);
    }
}




/******************************************************************************
* 函数名称:System_Init
* 功能描述:系统时钟及外设初始化
* 输入参数:无
* 输出参数:无
* 返回参数:无
******************************************************************************/
void System_Init(void)
{
    // 系统时钟已在STC-ISP烧录软件中配置为24MHz
    // 此处初始化GPIO和定时器
   
    GPIO_Init();      // GPIO端口初始化
    Timer0_Init();      // 定时器0初始化
    EA = 1;             // 开启总中断
}
....................................................需要完整代码请留言


我心飞扬 发表于 2026-4-27 00:47:04

分享一下代码让大家学习、借鉴一下吧。{:4_250:}{:4_213:}
页: [1]
查看完整版本: 重新写了一个超声波测距程序,测量距离4米以内,验证成功