找回密码
 立即注册

QQ登录

只需一步,快速开始

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

超声波避障小车的设计与制作

[复制链接]
跳转到指定楼层
楼主
ID:65619 发表于 2014-8-30 18:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

超声波避障小车的设计与制作
                       摘 要

智能小车是一种能够通过编程手段完成特定任务的小型化机器人,它具有制作成本低廉,电路结构简单,程序调试方便等优点。由于具有很强的趣味性,智能小车深受广大机器人爱好者以及高校学生的喜爱。
本论文介绍的是具有自动避障功能的智能小车的设计与制作(以下简称智能小车),论文对智能小车的方案选择,设计思路,以及软硬件的功能和工作原理进行了详细的分析和论述。经实践验收测试,该智能小车的电路结构简单,调试方便,系统反映快速、灵活,设计方案正确、可行,各项指标稳定、可靠。











































目  录
摘 要        I
Abstract        II
目  录        III
第一章 绪论        1
1.1项目研究背景及意义:        1
1.2项目主要研究内容:        1
1.3设计思路:        1
1.4应用场合和功能:        2
第二章 总体方案        3
2.1总体方案概述:        3
2.2 总体电路原理图:        3
第三章 各模块功能介绍        4
3.1障碍物测距系统:        4
3.2显示模块:        5
3.3驱动模块:        10
3.4电源模块:        12
第四章 软件设计        13
4.1 程序设计流程图        13
4.2 关键程序设计:        14
第五章 系统调试        17
5.1 调试的思路:        17
5.2 各模块的调试:        17
5.3 调试心得:        19
第六章 结论与展望        20
6.1 结论:        20
6.2 展望:        20
致  谢        21
参考资料        22
附录        23
1.元器件清单:        23
2.样机实物照片:        24
3.电路原理图:        25
相关程序        26


