找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5696|回复: 0
打印 上一主题 下一主题
收起左侧

基于单片机的导盲仪系统设计报告与源程序等资料下载

[复制链接]
跳转到指定楼层
楼主
单片机原理及应用
项目设计报告

姓名:张*
学号:15221*
班级:校区15电气1班
专业:电气工程及其自动化
学院:电气与信息工程学院


20186

目录

基于单片机的导盲仪系统

一、绪论

1、项目研究背景及意义

二、总体设计方案及论证

1、总体方案设计

三、硬件实现及单元电路设计

1、主控制模块

2、  电源设计

3、  超声波测试模块

4、 测距分析

5、 时钟电路的设计

6、 复位电路的设计

7、  声音报警电路的设计

8、显示模块

四、软件设计

1、主程序工作流程图

2、超声波探测程序流程图

五、总结

六、参考文献

附 录

附件1:原理图

附件2:程序

附件3:实物图


一、绪论
1、项目研究背景及意义
由于超声测距是一种非接触检测技术,不受光线、被测对象颜色等的影响,较其它仪器更卫生,更耐潮湿、粉尘、高温、腐蚀气体等恶劣环境,具有少维护、不污染、高可靠、长寿命等特点。因此可广泛应用于纸业、矿业、电厂、化工业、水处理厂、污水处理厂、农业用水、环保检测、食品(酒业、饮料业、添加剂、食用油、奶制品)、防汛、水文、明渠、空间定位、公路限高等行业中。可在不同环境中进行距离准确度在线标定,可直接用于水、酒、糖、饮料等液位控制,可进行差值设定,直接显示各种液位罐的液位、料位高度。因此,超声在空气中测距在特殊环境下有较广泛的应用。利用超声波检测往往比较迅速、方便、计算简单、易于实现实时控制,并且在测量精度方面能达到工业实用的指标要求,因此为了使移动机器人能够自动躲避障碍物行走,就必须装备测距系统,以使其及时获取距障碍物的位置信息(距离和方向)。因此超声波测距在移动机器人的研究上得到了广泛的应用。同时由于超声波测距系统具有以上的这些优点,因此在导盲仪的研制方面也得到了广泛的应用。

二、总体设计方案及论证
1、总体方案设计
本设计包括硬件和软件设计两个部分。模块划分为数据采集、按键控制、四位数码管显示、报警等子模块。电路结构可划分为:超声波传感器、蜂鸣器、单片机控制电路。就此设计的核心模块来说,单片机就是设计的中心单元,所以此系统也是单片机应用系统的一种应用。单片机应用系统也是有硬件和软件组成。硬件包括单片机、输入/输出设备、以及外围应用电路等组成的系统,软件是各种工作程序的总称。单片机应用系统的研制过程包括总体设计、硬件设计、软件设计等几个阶段。系统采用STC89C52单片机作为核心控制单元,当测得的距离小于设定距离时,主控芯片将测得的数值与设定值进行比较处理。然后控制蜂鸣器报警。系统总体的设计方框图如图2-1所示。




图2-1 系统方框图

三、硬件实现及单元电路设计
1、主控制模块
主控制最小系统电路如图3-1所示。

图3-1 最小系统

硬件电路总设计见图3-2,从以上的分析可知在本设计中要用到如下器件: STC89C52、超声波传感器、按键、四位数码管、蜂鸣器等一些单片机外围应用电路。其中D1为电源工作指示灯。电路中用到3个按键,一个是设定键, 一个加键,一个减键。

图3-2 总设计电路图

2、  电源设计
电源部分的设计采用3节5号干电池4.5V供电。
3、  超声波测试模块
超声波模块采用现成的HC-SR04超声波模块,该模块可提供 2cm-500cm 的非接触式距离感测功能,测距精度可达高到 3mm。模块包括超声波发射器、接收器与控制电路。基本工作原理:采用 IO 口 TRIG 触发测距,给至少 10us 的高电平信号;模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。实物如下图4。其中VCC 供5V 电源,GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四支线。

图3-3 超声波模块实物图

