精灵油画 2023-04-03 17:31 采纳率: 66.7%
浏览 40
已结题

52单片机超声波测距

想运用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
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月4日
  • 已采纳回答 4月3日
  • 创建了问题 4月3日

悬赏问题

  • ¥100 python读取速度问题
  • ¥15 stm32f407使用DMA问题
  • ¥15 您好 这个API接口该怎么弄 网站搭建好了 API也有 现在就不知道该怎么填写API 不知道怎么用
  • ¥88 用uniapp写一个多端的程序,用到高德地图,用高德的JSAPI吗?
  • ¥20 关于#c++#的问题:水果店管理系统
  • ¥30 dbLinq最新版linq sqlite
  • ¥20 对D盘进行分盘之前没有将visual studio2022卸载掉,现在该如何下载回来
  • ¥15 完成虚拟机环境配置,还有安装kettle
  • ¥15 2024年全国大学生数据分析大赛A题:直播带货与电商产品的大数据分析 问题5. 请设计一份优惠券的投放策略,需要考虑优惠券的数量、优惠券的金额、投放时间段和投放商品种类等因素。求具体的python代码
  • ¥15 有人会搭建生鲜配送自营+平台的管理系统吗