第一章 绪论
1.1项目研究背景及意义:
智能作为现代社会的新产物,是以后的发展方向,他可以按照预先设定的 模式在一个特定的环境里自动的运作,无需人为管理,便可以完成预期所要达 到的或是更高的目标。本设计主要体现多功能小车的智能模式,设计中的理论 方案、分析方法及特色与创新点等可以为自动运输机器人、采矿勘探机器人、 家用自动清洁机器人等自动半自动机器人的设计与普及有一定的参考意义。同 时小车可以作为玩具的发展对象,为中国玩具市场技术含量的缺乏进行一定的 弥补,实现经济收益,形成商业价值。 超声波作为智能车避障的一种重要手段,以其避障实现方便,计算简单, 易于做到实时控制,测量精度也能达到实用的要求,在未来汽车智能化进程中 必将得到广泛应用。我国作为一个世界大国,在高科技领域也必须占据一席之 地,未来汽车的智能化是汽车产业发展必然的,在这种情况下研究超声波在智 能车避障上的应用具有深远意义,这将对我国未来智能汽车的研究在世界高科 技领域占据领先地位具有重要作用。 本智能小车系统最诱人的前景就是可用于未来的智能汽车上了,当驾驶员 因疏忽或打瞌睡时这样的智能汽车的设计就能体现出它的作用。如果汽车偏离 车道或距障碍物小于安全距离时,汽车就会发出警报,提醒驾驶员注意,如果 驾驶员没有及时作出反应,汽车就会自动减速或停靠于路边。 这样的小车还可以用于月球探测等的无人探月车,帮助我们传达月球上更 多的信息,让我们更加的了解月球,为将来登月做好充分准备。 这样的小车在科学考察探测车上也有广阔的应用前景,在科学考察中,有 很多危险且人们无法涉足的地方,这时,智能科学考察车就能够派上用场,在 它上面装上摄像机,代替人们进行许多无法进行的工作。
1.2项目主要研究内容:
本设计题目为智能避障小车设计,主要研究小车的避障功能,小车遇到障碍物时,当距离障碍物大于40cm,PWM信号自增,驱动电机加速,小车加速前进,当小于30cm时,PWM信号自减,驱动电机减速,小车减速前进,并且小车采取相应的避障措施。这里探测装置必不可少,因为超声波在距离检测方面的较准确定位。所以采用超声波传感器作为探测装置,由于超声波遇到障碍物时发生像光一样的反射和散射,在经过多次发射之后再回到超声波检测端口会产生较严重的路程差,从而影响对距离的检测进而影响对障碍物的较准确定位。通过软件内部校准优化消除外部物理条件造成的误差从而达到对障碍物的较准确定位。
1.3设计思路:
直流电机PWM控制系统的主要功能包括:实现对直流电机的加速、减速,并且可以调整电机的转速,能够很方便的实现电机的智能控制。主体电路:即直流电机 PWM 控制模块。这部分电路主要由 AT89S52 单片机 的 I/O 端口、定时计数器、外部中断扩展等控制直流电机的加速、减速以及转弯,并且可以调整电机的转速,能够很方便的实现电机的智能控制。 其间是通过 AT89S52 单片机产生脉宽可调的脉冲信号并输入到 L298 驱动芯片来 控制直流电机工作的。该直流电机 PWM 控制系统由以下电路模块组成:设计控制部分: 主要由 AT89S52 单片机的外部中断扩展电路组成。直流电机PWM控制实现部分主要由电机和 L298 直流电机驱动模块组成。设计显示部分:LCD 数码显示部分,实现对超声波测的距离的实时显示。
1.4应用场合和功能:
应用场合:智能小车是一种能够通过编程手段完成特定任务的小型化机器人,它具有制作成本低廉,电路结构简单,程序调试方便等优点。由于具有很强的趣味性,智能小车深受广大机器人爱好者以及高校学生的喜爱。同时在玩具的应用上深受小朋友的青睐。
功能:本小车使用AT89S52单片机作为主控芯片,它通过超声波测距来获取小车距离障碍物的距离,并且用LED显示出来,当小车与障碍物的距离大于40cm时,小车会沿直线前进,当小车与障碍物的距离小于30cm时,小车转弯以避开障碍物,并且此时蜂鸣器报警。在避开障碍物后,小车会沿直线前进。



















第二章 总体方案
2.1总体方案概述:
   本小车使用AT89S52单片机作为主控芯片,它通过超声波测距来获取小车距离障碍物的距离,并且用LCD显示出来,当小车与障碍物的距离大于40cm时,小车会沿直线前进,当小车与障碍物的距离小于30cm时,小车转弯以避开障碍物,并且此时蜂鸣器报警。在避开障碍物后,小车会沿直线前进。简要框图如图2-1。


图 2.1:简要框图

2.2 总体电路原理图:

第三章 各模块功能介绍
3.1障碍物测距系统:
方案一:超声波视觉
   优点:价格合理,夜间不受影响。易于多目标测量和分类,分辨率好。缺点:测量范围小,对天气变化敏感。不能直接测量距离,算法复杂,处理速度慢。
方案二:激光雷达MMW雷达
   优点:夜间不受影响,不受灯光、天气影响。缺点:对水、灰尘、灯光敏感、价格贵。
探测障碍的最简单的方法是使用超声波传感器,它是利用向目标发射超声波脉冲,计算其往返时间来判定距离的。算法简单,价格合理。所以我们选择超声波传感器。

超声波测距原理:
首先利用单片机输出一个40kHz的触发信号,把触发信号通过TRIG管脚输入到超声波测距模块,再由超声波测距模块的发射器向某一方向发射超声波,在发射时刻的同时单片机通过软件开始计时,超声波在空气中传播,途中碰到障碍物返回,超声波测距模块的接收器收到反射波后通过产生一个回应信号并通过ECHO脚反馈给单片机,此时单片机就立即停止计时。时序图如图1所示。由于超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离,即:S=VT/2,通过单片机来算出距离。
图3.1:超声波测距原理