超声波探测模块HC-SR04的使用方法如下:IO口触发,给Trig口至少10us的高电平,启动测量;模块自动发送8个40Khz的方波,自动检测是否有信号返回;有信号返回,通过IO口Echo输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间,测试距离=(高电平时间*340)/ 2,单位为m。程序中测试功能主要由两个函数完成。
实现中采用定时器0进行定时测量,8分频,TCNTT0预设值0XCE,当timer0溢出中断发生2500次时为125ms,计算公式为(单位:ms):
T = (定时器0溢出次数 * (0XFF - 0XCE))/ 1000
其中定时器0初值计算依据分频不同而有差异。
4、 测距分析
超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),即:s=340t/2
最常用的超声测距的方法是回声探测法,超声波发射器向某一方向发射超声波,在发射时刻的同时计数器开始计时,超声波在空气中传播,途中碰到障碍物面阻挡就立即反射回来,超声波接收器收到反射回的超声波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物面的距离s,即:s=340t/2。   
只要测得超声波往返的时间,即可求得距离。这就是超声波测距仪的基本原理。如图12所示:

图3-4 超声波的测距原理


                             (3-1)
                           (3-2)
式中:L---两探头之间中心距离的一半.
又知道超声波传播的距离为:
                                ( 3-3)
式中:v—超声波在介质中的传播速度;
     t—超声波从发射到接收所需要的时间.
将(3—2)、(3—3)代入(3-1)中得:
                     ( 3-4)
其中,超声波的传播速度v在一定的温度下是一个常数(例如在温度T=30度时,V=349m/s);当需要测量的距离H远远大于L时,则(3—4)变为:
                                           ( 3-5)               
所以,只要需要测量出超声波传播的时间t,就可以得出测量的距离H.
5、 时钟电路的设计
XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。
因为一个机器周期含有6个状态周期,而每个状态周期为2个振荡周期,所以一个机器周期共有12个振荡周期,如果外接石英晶体振荡器的振荡频率为12MHZ,一个振荡周期为1/12us,故而一个机器周期为1us。如图3-5所示为时钟电路。

图3-5 时钟电路图


6、 复位电路的设计
复位方法一般有上电自动复位和外部按键手动复位,单片机在时钟电路工作以后, 在RESET端持续给出2个机器周期的高电平时就可以完成复位操作。例如使用晶振频率为12MHz时,则复位信号持续时间应不小于2us。本设计采用的是自动复位电路。如图3-6示为复位电路。

图3-6 复位电路图

7、  声音报警电路的设计
如下图所示,用一个Speaker和三极管、电阻接到单片机的P13引脚上,构成声音报警电路,如图3-7示为声音报警电路。

图3-7 声音报警电路图

8、显示模块
显示模块采用数码管显示接口电路如图3-8


图3-8 数码管电路



四、软件设计            
1、主程序工作流程图
按上述工作原理和硬件结构分析可知系统主程序工作流程图如下图4-1所示;

图4-1主程序工作流程图


2、超声波探测程序流程图

图4-2 超声波探测程序流程图

五、总结
本设计研究了一种基于单片机技术的超声波导盲仪系统。该系统通过以STC89C52单片机为工作处理器核心,超声波传感器,它是一种新颖的被动式超声波探测器件,能够以非接触测出前方物体距离,并将其转化为相应的电信号输出.该报警器的最大特点就是使用户能够操作简单、易懂、灵活;且安装方便、智能性高、误报率低。随着现代人们安全意识的增强以及科学技术的快速发展,相信超声波导盲仪必将在更广阔的人群中得到更深层次的应用。
六、参考文献
[1] 吴政江. 单片机控制红外线防盗报警器[J]. 锦州师范学院学报, 2001.
[2] 宋文绪. 传感器与检测技术[M]. 北京: 高等教育出版社, 2004.
[3] 余锡存. 单片机原理及接口技术[M]. 西安: 西安电子科技大学出版社, 2000.
[4] 唐桃波, 陈玉林. 基于AT89C51的智能无线安防报警器 [J]. 电子设计应用, 2003, 5(6): 49~51.
[5] 李全利. 单片机原理及接口技术[M]. 北京: 北京航空航天大学出版社, 2004.
[6] 薛均义, 张彦斌. MCS-51系列单片微型计算机及其应用[M]. 西安: 西安交通大学出版社, 2005.
[7] 徐爱钧, 彭秀华. 单片机高级语言C51应用程序设计[M]. 北京: 北京航空航天大学出版社, 2006.
[8] 康华光. 电子技术基础(模拟部分)[M]. 北京: 高等教育出版社, 2004.


