想运用52单片机实现一个超声波测距功能,具体如下:运行开始,超声波第一次测距d1,打开水泵放水(用3.3V模块),每一秒进行一次测距dn,当dn<d1时,水泵关闭,测试的数据同时有数码管显示。这个程序怎么写啊
3条回答 默认 最新
- lmr廖 2023-04-03 17:38关注
#include <reg52.h> #define TRIG P1_0 // 超声波发射引脚 #define ECHO P1_1 // 超声波接收引脚 #define PUMP P1_2 // 水泵控制引脚 #define DISP P2 // 数码管显示引脚 sbit LATCH = P3_4; // 数码管锁存引脚 sbit OE = P3_5; // 数码管输出使能引脚 sbit CLK = P3_6; // 数码管时钟引脚 sbit DATA = P3_7; // 数码管数据引脚 volatile unsigned int distance; // 当前距离 volatile unsigned char count; // 定时器计数器 volatile bit overflow; // 定时器溢出标志 // 读取数码管的值 void read_disp(unsigned char *value) { LATCH = 1; // 先将锁存引脚拉高 OE = 1; // 将输出使能引脚拉高 LATCH = 0; // 然后再拉低锁存引脚 OE = 0; // 将输出使能引脚拉低 // 逐位输出数据 for (int i = 0; i < 4; i++) { DATA = value[i]; CLK = 1; CLK = 0; } OE = 1; // 输出完成后再将输出使能引脚拉高 } // 超声波发射函数 void send_pulse() { TRIG = 1; // 将超声波发射引脚拉高 TH0 = 0; // 定时器清零 TL0 = 0; delay_us(10); // 延时 10 微秒 TRIG = 0; // 将超声波发射引脚拉低 } // 超声波中断处理函数 void echo_isr() interrupt 2 using 1 { static unsigned int start_time; if (overflow) { // 如果发生了定时器溢出 overflow = 0; distance = 0; // 距离设为 0,表示超时 } else { if (!ECHO) { // 如果接收到了回波信号 start_time = TH0 * 256 + TL0; // 记录开始时间 } else { // 如果回波结束 unsigned int end_time = TH0 * 256 + TL0; // 记录结束时间 distance = (end_time - start_time) / 58; // 计算距离 } } TR0 = 0; // 关闭定时器 count = 0; // 计数器清零 } // 定时器中断处理函数 void timer_isr() interrupt 1 using 2 { TH0 = 0; // 定时器重置 TL0 = 0; count++; // 计数器加 1 if (count == 10) { // 如果计数器达到 10(即 1 秒) count = 0; // 计数器清零 overflow = 1; // 发生定时器溢出 send_pulse(); // 发送超声波 TR0 = 1; // 启动定时器 } } void main() { TMOD = 0x01; // 定时器 0 工作在模式 1(16 位定时器)下 TH1 = 0xFD; // 设置定时器 1 的初值,每 50 微秒进入一次中断 TL
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 metadata提取的PDF元数据,如何转换为一个Excel
- ¥15 关于arduino编程toCharArray()函数的使用
- ¥100 vc++混合CEF采用CLR方式编译报错
- ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
- ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
- ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
- ¥50 如何openEuler 22.03上安装配置drbd
- ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
- ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
- ¥15 Windows11, backspace, enter, space键失灵