3.2显示模块:
方案一:用LCD显示。
优点:辐射小、显示内容多 、低耗能、散热小、显示的画面稳定不闪烁。缺点:不适合做图,图像还原不好、有可视范围限制 。
方案二:用LED显示。
优点:亮度高、成本低,缺点:不能显示汉字,显示内容较少。
对于本课题的要求,我们选择LCD实现功能,显示内容多,低功耗,显示画面稳定不闪烁,硬件电路设计简单。

字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。下面以长沙太阳人电子有限公司的1602字符型液晶显示器为例,介绍其用法。一般1602字符型液晶显示器实物如图:























图 3.2.1:1602字符型液晶显示器


3.2.1 1602LCD主要技术参数:
显示容量:16×2个字符
芯片工作电压:4.5—5.5V
工作电流:2.0mA(5.0V)
模块最佳工作电压:5.0V
字符尺寸:2.95×4.35(W×H)mm
3.2.2 引脚功能说明:
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表3-2-1所示:

编号        符号        引脚说明        编号        符号        引脚说明
1        VSS        电源地        9        D2        数据
2        VDD        电源正极        10        D3        数据
3        VL        液晶显示偏压        11        D4        数据
4        RS        数据/命令选择        12        D5        数据
5        R/W        读/写选择        13        D6        数据
6        E        使能信号        14        D7        数据
7        D0        数据        15        BLA        背光源正极
8        D1        数据        16        BLK        背光源负极
表3-2-1:引脚接口说明表
第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
3.2.3 1602LCD的指令说明及时序:
1602液晶模块内部的控制器共有11条控制指令,如表3-2-2所示:

序号        指令        RS        R/W        D7        D6        D5        D4        D3        D2        D1        D0
1        清显示        0        0        0        0        0        0        0        0        0        1
2        光标返回        0        0        0        0        0        0        0        0        1        *
3        置输入模式        0        0        0        0        0        0        0        1        I/D        S
4        显示开/关控制        0        0        0        0        0        0        1        D        C        B
5        光标或字符移位        0        0        0        0        0        1        S/C        R/L        *        *
6        置功能        0        0        0        0        1        DL        N        F        *        *
7        置字符发生存贮器地址        0        0        0        1        字符发生存贮器地址
8        置数据存贮器地址        0        0        1        显示数据存贮器地址
9        读忙标志或地址        0        1        BF        计数器地址
10        写数到CGRAM或DDRAM)        1        0        要写的数据内容
11        从CGRAM或DDRAM读数        1        1        读出的数据内容
表3-2-2:控制命令表
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1为高电平、0为低电平)
指令1:清显示,指令码01H,光标复位到地址00H位置。
指令2:光标复位,光标返回到地址00H。
指令3:光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移 S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。
指令4:显示开关控制。 D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:光标或显示移位 S/C:高电平时移动显示的文字,低电平时移动光标。
指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:字符发生器RAM地址设置。
指令8:DDRAM地址设置。
指令9:读忙信号和光标地址 BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:写数据。
指令11:读数据。
与HD44780相兼容的芯片时序表如下:

读状态        输入        RS=L,R/W=H,E=H        输出        D0—D7=状态字
写指令        输入        RS=L,R/W=L,D0—D7=指令码,E=高脉冲        输出        无
读数据        输入        RS=H,R/W=H,E=H        输出        D0—D7=数据
写数据        输入        RS=H,R/W=L,D0—D7=数据,E=高脉冲        输出        无
表3-2-3:基本操作时序表

读写操作时序如图3.2.2和3.2.3所示:


图 3.2.2 :读操作时序


图 3.2.3 :写操作时序