附件1:原理图
附件2:程序

  1. #include <reg52.h>                       //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义              变量范围0~255
  3. #define uint  unsigned int              //无符号整型 宏定义              变量范围0~65535
  4. #include <intrins.h>

  5. //数码管段选定义      0     1    2    3    4    5              6              7                8                 9            
  6. uchar code smg_du[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0,
  7.                                                                         0x60,0x25,0x39,0x26,0x31,0x71,0xff};              //断码


  8. uchar dis_smg[8]   ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};

  9. //数码管位选定义
  10. sbit smg_we1 = P3^4;                  //数码管位选定义
  11. sbit smg_we2 = P3^5;
  12. sbit smg_we3 = P3^6;
  13. sbit smg_we4 = P3^7;

  14. sbit c_send   = P3^2;                            //超声波发射
  15. sbit c_recive = P3^3;                            //超声波接收

  16. sbit beep = P2^3;   //蜂鸣器IO口定义
  17. uchar smg_i = 3;    //显示数码管的个位数
  18. bit flag_300ms ;

  19. long distance;                      //距离
  20. uint set_d;                          //距离
  21. uchar flag_csb_juli;    //超声波超出量程
  22. uint  flag_time0;       //用来保存定时器0的时候的

  23. uchar menu_1;           //菜单设计的变量


  24. /***********************1ms延时函数*****************************/
  25. void delay_1ms(uint q)
  26. {
  27.               uint i,j;
  28.               for(i=0;i<q;i++)
  29.                             for(j=0;j<120;j++);
  30. }

  31. /***********************处理距离函数****************************/
  32. void smg_display()
  33. {
  34.               dis_smg[0] = smg_du[distance % 10];
  35.               dis_smg[1] = smg_du[distance / 10 % 10];
  36.               dis_smg[2] = smg_du[distance / 100 % 10] & 0xdf; ;            
  37. }

  38. /********************独立按键程序*****************/
  39. uchar key_can;              //按键值

  40. void key()              //独立按键程序
  41. {
  42.               static uchar key_new;
  43.               key_can = 20;                   //按键值还原
  44.               P2 |= 0x07;
  45.               if((P2 & 0x07) != 0x07)                            //按键按下
  46.               {
  47.                             delay_1ms(1);                                 //按键消抖动
  48.                             if(((P2 & 0x07) != 0x07) && (key_new == 1))
  49.                             {                                                                                    //确认是按键按下
  50.                                           key_new = 0;
  51.                                           switch(P2 & 0x07)
  52.                                           {
  53.                                                         case 0x06: key_can = 3; break;                 //得到k2键值
  54.                                                         case 0x05: key_can = 2; break;                 //得到k3键值
  55.                                                         case 0x03: key_can = 1; break;                 //得到k4键值
  56.                                           }
  57.                             }                                         
  58.               }
  59.               else
  60.                             key_new = 1;            
  61. }

  62. /****************按键处理显示函数***************/
  63. void key_with()
  64. {
  65.               if(key_can == 1)                            //设置键
  66.               {
  67.                             menu_1 ++;
  68.                             if(menu_1 >= 2)
  69.                             {
  70.                                           menu_1 = 0;
  71.                                           smg_i = 3;                            //只显示3位数码管
  72.                             }
  73.                             if(menu_1 == 1)
  74.                             {
  75.                                           smg_i = 4;                 //只显示4位数码管
  76.                             }
  77.               }
  78.               if(menu_1 == 1)                                          //设置报警
  79.               {
  80.                             if(key_can == 2)
  81.                             {
  82.                                           set_d ++ ;                            //加1
  83.                                           if(set_d > 400)
  84.                                                         set_d = 400;
  85.                             }
  86.                             if(key_can == 3)
  87.                             {
  88.                                           set_d -- ;                            //减1
  89.                                           if(set_d <= 1)
  90.                                                         set_d = 1;
  91.                             }
  92.                             dis_smg[0] = smg_du[set_d % 10];                         //取小数显示
  93.                             dis_smg[1] = smg_du[set_d / 10 % 10] ;         //取个位显示
  94.                             dis_smg[2] = smg_du[set_d / 100 % 10] & 0xdf ; //取十位显示
  95.                             dis_smg[3] = 0x60;                      //a
  96.               }            
  97. }

  98. /****************报警函数***************/
  99. void clock_h_l()
  100. {
  101.               static uchar value;
  102.               if(distance <= set_d)
  103.               {
  104.                             value ++;  //消除实际距离在设定距离左右变化时的干扰
  105.                             if(value >= 2)
  106.                             {
  107.                                           beep = ~beep;                 //蜂鸣器报警            
  108.                             }
  109.               }
  110.               else
  111.               {
  112.                             value = 0;
  113.                             beep = 1;                            //取消报警
  114.               }            
  115. }

  116. /***********************数码位选函数*****************************/
  117. void smg_we_switch(uchar i)
  118. {
  119.               switch(i)
  120.               {
  121.                             case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  122.                             case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  123.                             case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  124.                             case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  125.               }            
  126. }

  127. /***********************数码显示函数*****************************/
  128. void display()
  129. {
  130.               static uchar i;  
  131.               i++;
  132.               if(i >= smg_i)
  133.                             i = 0;            
  134.               smg_we_switch(i);                            //位选
  135.               P1 = dis_smg[i];                            //段选                     
  136. }

  137. /******************小延时函数*****************/
  138. void delay()
  139. {
  140.               _nop_();                                        //执行一条_nop_()指令就是1us
  141.               _nop_();
  142.               _nop_();
  143.               _nop_();
  144.               _nop_();
  145.               _nop_();
  146.               _nop_();
  147.               _nop_();
  148.               _nop_();
  149.               _nop_();
  150. }


  151. /*********************超声波测距程序*****************************/
  152. void send_wave()
  153. {
  154.               c_send = 1;                                       //10us的高电平触发
  155.               delay();
  156.               c_send = 0;            
  157.               TH0 = 0;                                      //给定时器0清零
  158.               TL0 = 0;
  159.               TR0 = 0;                                                          //关定时器0定时
  160.               while(!c_recive);                              //当c_recive为零时等待
  161.               TR0=1;
  162.               while(c_recive)                                  //当c_recive为1计数并等待
  163.               {
  164.                             flag_time0 = TH0 * 256 + TL0;
  165.                             if((flag_time0 > 40000))      //当超声波超过测量范围时,显示3个888
  166.                             {
  167.                                           TR0 = 0;
  168.                                           flag_csb_juli = 2;
  169.                                           distance = 888;
  170.                                           break ;                           
  171.                             }
  172.                             else
  173.                             {
  174.                                           flag_csb_juli = 1;            
  175.                             }
  176.               }
  177.               if(flag_csb_juli == 1)
  178.               {            
  179.                             TR0=0;                                                                                                  //关定时器0定时
  180.                             distance =flag_time0;                                          //读出定时器0的时间
  181.                             distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
  182.                             if((distance > 500))                                                        //距离 = 速度 * 时间
  183.                             {            
  184.                                           distance = 888;                                                        //如果大于3.8m就超出超声波的量程
  185.                             }
  186.               }
  187. }


  188. /*********************定时器0、定时器1初始化******************/
  189. void time_init()               
  190. {
  191.               EA  = 1;                              //开总中断
  192.               TMOD = 0X11;                //定时器0、定时器1工作方式1
  193.               ET0 = 0;                              //关定时器0中断
  194.               TR0 = 1;                              //允许定时器0定时
  195.               ET1 = 1;                              //开定时器1中断
  196.               TR1 = 1;                              //允许定时器1定时            
  197. }



  198. /***************主函数*****************/
  199. void main()
  200. {
  201.               beep = 0;                            //开机叫一声  
  202.               delay_1ms(150);
  203.               P0 = P1 = P2 = P3 = 0xff;                 //初始化单片机IO口为高电平
  204.               time_init();              //定时器初始化程序
  205.               send_wave();              //测距离函数
  206.               while(1)
  207.               {                             
  208.                             if(flag_300ms == 1)
  209.                             {                           
  210. ……………………

  211. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码



全部资料51hei下载地址:

152219702125张俊岩.zip (8.66 MB, 下载次数: 68)


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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