- 打卡等级:偶尔看看I
- 打卡总天数:11
- 最近打卡:2026-04-10 01:15:45
已绑定手机
注册会员
- 积分
- 98
|
超声波测距,喜欢的朋友留言,下面是验证照片,用尺子测了很精准
。
描述:STC32G12K128 + HC-SR04超声波测距 + I2C LCD1602显示程序
* 晶振:24MHz
#include "STC32G.h" // STC32G系列单片机头文件
#include "intrins.h" // 包含_nop_()等函数
#include <stdio.h> // 标准输入输出库
#include <string.h> // 字符串处理库
/*============================================================================
* 类型定义
*============================================================================*/
typedef unsigned char u8; // 8位无符号整数
typedef unsigned int u16; // 16位无符号整数
typedef unsigned long u32; // 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)
*/
/*============================================================================
* 全局变量定义
*============================================================================*/
float g_distance = 0.0; // 测量距离(单位:厘米)
u16 g_pulse_width = 0; // 高电平脉冲宽度(单位:微秒)
u8 g_display_buf[17]; // 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); // 启动超声波测距
u16 HC_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以上,防止发射信号对回响信号的干扰[reference:4]
Delay_ms(100);
}
}
/******************************************************************************
* 函数名称:System_Init
* 功能描述:系统时钟及外设初始化
* 输入参数:无
* 输出参数:无
* 返回参数:无
******************************************************************************/
void System_Init(void)
{
// 系统时钟已在STC-ISP烧录软件中配置为24MHz
// 此处初始化GPIO和定时器
GPIO_Init(); // GPIO端口初始化
Timer0_Init(); // 定时器0初始化
EA = 1; // 开启总中断
}
....................................................需要完整代码请留言
|
|