找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2086|回复: 2
收起左侧

单片机超声波项目设计资料分享

[复制链接]
ID:419653 发表于 2018-12-26 17:41 | 显示全部楼层 |阅读模式
项目要求

1、设置三种模式,
        第一种模式:超声波测距,测距距离不在设置范围内蜂鸣器发出响声,测距距离在设置范围内,蜂鸣器不响,
        第二种模式:设置超声波最大测距距离,该模式下不能进行超声波测距,
        第三种模式:设置超声波最小测距距离,该模式下不能进行超声波测距,

2、四位数码管:最高位表示模式,其余三位数码管显示数据

3、三个按键,
        第一个按键:按下跳换模式,
        第二个按键:第一种模式不能按下,第二种模式按下最大值加1,第三种模式按下最小值加1,
        第三个按键:第一种模式不能按下,第二种模式按下最大值减1,第三种模式按下最小值减1,


设计思路

1、首先点亮一个数码管,然后实现动态扫描所有数码管,
2、实现按键按下变换数码管,设置出三种模式,
3、实现超声波测距,蜂鸣器发出响声,
4、将所有模块结合,完成项目要求,

单片机程序:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. /* 全局运行参数定义 */
  4. #define OSC_FREQ   (11059200)     //振荡器频率值,单位Hz
  5. #define SYS_MCLK   (OSC_FREQ/12)  //系统主时钟频率,即振荡器频率÷12

  6. //数码管io口定义
  7. sbit TUBE4=P3^4;
  8. sbit TUBE3=P3^5;
  9. sbit TUBE2=P3^6;
  10. sbit TUBE1=P3^7;
  11. //按键io口定义
  12. sbit KEY0=P2^0;
  13. sbit KEY1=P2^1;
  14. sbit KEY2=P2^2;

  15. //蜂鸣器io口定义
  16. sbit BUZZ=P2^3;

  17. sbit trig = P3^2;//超声波发射
  18. sbit echo = P3^3;        //超声波接收

  19. static unsigned char index=0;//模式选择的索引

  20. unsigned int flag1s = 0; //1s定时标志
  21. unsigned char T0RH = 0;    //T0重载值的高字节
  22. unsigned char T0RL = 0;    //T0重载值的低字节

  23. unsigned int HIGHEST = 400;    //超声波最大测距距离(cm)
  24. unsigned int LOWEST = 2;    //超声波最小测距距离(cm)
  25. static unsigned int testHighest = 100;    //超声波最高测距距离(设置值)
  26. static unsigned int testLowest = 10;    //超声波最低测距距离(设置值)

  27. unsigned char pdata KeySta[3] = { 1, 1, 1};  //全部矩阵按键的当前状态
  28. unsigned char code LedChar[] = {  //数码管显示字符转换表
  29.         0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,
  30.         0xa0,0x60,0x25,0x39,0x26,0x31,0x71,0xff
  31. };
  32. unsigned char LedBuff[4] = {        //数码管显示缓冲区,初值0xFF确保启动时都不亮
  33.         0xFF,0xFF,0xFF,0xFF
  34. };

  35. /* 数码管初始化函数 */
  36. void TUBE_Init();
  37. /* 数码管显示函数 */
  38. void TUBE_Display(unsigned int dis);
  39. /* 数码管按键显示函数 */
  40. void TUBE_KeyDisplay(unsigned int key);

  41. /* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
  42. void KeyDriver();
  43. /* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
  44. void KeyScan();

  45. /* 超声波测距函数 */
  46. unsigned int GetDistance(void);
  47. /* 蜂鸣器警报函数 */
  48. void IfDistance(void);

  49. /* 配置并启动T0,ms-T0定时时间 */
  50. void ConfigTimer0(unsigned int ms)
  51. {
  52.     unsigned long tmp;
  53.     tmp = (SYS_MCLK*ms)/1000; //计算所需的计数值
  54.     tmp = 65536 - tmp;        //计算定时器重载值
  55.     tmp = tmp + 33;           //补偿中断响应延时造成的误差   
  56.     T0RH = (unsigned char)(tmp>>8);   //定时器重载值拆分为高低字节
  57.     T0RL = (unsigned char)tmp;
  58.     TMOD &= 0xF0;   //清零T0的控制位
  59.     TMOD |= 0x01;   //配置T0为模式1
  60.     TH0 = T0RH;     //加载T0重载值
  61.     TL0 = T0RL;
  62.     ET0 = 1;        //使能T0中断
  63.     TR0 = 1;        //启动T0
  64. }
  65. /* 配置并启动T1,用于超声波测距 */
  66. void ConfigTimer1()
  67. {   
  68.     TMOD &= 0x0F;   //清零T1的控制位
  69.     TMOD |= 0x10;   //配置T1为模式1
  70.     TH1 = 0;     //加载T1重载值
  71.     TL1 = 0;
  72.     ET1 = 1;        //使能T1中断
  73. }
  74. /*mian函数*/
  75. void main()
  76. {
  77.         EA = 1;           //开总中断
  78.     ConfigTimer0(1);  //配置T0定时1ms
  79.         ConfigTimer1();        //配置T1
  80.         TUBE_Display(0);//数码管初始化
  81.         BUZZ=0;//蜂鸣器提示,程序开启,        
  82.         while(1)
  83.         {
  84.                 KeyDriver();//按键驱动函数,
  85.         }
  86. }

  87. /* T0中断服务函数,实现系统定时和按键扫描 */
  88. void InterruptTimer0() interrupt 1
  89. {
  90.     static unsigned int tmr1000ms = 0;
  91.     TH0 = T0RH;  //重新加载重载值
  92.     TL0 = T0RL;
  93.         TUBE_Init();        //数码管扫描函数
  94.         KeyScan();        //按键扫描函数
  95.     tmr1000ms++;  //定时1000ms
  96.     if (tmr1000ms >= 1000)//tmr1000ms=1000,时间为1S
  97.     {
  98.         tmr1000ms = 0;
  99.                 flag1s ++;
  100.                 if(flag1s>=2)BUZZ=1;//两秒后,蜂鸣器停止,
  101.         if(0==index)//模式=1,开启超声波测距
  102.                 {
  103.                         TUBE_Display(GetDistance());
  104.                         IfDistance();//蜂鸣器警报
  105.                 }        
  106.     }
  107. }
  108. /* 数码管初始化函数 */
  109. void TUBE_Init()
  110. {                        
  111.         static unsigned char choice=0;
  112.         //P1=0XFF;
  113.         switch(choice)//数码管扫描
  114.         {
  115.                 case 0:        TUBE4=0;TUBE3=1;TUBE2=1;TUBE1=1;choice++;P1=LedBuff[0];break;
  116.                 case 1:        TUBE4=1;TUBE3=0;TUBE2=1;TUBE1=1;choice++;P1=LedBuff[1];break;
  117.                 case 2:        TUBE4=1;TUBE3=1;TUBE2=0;TUBE1=1;choice++;P1=LedBuff[2];break;
  118.                 case 3:        TUBE4=1;TUBE3=1;TUBE2=1;TUBE1=0;choice=0;P1=LedBuff[3];break;
  119.                 default:break;
  120.         }
  121. }
  122. /* 数码管显示函数 */
  123. void TUBE_Display(unsigned int dis)
  124. {
  125.         //更改显示数码管数据
  126.         LedBuff[0]=LedChar[dis%10];
  127.         LedBuff[1]=LedChar[dis/10%10];
  128.         LedBuff[2]=LedChar[dis/100%10];
  129.         //判断模式,最高位数码管表示模式
  130.         if(0==index)LedBuff[3]=LedChar[10];
  131.         if(1==index)LedBuff[3]=LedChar[11];
  132.         if(2==index)LedBuff[3]=LedChar[12];
  133. }
  134. /* 数码管按键显示函数 */
  135. void TUBE_KeyDisplay(unsigned int key)
  136. {
  137.         
  138.         switch(index)//判断模式
  139.         {
  140.                 case 0://模式一,超声波测距
  141.                         if(0==key)//按下按键一,模式+1
  142.                         {
  143.                                 ++index;
  144.                                 TUBE_Display(testHighest);
  145.                         }
  146.                         break;
  147.                 case 1://模式二,设置超声波最高测距距离
  148.                         if(0==key)//按下按键一,模式+1
  149.                         {
  150.                                 ++index;
  151.                                 TUBE_Display(testLowest);
  152.                         }
  153.                         if(1==key)//按下按键二,超声波设置的最高测距距离+1
  154.                         {
  155.                                 if(HIGHEST>testHighest)testHighest++;
  156.                                 TUBE_Display(testHighest);
  157.                         }
  158.                         if(2==key)//按下按键三,超声波设置的最高测距距离-1
  159.                         {
  160.                                 if(LOWEST<testHighest)testHighest--;
  161.                                 TUBE_Display(testHighest);
  162.                         }
  163.                         break;
  164.                 case 2://模式三,设置超声波最低测距距离
  165.                         if(0==key)//按下按键一,模式+1
  166.                         {
  167.                                 ++index;
  168.                                 TUBE_Display(GetDistance());
  169.                         }
  170.                         if(1==key)//按下按键二,超声波设置的最低测距距离+1
  171.                         {
  172.                                 if(HIGHEST>testLowest)testLowest++;
  173.                                 TUBE_Display(testLowest);
  174.                         }
  175.                         if(2==key)//按下按键三,超声波设置的最低测距距离-1
  176.                         {
  177.                                 if(LOWEST<testLowest)testLowest--;
  178.                                 TUBE_Display(testLowest);
  179.                         }
  180.                         break;
  181.                 default:break;
  182.         }
  183.         if(index>=3)index=0;
  184. }

  185. /* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
  186. void KeyDriver()
  187. {
  188.     unsigned char i;
  189.     static unsigned char pdata backup[3] = { 1, 1, 1};  //按键值备份,保存前一次的值

  190.     for (i=0; i<3; i++)  //循环检测按键
  191.     {
  192.         if (backup[i] != KeySta[i])    //检测按键动作
  193.         {
  194.             if (backup[i] != 0)           //按键按下时执行动作
  195.             {
  196.                 TUBE_KeyDisplay(i);//调用按键动作函数
  197.             }
  198.             backup[i] = KeySta[i];     //刷新前一次的备份值
  199.         }   
  200.     }
  201. }
  202. /* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
  203. void KeyScan()
  204. {
  205.     unsigned char i;
  206.     static unsigned char keyout = 0;   //矩阵按键扫描输出索引
  207.     static unsigned char keybuf[3] = {0xFF, 0xFF, 0xFF};  //矩阵按键扫描缓冲区

  208.     //将3个按键值移入缓冲区
  209.     keybuf[0] = (keybuf[0] << 1) | KEY0;
  210.     keybuf[1] = (keybuf[1] << 1) | KEY1;
  211.     keybuf[2] = (keybuf[2] << 1) | KEY2;
  212.     //消抖后更新按键状态
  213.     for (i=0; i<3; i++)  //3个按键,循环3次
  214.     {
  215.         if (keybuf[i] == 0x00)
  216.         {   //连续8次扫描值为0,即8ms内都是按下状态时,可认为按键已稳定的按下
  217.             KeySta[i] = 0;
  218.         }
  219.         else if (keybuf[i] == 0xFF)
  220.         {   //连续8次扫描值为1,即8ms内都是弹起状态时,可认为按键已稳定的弹起
  221.             KeySta[i] = 1;
  222.         }
  223.     }
  224.     //执行下一次的扫描输出
  225.     keyout++;        //输出索引递增
  226.     if(keyout>=3)keyout = 0;  //索引值加到3即归零
  227. }

  228. /* 超声波测距函数 */
  229. unsigned int GetDistance(void)
  230. {
  231.     unsigned int ss;//用于记录测得的距离
  232.     trig = 1;//给IO口trig高电平
  233.         _nop_();//延时 时间要大于10us
  234.         _nop_();
  235.         _nop_();
  236.         _nop_();
  237.         _nop_();
  238.         _nop_();
  239.         _nop_();
  240.         _nop_();
  241.         _nop_();
  242.         _nop_();
  243.         _nop_();
  244.         _nop_();
  245.     trig = 0;//给IO口trig低电平
  246.         while(!echo);//当echo为高电平的时候,跳出循环
  247.         TH1 = 0;//定时器清零
  248.     TL1 = 0;
  249.     TR1 = 1;//启动定时器1,开启计时
  250.     while(echo);//echo不为0,即脉冲返回结束,计时结束
  251.     TR1 = 0;//停止计时
  252.     //ss = ((TH1 * 256 + TL1) * 0.34) / 2;//计算距离
  253.         ss = (TH1 * 256 + TL1) /58;//计算距离,公式= us/58 单位是cm        或 us/148 单位是英寸
  254.         if(ss<HIGHEST && ss>LOWEST)return ss; //判断距离是否在超声波测距的最大值和最小值范围内,“是”返回SS
  255.         
  256.         return 0; // “否”返回0   
  257. }

  258. /* 蜂鸣器警报函数 */
  259. void IfDistance(void)
  260. {
  261.         unsigned int ss;//用于记录测得的距离
  262.         ss=GetDistance();//得到超声波测得的距离
  263.         //判断超声波测到的距离是否在超声波设置测距的最大值和最小值范围内
  264.         if(ss>testHighest || ss<testLowest)BUZZ=0;//蜂鸣器发声
  265. }
复制代码
全部资料51hei下载地址:
PCB图.jpg

HC-SR04超声波测距模块说明书.pdf

426.67 KB, 下载次数: 7, 下载积分: 黑币 -5

PDF格式 模块超声波测距仪.pdf

89.76 KB, 下载次数: 6, 下载积分: 黑币 -5

HC-SR04超声波_原理图.pdf

44.21 KB, 下载次数: 10, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:89286 发表于 2018-12-27 08:36 | 显示全部楼层
thanks for sharinf
回复

使用道具 举报

ID:419653 发表于 2018-12-28 17:45 | 显示全部楼层
三种模式的图片图片补上

设置最大测距

设置最大测距

设置最小测距

设置最小测距

超声波正在测距

超声波正在测距
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表