3.3驱动模块:
方案一:采用ULN2003驱动,它是由7组达林顿晶体管阵列和相应的电阻网络以及钳位二极管网络构成,具有同时驱动7组负载的能力,一般用于高速大功率驱动电路。所以我们不采用这个方案。
方案二:采用由双极性管组成的H桥电路(L298N)。用单片机控制晶体管使之工作在占空比可调的开关状态,精确调整电机转速。这种电路由于工作在管子的饱和截止模式下,则效率非常高;H桥电路保证了可以简单地实现转速和方向的控制,电子开关的速度很快,稳定性也很高。而且它有更强的驱动能力。L298N有过电流保护功能,当出现电机卡死时,可以保护电路和电机等。
L298N有过电流保护功能,当出现电机卡死时,可以保护电路和电机
等。所以我们选择L298N。
下图为L298内部图:
图3.3:L298内部原理图


L298各引脚功能,如下表。
引脚        功能
1、15        SEN1、SEN2        分别为两个H桥的电流反馈脚,不用时可以接地
2、3        1Y1、1Y2        输出端,与对应输入端(IN1、IN2)同逻辑
4        VS        驱动电压,最小值需比输入的低电平电压高2.5V
5、7        IN1、IN2        输入端,TTL电平兼容
6、11        EN1、EN2        使能端,低电平禁止输出
8        GND        地
9        VSS        逻辑电源,4.5~7V
10、12        IN3、IN4        输入端,TTL电平兼容
13、14        2Y1、2Y2        输出端,与对应输入端(IN3、IN4)同逻辑
表3-3-1 封装引脚及功能



驱动电机的运行,I/O端口状态与电机制动对照表,如下。
IN1        IN2        IN3        IN4        EN1        EN2        转速
1        0        1        0        1        1        正转
0        1        0        1        1        1        反转
1        1        1        1        1        1        停止
0        0        0        0        1        1        停止
X        X        X        X        0        0        停止
表3-3-2 I/O端口状态与电机制动对照表

3.4电源模块:
我们选择采用5v的独立的稳压电源。
优点:稳定可靠,且有各种成熟电路可供选用;
缺点:各模块都采用独立电源,会使系统复杂,且可能影响电路电平。
综合电源模块的缺优点,和电路的实际需求,我们采用了两块独立稳压电源,一块给小车的电机驱动供电,一块给小车的芯片供电,这样弥补了单个独立电源供电出现电力不足的情况。










第四章 软件设计
4.1 程序设计流程图
本设计系统软件采用模块化结构,由主程序﹑定时子程序、电机驱动子程序﹑中断子程序、显示子程序﹑算法子程序构成。主程序流程图如图4.1所示。

        图 4.1:主程序流程图
4.2 关键程序设计:
1.        PWM产生程序设计:
void Timer2(void) interrupt 5
{  
        TF2=0;             
RCAP2H=0x0fe;
        RCAP2L=0x33;                              
        ++click;
        if (click>=100) click=0;
        if (click<=ZK1)               
                PWM1=1;
                        else
                        PWM1=0;

        if (click<=ZK2)                        
                PWM2=1;
                        else
                        PWM2=0;                        
}

2.超声波的发射与接受程序设计:
void  zd3()  interrupt 3                  
{
        TH1=0x0f8;
        TL1=0x30;
        timer++;
        if(timer>=200)
        {
                timer=0;
                TX=1;                                        
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                TX=0;
}
}

3.1602的初始化程序的设计:
void ini_lcd1602()
{
  write_lcd1602(0x38,0);
  delay(1);  
  write_lcd1602(0x0c,0);
  delay(1);
  write_lcd1602(0x06,0);
  delay(1);
  write_lcd1602(0x01,0);
  delay(1);  
}

4.1602的写程序的设计:
void write_lcd1602(uchar cmd,uchar i)       
{
    lcd_mang();
        rs=i;
        rw=0;
        e=0;
        _nop_();
        _nop_();       
        e=1;
        _nop_();
        _nop_();
        P0=cmd;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        e=0;       
}

5.1602的判忙程序的设计:
void lcd_mang()
{
   rs=0;
   rw=1;
   e=1;
   _nop_();
_nop_();
_nop_();
_nop_();
   while(P0&0x80);
   e=0;
}



