• 23、基于51单片机的三路超声波测距系统(Proteus仿真+程序+设计报告)


    编号:23

    基于51单片机的三路超声波测距系统

    功能描述:

          本设计由51单片机+三路HC_SR04超声波模块+液晶1602+按键+蜂鸣器LED组成。
    1、采用51C系列单片机。
    2、三路HC_SR04超声波模块实现测距。测距范围2cm-400cm之间。
    3、液晶1602实时显示测到的距离。
    4、三个按键可实现上限报警值设定,按键分别为设置键、设置加、设置减。
    5、当测得距离小于上限值时,声光报警。

    注意:Proteus8.6以上版本才能打开

    视频演示链接:

    23、基于51单片机的三路超声波测距系统

    仿真图:

    程序源码:

    1. /***********************************************
    2. ***********************************************/
    3. #include "reg52.h"
    4. #include "lcd1602.h"
    5. #include "delay.h"
    6. #include "HCSR04.h"
    7. #include "eeprom.h"
    8. #include "key.h"
    9. sbit beep = P3^7; //蜂鸣器控制脚
    10. bit flag_timer = 0; //定时时间到标志位
    11. bit flag_beep = 0; //报警标志位
    12. short Dis_up = 50; //距离上限 默认50cm
    13. void EEPROM_Read(void) //读EEPROM中保存的数据
    14. {
    15. Dis_up = byte_read(0x2000+1)*256+byte_read(0x2000+2); //读取距离上限数据
    16. }
    17. void EEPROM_Write(void) //写数据进eepROM
    18. {
    19. SectorErase(0x2000); //擦除扇区
    20. byte_write(0x2000+0,12); //存储标志位
    21. byte_write(0x2000+1,Dis_up/256); //存数据 Dis_up不是八位的数据 可能会大于256 所以分为成高低八位存储
    22. byte_write(0x2000+2,Dis_up%256); //存数据
    23. }
    24. void EEPROM_Check(void) //检测 是不是第一次使用芯片或者芯片是否正常
    25. {
    26. if(byte_read(0x2000+0)!=12)
    27. {
    28. EEPROM_Write(); //写数据进EEPROM
    29. }
    30. else
    31. EEPROM_Read(); //读数据从EEPROM
    32. }
    33. /************************************************************************
    34. * 函数: void Timer0Init(void)
    35. * 描述: 定时器1初始化函数
    36. * 参数: none.
    37. * 返回: none.
    38. * 备注:定时2ms 12MHz
    39. ************************************************************************/
    40. void Timer1Init(void) //2毫秒@12MHz
    41. {
    42. TMOD &= 0x0F; //设置定时器模式
    43. TMOD |= 0x10; //设置定时器模式
    44. TL1 = 0xCD; //设置定时初值
    45. TH1 = 0xF8; //设置定时初值
    46. TF1 = 0; //清除TF1标志
    47. TR1 = 1; //定时器1开始计时
    48. ET1 = 1; //开始计数
    49. EA = 1; //开总中断
    50. }
    51. void main(void)
    52. {
    53. unsigned char var = 0;
    54. unsigned int Fdistance,Ldistance,Rdistance;
    55. EEPROM_Check(); //读取EEPROM
    56. Timer1Init(); //2毫秒@12MHz
    57. HCSR04_Init();
    58. Lcd1602_Init(); //LCD1602液晶初始化
    59. Lcd1602_String(0,0," F: ");
    60. Lcd1602_String(0,1,"L: R: ");
    61. while(1)
    62. {
    63. if(flag_timer==1) //600毫秒赋一次值 flag_timer是标志位
    64. {
    65. flag_timer = 0; //清除标志 等待下一次600ms
    66. if(HCSR04_Count(&Fdistance)==0) //测距 将距离值传递给distance
    67. {
    68. Lcd1602_Write_Com(0x80+6);
    69. Lcd1602_Write_Data(Fdistance%1000/100+0x30);
    70. Lcd1602_Write_Data(Fdistance%1000%100/10+0x30);
    71. Lcd1602_Write_Data(Fdistance%1000%100%10+0x30);
    72. Lcd1602_Write_Data('c');
    73. Lcd1602_Write_Data('m');
    74. }
    75. else
    76. {
    77. Lcd1602_Write_Com(0x80+6);
    78. Lcd1602_Write_Data('-');
    79. Lcd1602_Write_Data('-');
    80. Lcd1602_Write_Data('-');
    81. Lcd1602_Write_Data('c');
    82. Lcd1602_Write_Data('m');
    83. }
    84. if(HCSR04_Count1(&Ldistance)==0) //测距 将距离值传递给distance
    85. {
    86. Lcd1602_Write_Com(0xc0+2);
    87. Lcd1602_Write_Data(Ldistance%1000/100+0x30);
    88. Lcd1602_Write_Data(Ldistance%1000%100/10+0x30);
    89. Lcd1602_Write_Data(Ldistance%1000%100%10+0x30);
    90. Lcd1602_Write_Data('c');
    91. Lcd1602_Write_Data('m');
    92. }
    93. else
    94. {
    95. Lcd1602_Write_Com(0xC0+2);
    96. Lcd1602_Write_Data('-');
    97. Lcd1602_Write_Data('-');
    98. Lcd1602_Write_Data('-');
    99. Lcd1602_Write_Data('c');
    100. Lcd1602_Write_Data('m');
    101. }
    102. if(HCSR04_Count2(&Rdistance)==0) //测距 将距离值传递给distance
    103. {
    104. Lcd1602_Write_Com(0xc0+10);
    105. Lcd1602_Write_Data(Rdistance%1000/100+0x30);
    106. Lcd1602_Write_Data(Rdistance%1000%100/10+0x30);
    107. Lcd1602_Write_Data(Rdistance%1000%100%10+0x30);
    108. Lcd1602_Write_Data('c');
    109. Lcd1602_Write_Data('m');
    110. }
    111. else
    112. {
    113. Lcd1602_Write_Com(0xC0+10);
    114. Lcd1602_Write_Data('-');
    115. Lcd1602_Write_Data('-');
    116. Lcd1602_Write_Data('-');
    117. Lcd1602_Write_Data('c');
    118. Lcd1602_Write_Data('m');
    119. }
    120. }
    121. KEY_Set();
    122. if(Fdistance//当前距离小于上限
    123. {
    124. var++;
    125. if(var>5) //为了防止误差多次判断距离是否超限
    126. {
    127. var = 0;
    128. flag_beep = 1; //开报警标志 执行报警程序在定时器中断
    129. }
    130. }
    131. else
    132. {
    133. var = 0;
    134. flag_beep = 0; //关报警标志位
    135. }
    136. }
    137. }
    138. //定时器1中断服务函数
    139. void tm1_isr() interrupt 3 using 1
    140. {
    141. static unsigned int cnt=0,cnt1;
    142. TF1 = 0;
    143. TL1 = 0x30; //设置定时初值
    144. TH1 = 0xF8; //设置定时初值
    145. if(cnt++ >= 300) //2ms*300 =600ms
    146. {
    147. cnt = 0;
    148. flag_timer = 1; //600ms到 赋值标志为1 600ms赋一次 600ms不是必须的 可以自己修改
    149. }
    150. if(cnt1++>=200) //2ms*200 =400ms
    151. {
    152. cnt1 = 0;
    153. if(flag_beep==1) //报警标志位打开
    154. beep = ~ beep; //蜂鸣器控制脚取反 400ms取反一次 产生滴滴滴 响声 而不是一直长鸣
    155. else
    156. beep = 1; //高电平关闭报警
    157. }
    158. }

    软件免费下载地址:

    1、Proteus仿真软件
    文件内容:Proteus7.8安装包、Proteus8.6安装包、Proteus.8.10安装包、Proteus Professional 8.11 SP0安装包

    链接:https://pan.baidu.com/s/11LNUZ9BJXWvXf1C4dPc3_w 
    提取码:2756 


    2、KEIL4 C51软件安装包

    链接:https://pan.baidu.com/s/1CTZBqDsPsyIbjCIjI_birA 
    提取码:sy2a 

    文件下载:

    https://pan.baidu.com/s/1lcnMvoSlOogmLmcojNwdoA?pwd=w7cn

  • 相关阅读:
    「高效程序员的修炼」快速上手Shell编程、执行与定时任务
    月薪2万的大数据职位,为什么必须学习Python?
    Linux软硬链接和动静态库
    什么牌子的蓝牙耳机好?音质好的蓝牙耳机推荐
    java毕业生设计毕业生交流学习平台计算机源码+系统+mysql+调试部署+lw
    并查集-合并集合
    语法基础(变量、输入输出、表达式与顺序语句完成情况)
    【经验分享】PS如何设置像素
    别再被数据分析“割韭菜了”,光学python、BI没有用,上项目才行
    Cadence Allegro 通过全局视窗局部放大板卡的方法
  • 原文地址:https://blog.csdn.net/bxy415655001/article/details/127928988