第五章 系统调试
5.1 调试的思路:
        本设计的智能避障小车,一共分为四大模块。分别是:L298驱动模块,超声波测距模块,LCD显示模块以及蜂鸣器报警模块。调试的时候我们可以把四大模块分别调试,最后再把所有模块组合起来再进行最后的整机调试这样一个调试的思路。
5.2 各模块的调试:
5.2.1 LCD的调试:首先根据电路图将显示模块焊好,再用万用表检查电路是否出现短路。一切都正常的情况下,将LCD测试程序烧到芯片中,观察LCD的显示是否正确,如图5.2.1。一开始可能什么都不显示,这个时候我们只需调整LCD 3脚的变阻器阻值即可。

图 5.2.1:LCD测试图

5.2.2 超声波的调试:
        超声波模块一共有四个脚,一个是VCC,一个是GND,还有两个分别是超声波的发射和接收引脚。连接电路时候只需引出四根插线,分别连接到89S52的对应引脚,烧制好测试程序,测试结果图如5.2.2。本设计四根插线分别连接到VCC,GND,还有发射和接收引脚分别为:P3.0和P3.2口。
图 5.2.2:超声波测试图


5.2.3 蜂鸣器报警调试:
        蜂鸣器的连接很简单,只需用一个PNP管来做驱动,当低电平到来时蜂鸣器发出声音,当高电平到来时没有声音。本设计中,蜂鸣器连接到P3.4口,如图5.2.3所示。










图5.2.3:蜂鸣器报警电路

5.3 调试心得:
        通过系统的调试,我们可以学到更多的知识,我们也可以发现仿真和实物调试不同的地方。程序设计的结果可能往往和实物调试出的结果不一样,这就需要我们去思考,去斟酌,去改进,以达到预期效果。通过程序和硬件的调试,我们可以更深刻的理解各功能模块之间的联系,也可以明白各调试的步骤。
        在调试的过程中,我也遇到许多问题,例如:我在宿舍调试好小车之后,带到班级时候在插上电源试图让小车跑起来时候,发现超声波模块失去了作用,LCD不再显示数据了,后来我用电脑USB口供电发现也不可以,检查了许久才发现是超声波模块上的电源线和地线的两根插线出现了断路,换线之后LCD正常显示数值,小车正常行驶。整个调试过程需要硬件和软件结合起来调试,要仔细检查电路,认真思考程序。
        硬件部分调试的步骤:
1)        检查原理图连接是否正确
2)        用万用表检查是否有虚焊,引脚短路现象
3)        检查原理图与电路板上引脚是否一致
4)        各模块逐个调试,看看各模块是否能用
5)        整合在一起调试,用电脑USB口供电
6)        在5的基础上用电池供电




















第六章 结论与展望
6.1 结论:
历时三个月的设计过程中,我首先边查资料,边在实验室焊接小车的线路板。在焊接过程中,我感觉到即使是一个简单的电路,要想很轻松的焊好,也不是很容易的事情。有时是“虚焊”的原因,有时可能是阻值选错。在焊接显示电路时,我就错将680欧的电阻焊成了6.8千欧。这使我深深感受到理论与实际间的差距。在调试过程中,发现插上编程器后不能烧制程序,通过检查电路发现,AT89S52芯片的使能端没有接VCC。改好之后重新烧制,发现还是不可以,通过再次检查,发现是共阴管的驱动芯片74LS245的引脚出现焊接错误。通过这些调试,提高了我检查电路的能力,以及巩固了电路图的知识。通过这样的设计,提高了我的动手能力。每天在实验室除了焊接线路板,还可以上机编程,使我软件调试知识也提高了。本设计采用的是89S52单片机,这主要是因为该单片机的稳定性比较好。还可以采用其它系列的单片机。比如采用陵阳单片机,就可以简化编程,但其稳定性不是很好。
   
6.2 展望:
1、在本课题的基础上,我们可以在小车的底座下面装一个吸尘装置,这样就可以在小车行驶的过程中吸除一些预先放好的小纸屑。
2、设计出两辆小车,一辆小车放在另一辆的前面。当前面一辆小车起动时候,后面一辆小车也起动,前面一辆小车转弯的时候后面一辆也跟着转弯,前面一辆小车停止时,后面一辆也跟着停止。












致  谢
历时三个月的毕业设计已经告一段落。经过自己不断的搜索努力以及白老师的耐心指导和热情帮助,本设计已经基本完成。在这段时间里,白老师严谨的治学态度和热忱的工作作风令我十分钦佩,他的指导使我受益非浅。
通过这次毕业设计,使我深刻地认识到学好专业知识的重要性,也理解了理论联系实际的含义,并且检验了大学四年的学习成果。虽然在这次设计中对于知识的运用和衔接还不够熟练。但是我将在以后的工作和学习中继续努力、不断完善。这三个月的设计是对过去所学知识的系统提高和扩充的过程,为今后的发展打下了良好的基础。
由于自身水平有限,设计中一定存在很多不足之处,敬请各位老师批评指正。

























参考资料
1 赵负图,传感器集成电路手册.第一版,化学工业出版社,2004,590~591
2李华,MCS-51系列单片机实用接口技术,第三版,北京:1997年
3张红润,实用自动控制,成都:科技大学出版社。1990年1月
4康华光,电子技术基础,北京:高等教育出版社,1983年10月
5潘新民,微型计算机控制技术,北京:人民邮电技术出版社,1988年3月
6赵依军,单片机微型接口技术。北京:人民邮电技术出版社,1989年3月
7李广弟,单片机基础,北京:北京航空航天大学出版社,2001
8胡汉才,单片机原理及其接口技术,北京:清华大学出版社,1996
9王毅,单片机器件应用手册,北京:人民邮电出版社,1995































附录
1.元器件清单:
序号        元件名称                数量        参数
1        AT89S52单片机                1        ——
2        超声波模块                    1        ——
3        L298n                1       
4        智能避障小车底盘                1       
5        蜂鸣器                1       
6        LCD液晶屏                1       
                               
2.样机实物照片:







3.电路原理图:




















相关程序
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char i;
sbit rs=P2^6;                          //定义引脚
sbit rw=P2^5;
sbit e=P2^7;
sbit TX=P3^0;    //触发信号引脚
sbit FM=P3^4;
sbit PWM1=P3^6;           //pwm信号输出
sbit PWM2=P3^7;
static char click=0;   
unsigned char ZK1,ZK2;
unsigned int  time=0;
unsigned int  timer=0;
unsigned long S;
bit      flag =0;

unsigned char code ASCII[19] =   {'0','1','2','3','4','5','6','7','8','9','.','-','M','J','U',' ','L','I',':'};


static unsigned char DisNum = 0; //显示用指针                                  
           unsigned long S=0;
           unsigned char disbuff[11]           ={ 0};


void Conut(void)
{
                time=TH0*256+TL0;
                TH0=0;
                TL0=0;
               
                S=(time*1.7)/100;
  
                disbuff[0]=13;
                disbuff[1]=14;
                disbuff[2]=15;
                disbuff[3]=16;
                disbuff[4]=17;
                disbuff[5]=18;
                disbuff[6]=S%1000/100;
                disbuff[7]=10;
                disbuff[8]=S%1000%100/10;
                disbuff[9]=S%1000%10 %10;
                disbuff[10]=12;               
}


void delay_1(void)   //误差 0us
{
    unsigned char a,b;
    for(b=215;b>0;b--)
        for(a=45;a>0;a--);
}

void delay(uchar a)
{
     uchar i;
     while(a--)
           {
              for(i=0;i<250;i++)
                    {
                           _nop_();
               _nop_();
                           _nop_();
               _nop_();  
                        }
           }   
}

//判忙
void lcd_mang()
{
   rs=0;
   rw=1;
   e=1;
   _nop_();
        _nop_();
        _nop_();
        _nop_();
   while(P0&0x80);
     e=0;
}

//1602的写
void write_lcd1602(uchar cmd,uchar i)        //当i为0的时候为向1602写指令为1写数据
{
    lcd_mang();
        rs=i;
        rw=0;
        e=0;
        _nop_();
        _nop_();       
        e=1;
        _nop_();
        _nop_();
        P0=cmd;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        e=0;       
}

//1602的初始化
void ini_lcd1602()
{
  write_lcd1602(0x38,0);
  delay(1);  
  write_lcd1602(0x0c,0);
  delay(1);
  write_lcd1602(0x06,0);
  delay(1);
  write_lcd1602(0x01,0);
  delay(1);  
}


void Timer2Interrupt()
{   
        RCAP2H=0x0fe;
        RCAP2L=0x33;
        ET2=1;                                          // 允许T2定时器中断
        EA=1;                                           // 打开总中断
        TR2=1;                                          // 启动T2定时器  
}

void zd0() interrupt 1        
{
        flag=1;                                                         
}

void  zd3()  interrupt 3                  //T1中断用来扫描数码管和计800MS启动模块
{
        TH1=0x0f8;
        TL1=0x30;
        timer++;
        if(timer>=200)
        {
        timer=0;
        TX=1;                                        //800MS  启动一次模块
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        TX=0;
}
}

void Timer2(void) interrupt 5
{  
        TF2=0;   // T2定时器发生溢出中断时,需要用户自己清除溢出标记
           RCAP2H=0x0fe;
        RCAP2L=0x33;                               /*恢复定时器初始值*/
        ++click;
        if (click>=100) click=0;
        if (click<=ZK1)               
                PWM1=1;
                        else
                        PWM1=0;

        if (click<=ZK2)                        
                PWM2=1;
                        else
                        PWM2=0;                        
}
//主函数
void main()
{  
        TMOD=0x19;                   //设T0为方式1,GATE=1;
        TH0=0;
        TL0=0;         
        TH1=0x0f8;                   //2MS定时
        TL1=0x30;
        ET0=1;             //允许T0中断
        ET1=1;                           //允许T1中断
        TR1=1;                           //开启定时器
        Timer2Interrupt();
        EA=1;                           //开启总中断
        ZK1=20;
        ZK2=20;
        ini_lcd1602();
        while(1)
          {


                while(INT0==0);                //当RX为零时等待
                TR0=1;
                while(INT0==1);                        //当RX为1计数并等待
                TR0=0;                                //关闭计数
                Conut();                        //计算
                                if (S>40)                                //控制加速
                                {
                                FM=1;
                                P1=0xaf;
                                ZK1=ZK1-5;
                                ZK2=ZK2-5;
                                }
                                                else
                                                if(S<30)                        //控制转向
                                                        {
                                                        FM=0;
                                                        ZK1=ZK1+5;
                                                        ZK2=ZK2+5;
                                                        P1=0X8F;
                                                        delay_1();
                                                        }               
                if (ZK1>99) ZK1=1;
                if (ZK1<1) ZK1=10;
                if (ZK2>99) ZK2=1;
                if (ZK2<1) ZK2=10;
                 
                write_lcd1602(0x80,0);
                for(i=0;i<=10;i++)
                write_lcd1602(ASCII[disbuff[i]],1);  
       
          }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1 发表于 2014-8-30 21:33 | 只看该作者
怎么没有图呢?
回复

使用道具 举报

板凳
ID:72600 发表于 2015-1-21 18:04 | 只看该作者
图咋看不见呢
回复

使用道具 举报

地板
ID:115002 发表于 2016-4-18 21:35 | 只看该作者
追加,怎么美图呢?
回复

使用道具 举报

5#
ID:91096 发表于 2016-5-31 10:07 | 只看该作者
求图啊啊啊啊啊
回复

使用道具 举报

6#
ID:132602 发表于 2016-7-23 14:34 | 只看该作者
没有图啊。。。
回复

使用道具 举报

7#
ID:497418 发表于 2019-4-28 15:40 | 只看该作者
没有图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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