基于51单片机的智能小车设计

2024-08-31

基于51单片机的智能小车设计(精选10篇)

1.基于51单片机的智能小车设计 篇一

基于单片机的智能跟随小车的设计与实现

【摘要】本文设计了一种能够通过传感器实时采集信号、智能分析周围环境以及路径信息、自动控制方向等功能的智能小车。小车以STC89c52单片机控制为核心,利用车前三个反射式红外发射―接收探头检测周围信息,以及利用光电传感器检测前方物体,并将检测信号反馈给单片机,实现小车的避障和跟随功能。基于STC89C52单片机的智能小车系统结构简单,性价比高,易于推广和移植,具有广阔的应用前景。

【关键词】STC89C52;避障;跟随;光电传感器

引言

随着科技的发展和人民生活水平的提高,越来越多的智能车得到普及普及,和传统汽相比,智能小车具有更好的安全性,机动性和广泛的应用性。智能小车,也就是轮式机器的智能化成果,是一种集传感器应用,智能芯片控制,驱动控制的高科技创意性设计。智能小车的功能是对指定的目标物进行跟踪和实时的躲避障碍物,这是他与其他小车最大的区别也是最大的一个特点。小车通过红外传感器对目标物体进行实时识别和跟踪,并且及时的躲避障碍物,具有灵敏性好,智能化程度高的特点。如果把它用在超市,将会极大地方便人们的生活。如果用在商城和机场,人们也不用提着沉重的行李箱满地跑了。

1、总体方案设计

智能小车总体设计内容:一是STC89C52芯片控制电路的设计;二是驱动电路的设计;三是光电传感器电路的设计;四是避障系统的设计;五是电源稳压电路的设计;六是硬件的焊接组装;七是软件的编程调试。小车总共分为5个部分,以单片机为核心的主控模块,电源模块,红外传感模块,驱动模块,避障模块。具体工作原理是:红外传感器在预设距离内检测前方是否有目标物体,如果有则自动进行跟随。同时,红外光电对管检测前方障碍物,当检测到前方有障碍物并且小于预设值时将把信息发回给单片机,控制驱动电路让车轮停止转动并后退绕过障碍物继续跟随。

2、系统的硬件设计

2.1主控模块

主控模块通过单片机利用程序来精确控制小车的运动,从而实现对小车的自动控制。STC89C52单片机具有控制简单、方便、快捷等优点,因此我们采用STC89C52单片机作为控制芯片。

2.2传感器模块

本设计所采用的传感器是集发射与接收为一体的光电传感器,具有很多其他传感器所没有的特性比如发射机距离远,抗干扰能力强,结构简单,可调节等优良的特点[1]。红外传感器是利用物体对近红外线光束的反射原理,由同步回路感应反射回来的光,据其强弱来检测物体的存在与否。通过有无信号来输出高低电平,然后把信号送给单片机处理,实现实时跟随的功能。红外探测法是避障模块所使用的方法,就是利用红外线在不同颜色的物理表面具有不同反射性质的特点来进行避障[2]。由于红外光遇到白光的时候会发生漫反射,光电传感器就可以不断向外发射红外光,接收管就能接收到反射回来的信号,然后发送到单片机。若遇到黑色的物体将不会接收到信号而检测到障碍物进而启动躲避系统。传感器模块原理图如图2所示。

2.3驱动模块

驱动模块采用L298N驱动芯片,总共有四路输入,四路输出。INX均接单片机的P1口,IN1和IN3口控制轮子正转,IN2和IN4口控制轮子逆转,通过调节输入信号的占空比来调节小车轮子转动的速度。当小车左侧遇到障碍物时,驱动电路控制右侧轮子不动,左侧轮子加速转动,进行右转;当小车右侧遇到障碍物时,情况正好相反;当小车前方遇到障碍物时,驱动电路控制轮子停止,然后反转后退,绕过障碍物继续前进。

2.4电源模块

电源供电模块,使用的是直流稳压[3]电源,输入的是直流+12V电压,运用三线稳压器件7805,输出+5V直流电压。电源部分电路设计简单方便,同时也充分发挥了稳压器保护电路的作用。

3、系统的软件设计

软件设计部分决定了智能小车能否实现其跟随和避障的功能,是本次设计的关键部分。小车程序分为以下三部分:主程序部分,跟随和避障程序部分,驱动程序部分[4]。主程序流程图如图3所示。

4、仿真测试

基于PROTEUS仿真软件,我们设计了智能跟随小车控制电路的仿真图,如图4所示。

由于PROTEUS软件中没有红外传感器,所以我们用从上到下编号1-6的六个开关代替传感器,来实现探测目标的功能[5]。图中四个电机的转动方向代表四个轮子的转动方向,同时速度的快慢也可以从图中显示出来。首先,闭合开关3,表示发现目标物体,四个轮子正转,并且加速前进,闭合开关4,表示遇到障碍物,轮子停止转动并且反向转动直到障碍物离开检测范围。断开开关3、4,闭合开关5,表示目标物体向左移动,此时左侧轮子停止转动,右侧轮子正转并且加速转动,当小车右侧出现目标物是动作与之相反。闭合开关6,表示左侧有障碍物,这时右侧轮子不动,左侧轮子正转,实现向右转向的目的。当小车右侧出现障碍物时动作与之相反。

5、系统调试

先进行硬件调试,通过仿真好的电路图[6],用万用表检测已经焊好的电路板上每一个节点是否有短路、断路和接触不良的情况,看各个节点电压是否正常。当硬件调试没有问题,完成了以后进行软件调试,通过修改各个接口对应的程序进行调试,最终完成软件的修改,达到了预期的效果。

6、结束语

本次项目设计非常成功,通过老师的指导和我们的团队合作,小车很好了实现了其跟随和避障的功能效果。最然在开始我们对这个项目没有任何的头绪,但是经过我们共同的努力成功完成了这个作品,每一个人都感到了团队合作的艰辛和成功后的喜悦。通过实验测试智能跟随小车的灵敏性,效果良好,能够很好的按照预期完成指定动作,并且运行稳定。

参考文献

[1]周继明,江世明.传感器技术及应用[M].长沙:中南大学出版社,2005.[2]冯博琴,吴宁.微型计算机原理与接口技术[M].北京:清华大学出版社,2011.[3]余锡存,曹国华.单片机原理及接口技术[M].西安:西安电子科技大学出版社,2007.[4]李学礼.基于Proteus 的8051单片机的实例教程[M].北京:电子工业出版社,2008.[5]谭浩强.C++面向对象程序设计[M].清华大学出版社,2006.[6]周润景,郝晓霞.传感器与检测技术[M].北京:电子工业出版社,2009.[7]来清民.传感器与单片机接口及实例[M].北京:北京航空航天大学出版社,2008.作者简介

张文霞,女,1982年生,鄂尔多斯市人,在读博士,讲师,工作于内蒙古大学鄂尔多斯学院,研究方向为图像处理及模式识别。

2.基于51单片机的智能小车设计 篇二

随着汽车工业的迅速发展, 关于汽车的研究也就越来越受人关注[1]。全国电子大赛和各省电子大赛几乎每次都有智能小车这方面的题目, 全国各高校也都很重视该课题的研究, 可见其具有重要的研究意义。智能小车是一个集环境感知、规划决策、自动行驶等功能于一体的综合系统, 它集中地运用了计算机、传感、信息、通信、导航、人工智能及自动控制等技术, 是典型的高新技术综合体[2]。本设计的智能小车实现了实时显示时间、里程, 红外线遥控控制, 自动避障三大功能。

1、系统硬件电路设计

系统功能原理图如图1所示。

智能小车采用AT80C51单片机进行智能控制。开始由手动启动小车, 并复位, 当有红外遥控信号时, 根据信号进入相应的行驶状态。在运动过程中由超声波传感器和红外光电传感器检测, 通过单片机控制小车开始记数显示并避障;系统的自动避障功能通过超声波传感器正前方检测, 由单片机控制实现;在小车行驶过程中, 采用双极式H型PWM脉宽调制技术, 以提高系统的静动态性能;采用动态共阴显示行驶时间和里程。

1.1 超声波测距电路

为了使智能小车能自动避障行驶, 就必须有测距电路, 以使其及时获取距障碍物的距离信息 (距离和方向) 。测距电路包括发射电路和接收电路。其工作原理为:超声波发射器向某一方向发射超声波, 在发射的同时开始计时, 超声波在空气中传播, 途中碰到障碍物就立即反射回来, 超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s, 根据计时器记录的时间t, 就可以计算出发射点距障碍物的距离s, 即:s=340t/2。

本系统发射电路的基本要求就是能由单片机控制并产生稳定的40KHz方波, 而接收电路的要求就是把接收到的信号进行放大到足以引起单片机的外部中断, 使其来控制小车的后续动作。

1.2 行车距离检测电路

由于红外检测具有反应速度快、定位精度高, 可靠性强以及可见光传感器所不能比拟的优点, 故采用红外光电码盘测速方案。

为实现可逆记数功能, 我们在测距仪中并列放置了两个槽型光电耦合器, 遮光盘先后通过凹槽可产生两个脉冲信号。根据两个脉冲信号发生的先后顺序与两个光电耦合器的位置关系, 即可计算出玩具车的行驶方向 (前进或后退) 。其测距原理为:将光栅安装在电机轴上, 当电机转动时, 光栅也随之转动, 同时安装在光栅一侧的红外发光二极管点亮, 在光栅另一侧的红外三极管用于接收红外发光二极管发出的红外线信号。由于光栅随电机高速转动, 则红外线三极管接收到的就是一系列脉冲信号。将该信号传输到AT80C51单片机的内部计数器计数, 根据预先实测的数据换算关系即可计算出小车的行车距离。

1.3 PWM调速电路

为顺利实现电动小汽车的左转和右转, 本设计采用了可逆PWM变换器。可逆PWM变换器主电路的结构式有H型、T型等类型。本设计中采用了常用的双极式H型变换器, 它是由4个三极电力晶体管和4个续流二极管组成的桥式电路。

脉宽调制器本身是一个由运算放大器和几个输入信号组成的电压比较器。运算放大器工作在开关状态, 稍微有一点输入信号就可使其输出电压达到饱和值, 当输入电压极性改变时, 输出电压就在正、负饱和值之间变化, 这样就完成了把连续电压变成脉冲电压的转换作用。加在运算放大器反相输入端上的有三个输入信号。一个输入信号是锯齿波调制信号, 另一个是控制电压, 其极性大小可随时改变, 与锯齿波调制信号相减, 从而在运算放大器的输出端得到周期不变、脉宽可变的调制输出电压。只要改变控制电压的极性, 也就改变了PWM变换器输出平均电压的极性, 因而改变了电动机的转向。改变控制电压的大小, 则调节了输出脉冲电压的宽度, 从而调节电动机的转速。只要锯齿波的线性度足够好, 输出脉冲的宽度是和控制电压的大小成正比的。

1.4 显示电路[3]

数码管由于显示速度快, 使用简单, 显示效果简洁明了而得到了广泛应用[8]。本设计采用8片74LS373控制数码管作显示器, 并具有双重功能, 在小车不行驶时显示年月和时分;当小车行驶时, 分别显示时间和行驶距离。通过对74LS373的锁存使能端进行控制来实现对8个数码管的显示和更新。

2、系统软件设计[4,5]

本设计系统软件采用模块化结构, 由主程序﹑定时子程序、避障子程序﹑中断子程序、显示子程序﹑调速子程序﹑算法子程序构成。主程序流程图如图2所示。

其中:避障中断服务子程序完成对超声波探测器产生的外部中断进行处理, 如果超出预定的危险距离就左转进行避障。

遥控中断服务子程序完成对遥控信号产生的外部中断进行处理, 对不同的遥控信号产生相应的控制信号。

在定时中断服务子程序, 完成定时与里程的计算。

3、系统功能测试

本设计是以AT80C51为核心, 经过调试, 小车基本上可以实现红外遥控控制、遇到障碍物时减速左转避障、前进、后退、左右转、显示行车时间和里程等功能。但有些功能还需改进, 比如小车的调速系统反应时间还有待缩短等。

4、结语

本文给出了基于高性能单片机AT80C51的智能小车的硬件和软件模块设计。采用单片机作为核心处理芯片, 具有编程灵活、易于控制、稳定性好、扩展方便的优点。整个系统采用模块化设计, 使得系统具有良好的可升级性和扩展性。

参考文献

[1].齐英鑫.基于80C51单片机的智能电动小车[J].科技信息, 2008 (31) :36-37.

[2].寸晓非.基于16位单片机的智能小车设计[J].荆门职业技术学院学报, 2008, 23 (3) :38-42.

[3].董涛, 刘进英, 蒋苏.基于单片机的智能小车的设计与制作[J].计算机测量与控制, 2009, 17 (2) :380-382.

[4].电子工程师论坛[EB/OL].http://pdf.18ic.com/bbs_index.html.

3.基于51单片机的智能小车设计 篇三

摘要:本文介绍了一款基于红外遥控技术与单片机控制技术的遥控温度检测报警小车的设计。采用C语言编程控制单片机核心,设计和完成了能够遥控测温并在显示器上实时显示温度的小车。文章阐述了项目背景、模块设计、业务流程以及模块功能实现的分析;经测试达到功能目的,配合相关的电路设计图,可做为在校学生的实践项目进行使用。

关键词:单片机 无线遥控 温度检测小车

现代信息技术的三大基础是信息采集(即传感器技术)、信息传输(通信技术)和信息处理(计算机技术)。传感器属于信息技术的前沿尖端产品,尤其是温度传感器被广泛用,数量高居各种传感器之首。数字温度传感器可以直接将被检测的温度信息以数字化形式输出,而单片机微处理器越来越丰富的外围功能模块,更加方便了数字式温度传感器输出信号的处理。将单片机控制的小车和数字温度传感器结合起来,形成一个遥控的实时测温平台,对于在学院学习单片机控制专业课的学生来讲是一个好的研究项目。

1 总体设计思路及分析

本设计主要包括以下部分:主控制器STC89C52,红外收发,温度采集与显示,蜂鸣器报警,红外遥控,小车装置。为求的系统的稳定,且有较大的灵活性,其中温度采集采用高精度的数字温度传感器DS18B20,蜂鸣器进行报警,实测温度值通过数码管显示。同时为增加系统绝对可控性,自动化性,红外遥控发射遥控小车做大范围的测控无人化测控。如图1所示。

2 项目实现

2.1 单片机控制模块。STC89C52控制器是增强型的51微型控制器,本系统的软件程序用C语言编写,主要分为主程序,外部中断解码子程序,定时器1中断程序,显示子程序,小车行进子程序。主程序完成系统的硬件初始化,子程序调用的功能。关于定时器和外部中断初始化的部分设置如下:

TMOD=0x02;

TH0=0x00;

TL0=0x00;

EA=1;

ET0=1;

TR0=1;

IT0=1;

EX0=1;

......

2.2 温度检测模块。温度报警器采用DALLAS公司生产的单线数字温度传感器DS18B20,可以把温度信号直接转换成串行数字信号供微机处理;其测温范围-55℃~+125℃,可实现高精度测温在9位分辨率时最多在93.75ms内把温度转换为数字,且硬件电路十分简单。

本测温系统只有一个从机DS18B20,所以进行温度转换时先初始化,然后直接向ds18B20发温度转换命令进行温度转换,其过程如下所示:①初始化DS18B20:init();②紧接着发送温度转化指令write_byte(0xcc);write_byte(0x44);③再次初始化温感init();④发送温度读取指令write_byte(0xcc) ;write_byte(0xbe);⑤定义一个整形或字符型内存变量接受温度数据的高低位low=read_byte() ;high=read_byte();⑥合并温度数据的高低位使温度数据的二进制表示,转化后可得十进制温度。

2.3 红外遥控模块。TC9012作为红外遥控器控制核心,遥控编码脉冲信号是由引导码、系统码、系统反码、功能码、功能反码等信号组成。以PPM码(脉冲位置调制码)对红外数据调制在38KHz的载波上对外进行发射信号。

HS1838是用于红外遥控接收的小型一体化接收头,集成红外线的接收、放大、解调,不需要任何外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输,中心频率38.0kHz。

2.4 小车电机驱动模块。L9110直流电机的驱动芯片是为控制和驱动电机设计的两通道推挽式功率放大专用集成电路器件,将分立电路集成在单片IC 之中,使外围器件成本降低,整机可靠性提高。

Cargo()子程序完成从主程序接受从遥控器传递的参数,实现对应的小车控制操作:

void cargo(uchar right1,uchar right2,uchar left1 ,uchar left2)

{

youdj1=right1 ;

youdj2=right2 ;

zuodj1=left1 ;

zuodj2=left2 ;

}

其中youdj1,youdj2,zuodj1,zuodj2对应单片机P10,P11,P12,P13端口,对应的电机端分别是右电机负极,右电机正极,左电机正极,左电机负极。

传递参数对应小车控制为:

cargo(0,1,1,0) 左右电机全部正转,小车前进

cargo(0,0,1,0) 左电机停止,右电机正转,小车左拐

cargo(0,1,0,0) 右电机停止,左电机正转,小车右拐

cargo(0,1,1,0) 左右电机全部反转,小车后退

cargo(0,0,0,0) 左右电机全部停止,小车停止

3 结束语

设计采用STC89C52单片机作为控制器,使用C语言编写相关程序,调试完成了无线小车自动测温功能。电源部分应用轻便的锂电池材料使得动力得到保障,由于红外遥控下的电机灵敏度略低,故在小车行进控制上略显不足,后期将主要改进小车温度远程传送的问题,总体上满足在校大学生初级阶段的学习需要。

参考文献:

[1]吴健,侯文,郑宾.基于STC89C52单片机的温度控制系统[J]. 电脑知识与技术,2011(04).

[2]周鹏.基于STC89C52单片机的多功能测温仪设计[J].微型机与应用,2013(01).

4.基于51单片机的智能小车设计 篇四

题:

基于51单片机数字温度计设计

业:

电子信息工程

级:

号:

名:

指导教师:

设计日期:

成绩:

XX大学XX学院电气学院

基于51单片机数字温度计设计

一、设计目的1、掌握单片机电路的设计原理、组装与调试方法。

2、掌握LED数码显示电路的设计和使用方法。

3、掌握DS18B20温度传感器的工作原理及使用方法。

二、设计要求

1、本次单片机课程设计要求以51系列单片机为核心,以开发板为平台。

2、设计一个数字式温度计,要求使用DS18B20温度传感器测量温度。

3、经单片机处理后,要求用4位一体共阴LED数码管来设计显示电路,以显示测量的温度值。

4、另外还要求在设计中加入报警系统,如果我们所设计的系统用来监控某一设备,当设备的温度超过或低于我们所设定的温度值时,系统会产生报警。

5、要求在设计中加入上下限警报温度设置电路。

三、设计的具体实现

1数字温度计设计的方案

在做数字温度计的单片机电路中,对信号的采集电路大多都是使用传感器,这是非常容易实现的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。采集之后,通过使用51系列的单片机,可以对数据进行相应的处理,再由LED显示电路对其数据进行显示。

2系统设计框图

温度计电路设计总体设计方框图如下图所示,控制器采用单片机AT89C51,温度传感器采用DS18B20,用4位一体共阴LED数码管以串口传送数据实现温度显示。此外,还添加了报警系统,对温度实施监控。

3主控器AT89C51芯片

对于单片机的选择,可以考虑使用8031与8051系列,由于8031没有内部RAM,系统又需要大量内存存储数据,因而不适用。AT89C51

以低价位单片机可为提供许多高性价比的应用场合,可灵活应用于各种控制领域,对于简单的测温系统已经足够。单片机AT89C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要该器件是INTEL公司生产的MCS一5l系列单片机中的基础产品,采用了可靠的CMOS工艺制造技术,具有高性能的8位单片机,属于标准的MCS—51的CMOS产品。

AT8951的管脚如下图所示:

AT89C51芯片管脚图

4时钟电路

80C51时钟有两种方式产生,即内部方式和外部方式。80C51中有一个构成内部震荡器的高增益反向放大器,引脚XTAL1和XTAL2分别是该放大器的输入端和输出端。本次采用内部震荡电路,瓷片电容采用22PF,晶振为12MHZ。

晶体震荡电路图

复位电路

单片机系统的复位电路在这里采用的是上电+按钮复位电路形式,其中电阻R采用10KΩ的阻值,电容采用10μF的电容值。

复位电路

温度传感电路

DALLAS

最新单线数字温度传感器DS18B20是一种新型的“一线器件”,其体积更小、更适用于多种场合、且适用电压更宽、更经济。DALLAS

半导体公司的数字化温度传感器DS18B20是世界上第一片支持“一线总线”接口的温度传感器。温度测量范围为-55~+125

摄氏度,可编程为9位~12

位转换精度,测温分辨率可达0.0625摄氏度,分辨率设定参数以及用户设定的报警温度存储在EEPROM

中,掉电后依然保存。被测温度用符号扩展的16位数字量方式串行输出。

DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列、各种封装形式,DQ

为数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源;GND为地信号;VDD为可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地,如下图所示。

DS18B20管脚图

显示电路

对于数字温度的显示,我们采用4位一体共阴LED数码管。足够显示0~100中各位数,并且还能显示一位小数部分。

4位LED数码显示管

温度报警电路

对于数字温度计的设计,除了温度的数字显示功能外还加入了报警系统,当测量的温度超过或低于我们所设定的温度值时,系统会产生报警并亮红灯报警。

其电路图如下所示。

蜂鸣器红灯报警系统电路图

源程序:

/********************************************************************

*

程序名;

基于51单片机的温度计

*

能:

实时测量温度,超过上下限报警,报警温度可手动调整。K1是用来

*

进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限

*

调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动

*

退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除

*

按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能,*

K1是实现减1功能,K3是用来设定上下限温度正负的。

*********************************************************************/

#include

#include//将intrins.h头文件包含到主程序(调用其中的_nop_()空操作函数延时)

#define

uint

unsigned

int

#define

uchar

unsigned

char

uchar

max=0x00,min=0x00;

//max是上限报警温度,min是下限报警温度

bit

s=0;

//s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右

bit

s1=0;

//s1标志位用于上下限查看时的显示

void

display1(uint

z);

#include“ds18b20.h“

#include“keyscan.h“

#include“display.h“

/******************************************************/

/*

主函数

/

/*****************************************************/

void

main()

{

beer=1;

//关闭蜂鸣器

led=1;

//关闭LED灯

timer1_init(0);

//初始化定时器1(未启动定时器1)

get_temperature(1);

//首次启动DS18B20获取温度(DS18B20上电后自动将EEPROM中的上下限温度复制到TH和TL寄存器)

while(1)

{

keyscan();

get_temperature(0);

display(temp,temp_d*0.625);

alarm();

}

}

/**********************************************************************

*

程序名;

ds18b20数码管动态显示头文件

*

能:

通过定时器0延时是数码管动态显示

**********************************************************************/

#ifndef

__ds18b20_display_H__

#define

__ds18b20_display_H__

#define

uint

unsigned

int

//变量类型宏定义,用uint表示无符号整形(16位)

#define

uchar

unsigned

char

//变量类型宏定义,用uchar表示无符号字符型(8位)

sbit

wei1=P2^4;

//可位寻址变量定义,用wei1表示P2.4口

sbit

wei2=P2^5;

//用wei2表示P2.5口

sbit

wei3=P2^6;

//用wei3表示P2.6口

sbit

wei4=P2^7;

//用wei4表示P2.7口

uchar

num=0;

//定义num为全局无符号字符型变量,赋初值为‘0’

uchar

code

temperature1[]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//定义显示码表0~9

uchar

code

temperature2[]={

0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

//带小数点的0~9.uchar

code

temperature3[]={

0x00,0x80,0x40,0x76,0x38};//依次是‘不显示’‘.’‘-’‘H’‘L’

/******************************************************/

/

延时子函数

/

/*****************************************************/

void

display_delay(uint

t)

//延时1ms左右

{

uint

i,j;

for(i=t;i>0;i--)

for(j=120;j>0;j--);

}

/******************************************************/

/*

定时器1初始化函数

/

/*****************************************************/

void

timer1_init(bit

t)

{

TMOD=0x10;

TH0=0x3c;

TL0=0xb0;

EA=1;

ET1=1;

TR1=t;

//

局部变量t为1启动定时器1,为0关闭定时器1

}

/******************************************************/

/*

定时器1中断函数

/

/*****************************************************/

void

timer1()

interrupt

{

TH0=0x3c;

//重新赋初值,定时50ms

TL0=0xb0;

num++;

//每进入一次定时器中断num加1(每50ms加1一次)

if(num<5)

{s=1;if(w==1){beer=1;led=1;}else{beer=1;led=1;}}

else

//进入4次中断,定时200ms时若报警标志位w为‘1’则启动报警,不为‘1’不启动

//实现间歇性报警功能

{s=0;if(w==1){beer=0;led=0;}else{beer=1;led=1;}}

if(num>20)

//进入20次中断,定时1s

{

num=0;

//num归0,重新定开始定时1s

s1=0;

//定时1s时间到时自动关闭报警上下限显示功能

v1=1;

//定时1s时间到时自动关闭报警上下限查看功能

}

}

/******************************************************/

/*

调整报警上下限选择函数

/

/*****************************************************/

void

selsct_1(uchar

f,uchar

k)

//消除百位的0显示,及正负温度的显示选择

{

if(f==0)

//若为正温度,百位为0则不显示百位,不为0则显示

{

if(k/100==0)

P0=temperature3[0];

else

P0=temperature1[k/100];

}

if(f==1)

//若为负温度,若十位为0,百位不显示,否则百位显示‘-’

{

if(k%100/10==0)

P0=temperature3[0];

else

P0=temperature3[2];

}

}

void

selsct_2(bit

f,uchar

k)

//消除十位的0显示,及正负温度的显示选择

{

if(f==0)

//若为正温度,百位十位均为0则不显示十位,否则显示十位

{

if((k/100==0)&&(k%100/10==0))

P0=temperature3[0];

else

P0=temperature1[k%100/10];

}

if(f==1)

//若为负温度,若十位为0,十位不显示,否则十位显示‘-’

{

if(k%100/10==0)

P0=temperature3[2];

else

P0=temperature1[k%100/10];

}

}

/******************************************************/

/*

主函数显示

/

/*****************************************************/

void

display(uchar

t,uchar

t_d)

//用于实测温度、上限温度的显示

{

uchar

i;

for(i=0;i<4;i++)

//依次从左至右选通数码管显示,实现动态显示

{

switch(i)

{

case

0:

//选通第一个数码管

wei2=1;

//关第二个数码管

wei3=1;

//关第三个数码管

wei4=1;

//关第四个数码管

wei1=0;

//开第一个数码管

if(a==0){selsct_1(f,t);}

//若a=0则在第一个数码管上显示测量温度的百位或‘-’

if(a==1)

{

P0=temperature3[3];

//若a=1则在第一个数码管上显示‘H’

}

if(a==2)

{

P0=temperature3[4];

//若a=2则在第一个数码管上显示‘L’

}

break;

case

1:

//选通第二个数码管

wei1=1;

wei3=1;

wei4=1;

wei2=0;

if(a==0){selsct_2(f,t);}

//若a=0则在第二个数码管上显示测量温度的十位或‘-’

if(a==1)

//若a=1则在第二个数码管上显示上限报警温度的百位或‘-’

{

if(s==0)

selsct_1(f_max,max);//若s=0则显示第二个数码管,否则不显示

else

P0=temperature3[0];

//通过s标志位的变化实现调节上下限报警温度时数码管的闪烁

if(s1==1)

selsct_1(f_max,max);//若s1=1则显示第二个数码管(s1标志位用于上下限查看时的显示)

}

if(a==2)

//若a=2则在第二个数码管上显示下限报警温度的百位或‘-’

{

if(s==0)

selsct_1(f_min,min);

else

P0=temperature3[0];

if(s1==1)

selsct_1(f_min,min);

}

break;

case

2:

//选通第三个数码管

wei1=1;

wei2=1;

wei4=1;

wei3=0;

if(a==0){P0=temperature2[t%10];}//若a=0则在第三个数码管上显示测量温度的个位

if(a==1)

//若a=1则在第三个数码管上显示上限报警温度的十位或‘-’

{

if(s==0)

selsct_2(f_max,max);//若s=0则显示第三个数码管,否则不显示

else

P0=temperature3[0];

if(s1==1)

selsct_2(f_max,max);//若s1=1则显示第三个数码管

}

if(a==2)

//若a=2则在第三个数码管上显示下限报警温度的十位或‘-’

{

if(s==0)

selsct_2(f_min,min);

else

P0=temperature3[0];

if(s1==1)

selsct_2(f_min,min);

}

break;

case

3:

//选通第四个数码管

wei1=1;

wei2=1;

wei3=1;

wei4=0;

if(a==0){P0=temperature1[t_d];}//若a=0则在第四个数码管上显示测量温度的小数位

if(a==1)

//若a=1则在第四个数码管上显示上限报警温度的个位

{

if(s==0)

P0=temperature1[max%10];//若s=0则显示第四个数码管,否则不显示

else

P0=temperature3[0];

if(s1==1)

P0=temperature1[max%10];//若s1=1则显示第四个数码管

}

if(a==2)

//若a=2则在第四个数码管上显示下限报警温度的个位

{

if(s==0)

P0=temperature1[min%10];

else

P0=temperature3[0];

if(s1==1)

P0=temperature1[min%10];

}

break;

}

display_delay(10);

//每个数码管显示3ms左右

}

}

/******************************************************/

/*

开机显示函数

/

/*****************************************************/

void

display1(uint

z)

//用于开机动画的显示

{

uchar

i,j;

bit

f=0;

for(i=0;i

//‘z’是显示遍数的设定

{

for(j=0;j<4;j++)

//依次从左至右显示‘-’

{

switch(j)

{

case

0:

wei2=1;

wei3=1;

wei4=1;

wei1=0;

break;

P0=temperature3[2];//第一个数码管显示

case

1:

wei1=1;

wei3=1;

wei4=1;

wei2=0;break;

P0=temperature3[2];//第二个数码管显示

case

2:

wei1=1;

wei2=1;

wei4=1;

wei3=0;break;

P0=temperature3[2];//第三个数码管显示

case

3:

wei1=1;

wei2=1;

wei3=1;

wei4=0;break;

P0=temperature3[2];//第四个数码管显示

}

display_delay(400);

//每个数码管显示200ms左右

}

}

}

#endif

/********************************************************************

*

程序名;

DS18B20头文件

*

明:用到的全局变量是:无符号字符型变量temp(测得的温度整数部分),temp_d

*

(测得的温度小数部分),标志位f(测量温度的标志位‘0’表示“正温度”‘1’表

*

示“负温度”),标志位f_max(上限温度的标志位‘0’表示“正温度”、‘1’表

*

示“负温度”),标志位f_min(下限温度的标志位‘0’表示“正温度”、‘1’表

*

示“负温度”),标志位w(报警标志位‘1’启动报警‘0’关闭报警)。

*********************************************************************/

#ifndef

__ds18b20_h__

//定义头文件

#define

__ds18b20_h__

#define

uint

unsigned

int

#define

uchar

unsigned

char

sbit

DQ=

P2^3;

//DS18B20接口

sbit

beer=P1^0;

//用beer表示P1.0

sbit

led=P1^1;

//用led表示P1.1

uchar

temp=0;

//测量温度的整数部分

uchar

temp_d=0;

//测量温度的小数部分

bit

f=0;

//测量温度的标志位,0’表示“正温度”

‘1’表示“负温度”)

bit

f_max=0;

//上限温度的标志位‘0’表示“正温度”

‘1’表示“负温度”)

bit

f_min=0;

//下限温度的标志位‘0’表示“正温度”、‘1’表示“负温度”)

bit

w=0;

//报警标志位‘1’启动报警‘0’关闭报警

/******************************************************/

/*

延时子函数

/

/*****************************************************/

void

ds18b20_delayus(uint

t)

//延时几μs

{

while(t--);

}

void

ds18b20_delayms(uint

t)

//延时1ms左右

{

uint

i,j;

for(i=t;i>0;i--)

for(j=120;j>0;j--);

}

/******************************************************/

/*

DS18B20初始化函数

/

/*****************************************************/

void

ds18b20_init()

{

uchar

c=0;

DQ=1;

DQ=0;

//控制器向DS18B20发低电平脉冲

ds18b20_delayus(80);

//延时15-80μs

DQ=1;

//控制器拉高总线,while(DQ);

//等待DS18B20拉低总线,在60-240μs之间

ds18b20_delayus(150);

//延时,等待上拉电阻拉高总线

DQ=1;

//拉高数据线,准备数据传输;

}

/******************************************************/

/*

DS18B20字节读函数

/

/*****************************************************/

uchar

ds18b20_read()

{

uchar

i;

uchar

d=0;

DQ

=

1;

//准备读;

for(i=8;i>0;i--)

{

d

>>=

1;

//低位先发;

DQ

=

0;

_nop_();

_nop_();

DQ

=

1;

//必须写1,否则读出来的将是不预期的数据;

if(DQ)

//在12us处读取数据;

d

|=

0x80;

ds18b20_delayus(10);

}

return

d;

//返回读取的值

}

/******************************************************/

/*

DS18B20字节写函数

/

/*****************************************************/

void

ds18b20_write(uchar

d)

{

uchar

i;

for(i=8;i>0;i--)

{

DQ=0;

DQ=d&0x01;

ds18b20_delayus(5);

DQ=1;

d

>>=

1;

}

}

/******************************************************/

/*

获取温度函数

/

/*****************************************************/

void

get_temperature(bit

flag)

{

uchar

a=0,b=0,c=0,d=0;

uint

i;

ds18b20_init();

ds18b20_write(0xcc);

//向DS18B20发跳过读ROM命令

ds18b20_write(0x44);

//写启动DS18B20进行温度转换命令,转换结果存入内部RAM

if(flag==1)

{

display1(1);

//用开机动画耗时

}

else

ds18b20_delayms(1);

ds18b20_init();

ds18b20_write(0xcc);

ds18b20_write(0xbe);

a=ds18b20_read();

//读内部RAM

(LSB)

b=ds18b20_read();

//读内部RAM

(MSB)

if(flag==1)

//局部位变量f=1时读上下线报警温度

{

max=ds18b20_read();

//读内部RAM

(TH)

min=ds18b20_read();

//读内部RAM

(Tl)

}

if((max&0x80)==0x80)

//若读取的上限温度的最高位(符号位)为‘1’表明是负温度

{f_max=1;max=(max-0x80);}

//将上限温度符号标志位置‘1’表示负温度,将上限温度装换成无符号数。

if((min&0x80)==0x80)//若读取的下限温度的最高位(符号位)为‘1’表明是负温度

{f_min=1;min=(min-0x80);}

//将下限温度符号标志位置‘1’表示负温度,将下限温度装换成无符号数。

i=b;

i>>=4;

if

(i==0)

{

f=0;

//i为0,正温度,设立正温度标记

temp=((a>>4)|(b<<4));

//整数部分

a=(a&0x0f);

temp_d=a;

//小数部分

}

else

{

f=1;

//i为1,负温度,设立负温度标记

a=~a+1;

b=~b;

temp=((a>>4)|(b<<4));

//整数部分

a=(a&0x0f);

//小数部分

temp_d=a;

}

}

/******************************************************/

/*

存储极限温度函数

/

/*****************************************************/

void

store_t()

{

if(f_max==1)

//若上限温度为负,将上限温度转换成有符号数

max=max+0x80;

if(f_min==1)

//若下限温度为负,将上限温度转换成有符号数

min=min+0x80;

ds18b20_init();

ds18b20_write(0xcc);

ds18b20_write(0x4e);

//向DS18B20发写字节至暂存器2和3(TH和TL)命令

ds18b20_write(max);

//向暂存器TH(上限温度暂存器)写温度

ds18b20_write(min);

//向暂存器TL(下限温度暂存器)写温度

ds18b20_write(0xff);

//向配置寄存器写命令,进行温度值分辨率设置

ds18b20_init();

ds18b20_write(0xcc);

ds18b20_write(0x48);

//向DS18B20发将RAM中2、3字节的内容写入EEPROM

}

//DS18B20上电后会自动将EEPROM中的上下限温度拷贝到TH、TL暂存器

/******************************************************/

/*

温度超限报警函数

/

/*****************************************************/

void

alarm()

{

//若上限值是正值

if(f_max==0)

{

if(f_min==0)

//若下限值是正值

{

if(f==0)

//若测量值是正值

{

if(temp<=min||temp>=max)

{w=1;TR1=1;}

//当测量值小于最小值或大于最大值时报警

if((tempmin))

{w=0;}

//当测量值大于最小值且小于最大值时不报警

}

if(f==1){w=1;TR1=1;}

//若测量值是负值时报警

}

if(f_min==1)

//若下限值是负值

{

if(f==0)

//若测量值是正值

{

if(temp>=max)//当测量值大于最大值时报警

{w=1;TR1=1;}

if(temp

{w=0;}

}

if(f==1)

//若测量值是负值

{

if(temp>=min)//当测量值大于最小值时报警

{w=1;TR1=1;}

if(temp

{w=0;}

}

}

}

if(f_max==1)

//若下限值是负值

{

if(f_min==1)

//若下限值是负值

{

if(f==1)

//若测量值是负值

{

if((temp<=max)||(temp>=min))

{w=1;TR1=1;}

//当测量值小于最大值或大于最小值时报警

if((tempmax))

{w=0;}

//当测量值小于最小值且大于最大值时不报警

}

if(f==0){w=1;TR1=1;}

//若测量值是正值时报警

}

}

}

#endif

/********************************************************************

*

程序名;

基于51单片机的温度计

*

能:

实时测量温度,超过上下限报警,报警温度可手动调整。K1是用来

*

进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限

*

调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动

*

退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除

*

按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能,*

K1是实现减1功能,K3是用来设定上下限温度正负的。

*********************************************************************/

#include

#include

//将intrins.h头文件包含到主程序(调用其中的_nop_()空操作函数延时)

#define

uint

unsigned

int

#define

uchar

unsigned

char

uchar

max=0x00,min=0x00;

//max是上限报警温度,min是下限报警温度

bit

s=0;

//s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右

bit

s1=0;

//s1标志位用于上下限查看时的显示

void

display1(uint

z);

//声明display1()函数(display.h头文件中的函数,ds18b20.h要用应先声明)

#include“ds18b20.h“

#include“keyscan.h“

#include“display.h“

/******************************************************/

/*

主函数

/

/*****************************************************/

void

main()

{

beer=1;

//关闭蜂鸣器

led=1;

//关闭LED灯

timer1_init(0);

//初始化定时器1(未启动定时器1)

get_temperature(1);

//首次启动DS18B20获取温度(DS18B20上电后自动将EEPROM中的上下限温度复制到TH和TL寄存器)

while(1)

{

keyscan();

get_temperature(0);

display(temp,temp_d*0.625);

alarm();

}

}

/**********************************************************************

*

程序名;

ds18b20keyscan函数

*

能:

通过键盘设定设定上下限报警温度

**********************************************************************/

#ifndef

__keyscan_H__

//定义头文件

#define

__keyscan_H__

sbit

key1=P2^2;

sbit

key2=P2^1;

sbit

key3=P2^0;

sbit

key4=P3^3;

uchar

i=0;

//定义全局变量i用于不同功能模式的选择,‘0’正常模式,‘1’上限调节模式,‘2’下限调节模式

uchar

a=0;

//定义全局变量a用于不同模式下数码管显示的选择

bit

k4=0;

//K4按键双功能选择位,k4=0时K4按键选择消按键音的功能,k4=1时K4按键选择正负温度设定功能

bit

v=0;

//K2、K3按键双功能选择位,v=0时选择上下限查看功能,v=1时选择上下限温度加减功能

bit

v1=0;

//v1=1时定时1250ms时间到自动关闭报警上下限查看功能

bit

v2=0;

/消按键音功能调整位,为‘0’时开按键音,为‘1’时关按键音

/******************************************************/

/*

读键盘延时子函数

/

/*****************************************************/

void

keyscan_delay(uint

z)

//延时1ms左右

{

uint

i,j;

for(i=z;i>0;i--)

for(j=120;j>0;j--);

}

/******************************************************/

/*

温度调节函数

/

/*****************************************************/

int

temp_change(int

count,bit

f)

//上下限温度调整

{

if(key2==0)

//判断K2是否按下

{

if(v2==0)beer=0;

//v2=0开按键音,否则消按键音

keyscan_delay(10);

//延时10ms

if(key2==0)

//再次判断K2是否按下(实现按按键时消抖)

{

beer=1;

//K2按下关按键音

if(f==0)

//若温度为正

{

count++;

//每按一下K2温度上调1

if(a==1){if(count>125)

count=125;}//当温度值大于125时不上调

if(a==2){if(count>125)

count=125;}

}

if(f!=0)

//若温度为负

{

count++;

//每按一下K2温度下调1

if(a==1){if(count>55)

count=55;}//当温度值小于-55时不再下调

if(a==2){if(count>55)

count=55;}

}

}

while(key2==0);

//K2松开按键时消抖

keyscan_delay(10);

}

if(key3==0)

{

if(v2==0)beer=0;

keyscan_delay(10);

if(key3==0)

//K3按按键时消抖

{

beer=1;

count--;

//每按一下K3温度为正时下调1,为负时上调1

if(a==1){if(count<0)

count=0;}//当温度值达到0时不再调

if(a==2){if(count<0)

count=0;}

}

while(key3==0);

keyscan_delay(10);

//K3松开按键时消抖

}

return

count;

}

/******************************************************/

/*

读键盘函数

/

/*****************************************************/

void

keyscan()

{

if(key1==0)

{

if(v2==0)beer=0;

keyscan_delay(10);

if(key1==0)

//K1按按键时消抖

{

beer=1;

TR1=1;

//开定时器1,通过s标志位的变化,实现在上下限温度调整时温度显示时闪烁的功能

k4=1;

//在上下温度调节功能模式下选择K4的调整上下限温度正负的功能

v=1;

//在上下温度调节功能模式下选择K2、K3的温度加减功能

i++;

//K1按一下i加1,i=‘0’进入正常模式,i=‘1’进入调上限模式,i=‘2’进入调下限模式

if(i>2)

//K1按下三次后退出调节模式

{

i=0;

//进入正常模式

TR1=0;

//关定时器1

k4=0;

//在正常模式下选择K4的消按键音功能

v=0;

//在正常模式下选择K2、K3的查看上下限报警温度功能

store_t();

//存储调整后的上下限报警温度

}

switch(i)

//显示选择

{

case

0:a=0;break;

//a=0选择显示测得的温度

case

1:a=1;break;

//a=1选择显示上限温度

case

2:a=2;break;

//a=2选择显示下限温度

default:break;

}

}

while(key1==0);

//K1松按键时消抖

keyscan_delay(10);

}

if(a==1&&v==1)

//a=1选择显示上限温度且v=1时选择上下限温度加功能

{led=0;max=temp_change(max,f_max);}//显示上限温度

else

if(a==2&&v==1)

//a=2选择显示下限温度且v=1时选择上下限温度减功能

{led=1;min=temp_change(min,f_min);}

else;

if(k4==1)

//k4=1时K4按键选择正负温度设定功能

{

if(key4==0)

{

if(v2==0)beer=0;

keyscan_delay(5);

if(key4==0)

{

beer=1;

if(a==1)

{if(max>55)

f_max=0;else

f_max=~f_max;}//当温度大于55度时,只能设定为正温度

if(a==2)

{if(min>55)

f_max=0;else

f_min=~f_min;}//当温度大于55度时,只能设定为正温度

}

while(key4==0);

keyscan_delay(10);

}

}

if(v==0)

//v=0时选择上下限查看功能

{

if(key2==0)

{

if(v2==0)beer=0;

keyscan_delay(10);

if(key2==0)

{

beer=1;

a=1;

//选择上限显示

TR1=1;

//开定时器1开始定时一分钟左右

s1=1;

//上限显示不闪烁,显示一分钟左右自动退出

}

while(key2==0);

keyscan_delay(10);

}

if(key3==0)

{

if(v2==0)beer=0;

keyscan_delay(10);

if(key3==0)

{

beer=1;

a=2;

//选择下限显示

TR1=1;

//开定时器1开始定时1s

s1=1;

//下限显示不闪烁,显示1s自动退出

}

while(key3==0);

keyscan_delay(10);

}

if(v1==1)

//v1=1时定时1s时间到自动关闭报警上下限查看功能

{a=0;v1=0;TR1=0;}

//a=0显示实测温度,v1清零,关定时器1

if(k4==0)

//k4=0时K4按键选择消按键音的功能

{

if(key4==0)

{

if(v2==0)beer=0;

keyscan_delay(10);

if(key4==0)

{

beer=1;

v2=~v2;

//为‘0’时开按键音,为‘1’时关按键音

}

while(key4==0);

keyscan_delay(10);

}

}

}

}

#endif

四、总结

单片机的学习与应用相关的总结与体会。在课设过程中,我们不仅巩固了平时所学习的单片机知识,而且通过不断查阅相关资料,学习新的知识,可以说,通过这次单片机的实践学习,我们学到了很多,而且对单片机的有关知识以及其在现实生活中的多方面应用有了更深层次的认识,这对于我们以后的学习和步入社会后参加工作都有很大的帮助。

在此次课程设计的进程中,我们遇到了很多问题,例如,一开始我们在确定课设题目后,在编写程序时,由于思路不太清晰,而且设计要求中需要使用新器件DS18B20智能测温,而其相关知识我们很模糊甚至可以说一无所知,不过后来,我们通过查找一些相关的资料书以及寻求辅导老师的帮助,又经过我们的主动思考,理清思路,终于将程序修改正确。在仿真时,由于我们有了之前的数模电课设仿真经验,所以此时我们课设进行的很顺利,并没有受到什么大的阻碍。

通过此次单片机课程设计,我们明白了很多,理论指导实践,但是理论也需要实践给予证明,不能盲目的相信书本,凡事都要通过自己的思考推敲,否则自己不会取的大的进步。而且在平时的学习生活中应该多和周围的同学相互学习,交流经验,遇到不会的东西时,切忌焦躁,首先要经过自己的独立思考,有了一定想法后,可以去查找相关的资料书刊或者找同学讨论,如果实在解释不了,再去找辅导老师,在这个遇到问题解决问题的过程中,不断加强自我的动脑能力,进而去指导动手能力,也只有这样,在思路清晰,条理顺畅的时候,再去进行软件编写和硬件操作工作,才有可能起到事半功倍的效果。

五、附录

系统硬件原理电路图

数字温度计设计器材表

单片机STC89C52

DS18B20

晶振12M

三极管8850

电容30PF

电解电容10UF/25V

小蜂鸣器

LED

ø5红

电阻10k,3k,2k,1k,510,330

各5

4位一体共阴数码管

AC/DC(5V/1A)电源

IC插座40

9X15cm万用板

六、参考文献

5.基于51单片机的智能小车设计 篇五

摘 要:本文提出了一种应用于智能小车的光源位置及光强检测的设计方案。该方案由硅光电池、A/D及D/A转换器PCF8591t完成光信号的采集和转换,由单片机完成数据处理和小车运动控制。使小车能够根据光源位置、光线强弱的变化实现快速寻光。

关键词:PCF8591t 硅光电池 单片机 智能追光小车

中图分类号:TP311 文献标识码:A 文章编号:1007-9416(2011)04-0148-03

1、引言

随着机器人控制技术的发展和成熟,智能小车作为其中的典型代表广泛应用于科研、生活、教学等各个方面。仅从历年省级乃至全国的电子设计大赛的比赛项目中都可以看到智能小车的身影。智能小车通过所搭载的各类传感器来实现避障、巡线、防碰撞、追光、搬运等各类功能,而相关控制功能实现的好坏于传感器的性能有着密不可分的关系。本方案旨在设计一种可应用于智能小车上的结构简单、使用方便、性能稳定的光源及光强检测模块。

2、总体设计方案

如图1所示。

在本方案中,光源的检测由分布在小车车身不同位置的多个硅光电池来实现,将所采集的光源信号送至PCF8591t进行A/D转换,而后由单片机依据转换后的信号作出判断来控制小车的运动,从而实现小车追光运动。其中光源检测电路的数目可依据实际情况进行选择。

3、硬件设计方案

3.1 光源信号采集电路

这部分电路主要实现光源信号的采集,目前很多智能小车对于光信号的检测通常采用光敏电阻来实现,但光敏电阻的检测结果容易受到周围环境的影响,而且由于光敏电阻本身的特点,使检测结果与实际光强无法呈线性关系,使得检测结果误差较大。而专门的光强检测芯片价格又较高,如需在一台小车上配置多个检测芯片的话,这将是一笔不小的开销。

本方案中采用硅光电池进行光信号检测,硅光电池两侧的输出电压能够跟随外界光线强弱变化,而且光电池具有响应速度快,使用方便,频率范围宽,价格低的优点。其应用电路如图2所示,图中光电池两端的电压经过隔离和放大后,得到5V以内的模拟电压输出。图中运放采用通用运放LM358或LM324均可。

如图2所示。

3.2 A/D转换电路

这部分电路完成对光源信号采集电路输出的模拟电压进行A/D转换,其转换结果送至单片机进行处理。电路如图3所示,PCF8591t是Philips(飞利浦)公司生产的具有I2C总线接口的8位A/D及D/A转换器。内部有4路A/D转换输入,1路D/A模拟输出,最高转换速率达11KHz,不过该芯片的基准参考电压需要外接,图3所示电路的参考电压采用芯片本身的供电电压DC+5V。

I2C总线是Philips公司推出的串行总线,它与传统的通信方式相比具有读写方便、结构简单、可维护性好、易实现系统扩展、易实现模块化标准化设计、可靠性高等优点。在与CPU的信息传输过程中仅靠时钟线SCL和数据线SDA就可以实现。PCF8591t的引脚功能如表1所示。

3.2.1 PCF8591t的地址控制字

PCF8591t的地址控制字具体格式描述如表2所示。其中,I2C总线协议规定A/D器件高四位地址为1001,低三位地址为引脚地址A0~A2,由硬件电路决定,地址控制字的最后一位为方向位/,对A/D器件进行读操作时为1,进行写操作时为0。

为描述简单起见,在本方案中,仅分别在智能小车的左前方、右前方共安装了二个光电池,采集后的光源信号分别送至PCF8591t的二个模拟输入通道AIN0和AIN1,故使用一片PCF8591t完全满足要求,此时电路中A0~A2做接地处理,则此时PCF8591t的器件写地址为90H,器件读地址为91H。

3.2.2 PCF8591t的转换控制字

转换控制字用于实现器件的各种功能.如模拟信号由哪几个通道输入、是选择A/D转换功能还是选择D/A转换功能等。控制字节存放在控制寄存器中,总线操作时为主控器发送的第二字节。其格式如表3所示。

其中:D1、DO两位是A/D通道编号:00、01、10、11分别代表通道0~通道3

D2自动增益选择,该位为1时,对当前通道转换后自动切换至下一通道进行转换,为0时不自动进行通道转换,此时可通过软件修改转换通道。

D5、D4模拟量输入选择:00为四路单输入、01为三路差分输入(分别为前三个通道AIN0~AIN2与最后一个通道AIN3的差分输入)、10为两路单端输入(AIN0、AIN1)与一路差分输入配合(AIN2-AIN3)、ll为两路差分输入(AIN0-AIN1、AIN2-AIN3)。

D6 模拟输出允许位,A/D转换时设置为0(此时地址控制字最低位D0此时设置为1),D/A转换时设置为1(此时地址控制字最低位D0此时设置为0)。

3.2.3 PCF8591t的A/D转换

在进行A/D转换时,需要遵循标准的I2C写读时序,其数据读取操作格式和逻辑操作波形时序如图4所示,对PCF8591进行写读操后便立即启动A/D转换,并读出A/D转换结果。其中DATA BYTE N为A/D的转换结果,分别对应于前一个数据读取期间所采样的模拟电压。A/D转换结束后,先发送一个非应答信号位,再发送结束信号位。

需要注意的两个问题:其一,上电复位后地址控制字和转换控制字均为为OOH,在A/D转换时须设置控制字,即须在读操作之前进行控制字节的写入操作。其二,由于在读周期中读出的第一个字节为前一次的转换结果,若需读取当前转换值,应多读一个字节。上电复位后读出的第一字节为80H。

4、软件设计方案

本方案中,智能小车上共安装了二个光电池,其信号放大电路的输出端分别作为PCF8591t的二路模拟信号输入,分别接于AIN0~AIN1。在进行光源检测时,读取每个输入端的A/D转换结果,然后进行综合判断就可以确定当前光源位置,以此来控制小车的运动,实现追光。其中完成单通道A/D转换及光源判断及运动控制部分的流程图如图5所示。

A/D转换的部分程序如下:

unsigned charad_conversion(unsigned char addr,unsigned char ch)

{ unsigned char i;

start();

write_byte(addr);// 发PCF8591t写地址

ack();

write_byte(ch);// 发PCF8591t转换控制字

ack();

stop();

start():

write_byte(addr+1);// 发PCF8591t读地址

ack();

i=read_byte();// 读取前一次转换数据

…………

returni;

}

其中,由于考虑到光电池及电路元件参数的分散性,所以在进行左右侧的转换值比较时,设定了容差范围,当两侧转换结果的差值在容差范围以内时,认为此时两侧的光强是一样的,小车可保持当前运动状态。实际应用时,应根据所选用的光电池特性和放大电路参数进行实际测量,以确定合适的容差范围。

同时,对于小车的运动控制,可采用PWM原理对小车进行调速,以此可方便的控制小车的运行速度和方向。

5、结论

采用本方案设计的智能小车追光系统,在实际应用中效果理想,性能稳定。而且由于PCF8591t在一片芯片中集成了4路A/D和1路D/A转换功能,且模拟输入有单端和差分方式可选,故给设计提供了很大的灵活性。而且芯片的通讯协议为I2C总线方式,在使用中为电路的设计提供了很大的方便,也为系统芯片有限的I/O口提供了最大的使用效率,同时具有读写操作简单,速度快,性能稳定,扩展方便等优点,还可以和其它I2C总线接口的器件构建功能较为全面的传感器系统,这一点在智能控制领域有着较为广阔的应用前景。

参考文献

6.基于51单片机的智能小车设计 篇六

51单片机课程设计报告

学院:

专业班级:姓名:

指导教师:

设计时间:

51单片机课程设计

一、设计任务与要求

1.任务:制作并调试51单片机学习板 2.要求:

(1)了解并能识别学习板上的各种元器件,会读元器件标示;(2)会看电路原理图;

(3)制作51单片机学习板;

(4)学会使用Keil C软件下载调试程序;

用调试程序将51单片机学习板调试成功。

二、总原理图及元器件清单

1.总原理图

要求:用铅笔在A4纸整页绘制

2.元件清单

三、模块电路分析

1.最小系统:

单片机最小系统电路分为振荡电路和复位电路,振荡电路选用 12MHz 高精度晶振, 振荡电容选用 22p和30p 独石电容;

晶振为单片机提供时钟激励,保证单片机内部和外部电路的时序逻辑电路协调动作,课程中使用的是12M的晶振,可以产生每秒12M频率的激

励。而构成振荡回路的俩个电容为负载电容,可以影响晶振的谐振频率和振荡幅度。

图 1图

2复位电路使用 RC 电路,使用普通的电解电容与金属膜电阻即可;

3当单片机上电瞬间由于电容电压不能突变会使电容两边的电位相同,此时RST为高电平,之后随着时间推移电源负极通过电阻对电容放电,放完电时RST为低电平。正常工作为低电平,高电平复位。(分析振荡电路:测振荡频率; 分析复位电路:高或低电平复位?)

2.显示模块:

发光二极管显示电路:

Usb的为系统加电时,power的发光二极管处于高电位,发光。当程序控制其余四个脚的电位为低电位,输出端口为高电位,剩下的四个发光二极管发光

4数码管显示电路

本课程使用数码管显示状态为静态显示。静态显示就是显示驱动电路具有

输出锁存功能。单片机将所要显示的数据输出后,数码管显示数据不变。Cpu不再控制led。静态显示的接口电路采用一个并行口接一个数码管。数码管的公共端按共阴极或共阳极分别接地或

VCC

5四、硬件调试

1、是否短路

用万用表检查P2两端是短路。电阻为0,则短路,电阻为一适值,电路正常。

2、焊接顺序

焊接的顺序很重要,按功能划分的器件进行焊接,顺序是功能部件的焊接--调试--另一功能部件的焊接,这样容易找到问题的所在。

3、器件功能

1)检查原理图连接是否正确

2)检查原理图与PCB图是否一致

3)检查原理图与器件的DATASHEET上引脚是否一致 4)用万用表检查是否有虚焊,引脚短路现象

5)查询器件的DATASHEET,分析一下时序是否一致,同时分析一下命令字是否正确

6)通过示波器对芯片各个引脚进行检查,检查地址线是否有信号的7)飞线。用别的的口线进行控制,看看能不能对其进行正常操作,多试验,才能找到问题出现在什么地方。

六、软件调试

1、设置硬件仿真环境

单片机应用系统程序的编译和仿真在KeilμVision环境下进行,在调试程序之前,需要对工程进行Debug设置,选择软件仿真或硬件仿真。软件仿真使用计算机来模拟程序的运行,不需要建立硬件平台就可以快速得到某些运行结果;硬件仿真是最准确的仿真方法,必须建立硬件平台,通过PC机→硬件仿真器→用户目标系统进行系统调试。采用硬件仿真的方法,硬件平台即为带有图1所示接口电路的单片机应用系统,设置硬件仿真环境的具体操作步骤如下:

首先,点击所建工程:Project菜单中的Options for Target„Targer 1‟,出现工程的配置窗口,点击Debug设置,选择KeilMcmitor-51 Driver,具体参数设置如图6所示。

图 6

然后,设置仿真器参数。建议波特率设置范围300~38 400。为避免程序中的中断和Keil硬件仿真环境中的中断互相冲突,不选择“Stop ProgramExecution with SerialInterrupt”。仿真器参数的设置如图7所示。

图7

完成51单片机在Keil μVision环境中的硬件仿真环境设置后,可以进行程序的调试仿真。

2、调试仿真

1)导入测试代码:文件→打开→key and display.Uv2 2)重建全部工程:工程→重建全部目标文件

重建结果为,“DA_5615” – 0 Error(s), 0 Warning(s).3)调试:调试→Start/Stop Debug session(Ctrl + F5)

调试结果为:Connected to Monitor_51 V3.4Load “C:......DA_56511、详细描述软件调试步骤。及各模块调试结果。

2、详细描述调试过程中出现的故障现象,并作故障分析,及解决方法

七、心得

7.基于51单片机的智能小车设计 篇七

现在的社会工作压力大时间紧,容易忽视室内卫生的保持,久而久之就会影响人体的健康。本文利用传感器、控制器、执行器等相应技术实现对人经过的地方进行打扫,系统会持续对工作区域进行监测,当有人或动物经过时,记录所经过的位置,然后将采集到的信息传到控制中心进行决策,最后驱动执行器执行清洁工作,从而保持室内卫生的干净。

1 系统设计

本系统按照采集—决策—执行的流程完成清洁工作,红外传感器和距离传感器检测工作区域内是否有人或物体经过并测量距离数据。单片机采集和计算路程值,并下达指令驱动清洁车前往目标地点完成清洁工作,同时采集下一个位置点,待所有需要清洁的位置都完成后,清洁车返回原位置,继续对工作区域进行监测,系统结构图如图1所示。

2 电路设计

本系统的硬件部分采用模块化设计来实现各功能,以STC89C52单片机为控制核心,包括超声波模块、人体红外感应模块、测速模块、电机驱动模块、清洁电机驱动电路、控制器。

2.1 HC-SR04超声波模块

HC-SR04模块采用I0触发测距,模块自动发送8个40 khz的方波,自动检测是否有信号返回,如果有信号返回,通过I0输出高电平,高电平持续时间就是超声波从发射到返回的时间,根据测试距离=(高电持续时间×声速)/2,声速=340/s,就可计算距离,电路结构如图2所示。

2.2 HC-SR501红外感应模块

图3是HC-SR501红外感应模块的电路原理图,LHI778是热释电红外传感器,输出端Vo连接单片机。其中BISS0001是信号处理芯片,此模块实时检测外界情况。

2.3 测速传感器模块

系统采用槽型光耦传感器测量速度,发射器和接收器分别位于U型槽的两边,可以安全可靠地检测高速变化,电路结构如图4所示。

2.4 电机驱动模块

此模块为双路H桥电机驱动,可以同时驱动两路直流电机或者1个4线两相式步进电机,电路结构如图5所示。

2.5 清洁电机驱动电路

当条件满足时单片机控制I0从而控制电机旋转。电机驱动电路如图6。

2.6 可编程控制器(STC89C52)

本系统利用单片机STC89C52作为控制器,主要用到单片机的外部中断0(INT0)和外部中断1(INT1),内部定时器T0和T1。

3 软件设计

软件采用C语言编写,单片机通电后程序进入初始化,然后进行信息采集送往单片机进行决策,根据程序控制完成工作。程序流程如图7。

4 结语

本系统结合传感器和编程技术实现了对卫生的及时清洁和保持功能,可以帮助人们进行清洁工作,实践应用表明该系统电路简单、工作稳定,具有一定市场价值。

参考文献

[1]谢富珍,戈林发.基于51单片机的智能小车设计[J].新余学院学报,2015(20):6-9.

[2]孙浩.PROTUES软件在设计电子电路中的应用[J].仪表技术,2009(8):74-75.

[3]黄春平,万其明,叶林.51单片机的智能循迹小车的设计[J].仪表技术,2011(2):54-56.

[4]孔庆芳.智能机器小车的设计与实现[J].电子制作,2015(2):21.

8.基于51单片机的智能小车设计 篇八

【关键词】 LED显示屏 Proteus仿真 单片机 点阵字库

1 引言

LED显示屏具有功耗小、亮度高,寿命长,性能稳定,驱动简单以及可视距离远等优点,已经成为最受欢迎的信息传播媒体工具。目前,LED显示屏应用十分广泛,如城市广场群显示、道路交通信息显示、世界杯体育场馆显示比赛信息、世界博览会会会场馆照明等各个领域。显示汉字信息时,一般需要多个LED点阵显示组合,最常见的组合方式有8x8,16×16,32×16等。本文将介绍由Proteus软件进行的LED显示屏仿真电路设计。

2 Proteus软件介绍

Proteus 7.4软件集电路设计、制版及仿真等多种功能于一身,是目前世界上较为先进、完整的嵌入式系统设计与仿真平台。它是一种可视化的支持多种型号单片机(如51 、PIC、AVR 等),并且支持与当前流行的单片机开发环境( Keil、IAR等) 连接调试的软硬件仿真系统。针对微控制系统与外设的混合电路的电路仿真、软件仿真、系统协同仿真,做到了一体化和互动效果。

PROTEUS 是纯软件环境,可免费下载。 在进行单片机系统的开发时,可以先在软件环境中模拟通过,再进行硬件的投入。这样处理,不仅省时省力,也可以节省因为方案不正确所造成的硬件投入的浪费。本文利AT89C5l单片机作为主控制器,采用Proteus软件实现对16×16 LED点阵汉字的分批显示。仿真运行通过后再进行点阵显示电路制作,大大缩减实际开发周期,节约了开发成本。

3 硬件電路设计

点阵式LED滚动汉字显示屏硬件电路分单片机控制部分、显示驱动、显示模块。设计框图如图1所示。

电路设计的核心是利用单片机读取显示字型码,通过驱动电路对16×16 LED点阵进行动态列扫描,以实现汉字的移动显示。设计选用的单片机为ATMEL公司的AT89C51,显示屏采用16×16 LED点阵。由于Proteus软件目前版本中还没有16×16点阵模块,设计中采用4个8×8点阵模块组合成1个16×16点阵模块。

LED显示屏驱动电路分阳极驱动和阴极驱动。阳极驱动电路向16×16点阵送字型码,本设计采用74HC595。阴极驱动电路对16×16点阵进行列扫描,本设计采用74HCl54。

4 软件设计

AT89C51单片机只有8位数据总线,要向16×16点阵送出16行阳极驱动,需要送两次,或先送上8行,或先送下8行,为了能够实现每一列字型码的完整显示,利用两片74HC595进行锁存,否则会出现字型残缺现象。

16×16共阴极LED点阵由4个8×8点阵构成,需要显示汉字字符串“单片机”,可通过建立数据表格的形式进行。通过16×16点阵汉字字模提取软件,可提取各显示汉字的字模数据, “单片机”字型码表如下:

本设计利用了Keil μVision2软件进行程序编写。 在新建Keil项目时选择AT89C51单片机作为CPU;编写C语言源程序并检查;确认程序无误后在“Options For Target”对话窗口中,选中“Output”选项中的“Create HEX File”,编译链接后就可以生LED.HEX文件。

5 系统调试与仿真

在利用Proteus、 Keil μVision2软件里分别设计好LED显示屏的硬件电路和程序部分后就可以进行系统调试了。Proteus仿真时,单片机需要加载程序,加载程序为从软件设计中获得的LED.HEX文件。在Proteus ISIS中,选中AT89C51并单击鼠标左键,对AT89C51进行设置,设置单片机时钟频率为12MHz,按照正确的文件路径加载LED.HEX文件。设置完毕相应参数后就可以开始仿真了。仿真过程中如有硬件问题可在Proteus软件中直接修改,如有软件问题可在Keil μVision2中修改,通过Keil与Proteus的联合调试就可以得到满意的结果。

6 结论

利用Proteus实现了对点阵式LED滚动汉字显示屏的仿真,显示了“单片机”3个字,达到了良好的设计效果。该仿真电路接近实际电路,可以直接由该电路利用相关软件设计印制电路板,加上电源、时钟和复位电路,就可以制作出实际的点阵式LED汉字显示屏。通过前期仿真缩短了开发周期,降低了开发成本,不失为进行单片机系统设计的有效手段。

参考文献:

[1] 朱清慧,张凤蕊,翟天嵩,等. Proteus 教程2电子线路设计、制版与仿真[M]. 北京:清华大学出版社,2008 :2892310

[2] 朱清慧, 王志奎. Proteus 在L ED 点阵滚动显示屏设计中的应用[J].液晶与显示, 2009(4)

[3] 孙凌燕,黄允千. Proteus 与Keil 软件的整合在单片机实验开发中的应用[J]. 实验室研究与探索, 2008(4)

9.89C51单片机课程设计 篇九

摘 要: 随着现代工农业技术的发展及人们对生活环境要求的提高,人们也迫切需要检测与控制温度。本文通过采用蜂鸣器作为电声元件的温度报警器的设计,阐明了该装置进行设计与制作的具体过程及方法。这种温度报警器结构简单,可操作性强,应用广泛。工作时,温度测量范围为5—38ºC。当前环境温度若超过设定的高温临界温度,由单片机发出报警信号,从而防止带来的不必要的损失。

造成高温火灾有:电气线路短路、过载、接触电阻过大等引发高温或火灾;静电产生高温或或火灾;雷电等强电侵入导致高温或火灾;最主要是机房内电脑、空调等用电设备长时间工作,导致设备老化,空调发生故障,而不能降温;因此机房内所属的电子产品发热快,在短时间内机房温度升高超出设备正常温度,导致系统瘫痪或产生火灾,这时温度报警系统就会发挥应有的功能。

关键词:STC89C51单片机,数字控制,温度计,DS18B20

目 录

摘要.....................................................错误!未定义书签。1 设计要求与方案论证......................................................3 1.1 设计要求..........................................................3 1.2 基本方案..........................................................3 1.2.1 单片机芯片的选择.............................................3 1.2.2 温度传感器设计...............................................3 2 主要元件介绍........................................................2.1 STC89C51介绍..................................................2.1.1 STC89C51引脚介绍........................................2.1.2 单片机最小系统:.............................................5 2.2 DS18B20传感器介绍.................................................5 2.2.1 DS18B20引脚介绍.............................................6 2.2.2 DS18B20的内部结构...........................................6 2.3 数码管介绍........................................................7 2.3.1 数码管概述...................................................7 3 软件部分................................................................8 3.1程序流程图........................................................8 3.2 程序.............................................................8 结论.....................................................................15 参考文献.................................................................16 附录 原理图..............................................................17

主要元件介绍

2.1 STC89C51介绍

2.1.1 STC89C51引脚介绍 ① 主电源引脚(2根)

VCC(Pin40):电源输入,接+5V电源 GND(Pin20):接地线 ②外接晶振引脚(2根)

XTAL1(Pin19):片内振荡电路的输入端 XTAL2(Pin20):片内振荡电路的输出端 ③控制引脚(4根)

RST/VPP(Pin9):复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。ALE/PROG(Pin30):地址锁存允许信号 PSEN(Pin29):外部存储器读选通信号

EA/VPP(Pin31):程序存储器的内外部选通,接低电平从外部程序存储器读指令,如果接高电平则从内部程序存储器读指令。

④可编程输入/输出引脚(32根)

STC89C51单片机有4组8位的可编程I/O口,分别位P0、P1、P2、P3口,每个口有8位(8根引脚),共32根。

P0口(Pin39~Pin32):8位双向I/O口线,名称为P0.0~P0.7 P1口(Pin1~Pin8):8位准双向I/O口线,名称为P1.0~P1.7 P2口(Pin21~Pin28):8位准双向I/O口线,名称为P2.0~P2.7 P3口(Pin10~Pin17):8位准双向I/O口线,名称为P3.0~P3.7

2.2.1 DS18B20引脚介绍

图3:DS18B20引脚

各引脚功能为:I/O为数据输入/输出端(即单线总线),它属于漏极开路输出,外接上拉电阻后,常态下呈高电平。UDD是可供选用的外部电源端,不用时接地,GND为地,NC空脚。

2.2.2 DS18B20的内部结构

DS18B20的内部结构主要包括7部分:寄生电源、温度传感器、64位激光(loser)ROM与单线接口、高速暂存器(即便筏式RAM,用于存放中间数据)、TH触发寄存器和TL触发寄存器,分别用来存储用户设定的温度上下限值、存储和控制逻辑、位循环冗余校验码(CRC)发生器。

图4:DS18B20内部结构

LED 数码显示器是一种由LED发光二极管组合显示字符的显示器件,它使用了8个Led发光二极管,其中七个用于显示字符,一个显示小数点,所以通称为七段发光二极管数码显示器。4位一体数码管,其内部段已连接好,引脚如图所示(数码管的正面朝自己,小数点在下方)。a、b、c、d、e、f、g、dp为段引脚,S1、S2、S3、S4分别表示四个软件设计

3.1 程序流程图

图6:程序流程图

3.2 程序

#include #define uint unsigned int #define uchar unsigned char //宏定义 #define SET P3_1

//定义调整键 #define DEC P3_2

//定义减少键 #define ADD P3_3

//定义增加键 #define BEEP P3_6

//定义蜂鸣器 #define ALAM P1_2

//定义灯光报警

dat>>=1;DQ = 1;// 给脉冲信号 if(DQ)dat|=0x80;Delay_DS18B20(4);} return(dat);} /*****写一个字节*****/ void WriteOneChar(unsigned char dat){ unsigned char i=0;for(i=8;i>0;i--){ DQ = 0;DQ = dat&0x01;Delay_DS18B20(5);DQ = 1;dat>>=1;} } /*****读取温度*****/ unsigned int ReadTemperature(void){ unsigned char a=0;unsigned char b=0;unsigned int t=0;float tt=0;Init_DS18B20();WriteOneChar(0xCC);//跳过读序号列号的操作 WriteOneChar(0x44);//启动温度转换 Init_DS18B20();WriteOneChar(0xCC);//跳过读序号列号的操作 WriteOneChar(0xBE);//读取温度寄存器 a=ReadOneChar();//读低8位 b=ReadOneChar();//读高8位 t=b;t<<=8;t=t|a;tt=t*0.0625;t= tt*10+0.5;//放大10倍输出并四舍五入 return(t);} //======================================

{ P0 = ~0x98;//显示C P2 = 0x7F;Delay(400);P0=~LEDData[n];//显示个位

P2 = 0xDF;Delay(400);P0 =~LEDData[m%10];//显示十位

DIAN = 0;//显示小数点

P2 = 0xF7;Delay(400);P0 =~LEDData[m/10];//显示百位

P2 = 0xFD;Delay(400);P2 = 0xff;//关闭显示 } /*****显示报警温度子程序*****/ void Disp_alarm(uchar baojing){ P0 =~0x98;//显示C P2 = 0x7F;Delay(200);P0 =~LEDData[baojing%10];//显示十位

P2 = 0xDF;Delay(200);P0 =~LEDData[baojing/10];//显示百位

P2 = 0xF7;Delay(200);if(set_st==1)P0 =~0xCE;else if(set_st==2)P0 =~0x1A;//上限H、下限L标示

P2 = 0xFD;Delay(200);P2 = 0xff;//关闭显示 } /*****报警子程序*****/ void Alarm(){ if(x>=10){beep_st=~beep_st;x=0;} if((m>=shangxian&&beep_st==1)||(m

BEEP=0;

ALAM=0;} else

if(x>=10){shanshuo_st=~shanshuo_st;x=0;} if(shanshuo_st){Disp_alarm(shangxian);} } else if(set_st==2){ BEEP=1;//关闭蜂鸣器 ALAM=1;EX0=1;//开启外部中断0 EX1=1;//开启外部中断1 if(x>=10){shanshuo_st=~shanshuo_st;x=0;} if(shanshuo_st){Disp_alarm(xiaxian);} } } }

/*****定时器0中断服务程序*****/ void timer0(void)interrupt 1 { TH0=0x3c;TL0=0xb0;x++;} /*****外部中断0服务程序*****/ void int0(void)interrupt 0 {

EX0=0;//关外部中断0 if(DEC==0&&set_st==1){ do{

Disp_alarm(shangxian);} while(DEC==0);shangxian--;if(shangxian

Disp_alarm(xiaxian);} while(DEC==0);xiaxian--;if(xiaxian<0)xiaxian=0;

参考文献

10.基于51单片机的智能小车设计 篇十

/*********************//注释,还可用//注释掉一行Filename:P_test.c

Chipname:STC89C51RCClockfrequency:1.20MHz***********************/#include“reg52.h”//预处理命令,文件包含预处理命令,后缀名都是.h,标准的MCS-51单片机头文件为”reg51.h”,STC89系列单片机头文件为”reg52.h”#defineunitunsignedint//宏定义预处理命令sbitBZ=P3`7;sbitkey=P1`0;voiddelay(unitms){

uniti;

while(ms--){

for(i=0;i<120;i++);}}

voidmain(void){

while(1)

{

if(key==0)

{

BZ=0x0;delayms(10);BZ=0x1;delayms(50);P0=0xFF;}else{

P0=~P0;

delayms(500);}}}

2.C51的数据类型

C51的数据类型

构造类型

位变量型bit字符型无符号字符型unsignedchar

有符号字符型signedchar

整数型无符号整数型unsignedint

有符号整数型signedint

长整数型无符号长整数型unsignedlongint

有符号长整数型signedlongint

实数型(浮点型)单精度浮点型float

双精度浮点型double

数组类型array结构体类型struct共用体union枚举enum

表3-1类型

指针类型空类型(void)

C51基本数据类型的长度和值域

长度/bit18816163232323224

单字节单字节双字节双字节四字节四字节四字节四字节三字节长度/byte

范围0,10-255-128-1270-65536-32768-32767

位变量型bit

无符号字符型unsignedchar有符号字符型signedchar无符号整数型unsignedint有符号整数型signedint

无符号长整数型unsignedlongint有符号长整数型signedlongint单精度浮点型float双精度浮点型double一般指针类型

3.C51的标识符和关键字

标识符是由字母、数字和下划线组成的字符串,第一个字符必须是字母或下划线,不超过32个字符。

表3-2C51中的关键字关键字autobdatabreakbitcasechar

用途

存储种类声明存储器类型说明程序语句位变量语句程序语句数据类型的声明

说明

用来声明局部变量

可位寻址的内部数据存储器退出最内层循环体

位变量的值是1(true)或0(flase)switch语句中的选择项单字节整数型或字符型数据

关键字codeconstcontinuedatadefaultdodoubleelseenumexternfloatforgotoidataifintinterruptlongpdataregisterreentrantreturnsbitshortsignedsizeofSfrSfr16staticstructswitchtypedefunionunsignedusingvoidvolatilewhilexdata

用途

存储器类型声明存储类型说明程序语句存储器类型说明程序语句程序语句数据类型说明程序语句数据类型说明存储类型说明数据类型说明程序语句程序语句存储器类型说明程序语句数据类型说明中断声明数据类型说明存储器类型说明存储类型说明再入函数说明程序语句位变量声明数据类型说明数据类型说明运算符

特殊功能寄存器声明特殊功能寄存器声明存储类型说明数据类型说明程序语句数据类型说明数据类型说明数据类型说明寄存器组定义数据类型说明数据类型说明程序语句存储器类型说明

说明程序存储器

在程序执行过程中不可修改的变量值退出本次循环,转向下一次循环直接寻址的内部数据存储器Switch语句中的失败选择项构成do...while循环结构双精度浮点数构成if...else选择结构枚举

在其他程序模块中声明了的全局变量单精度浮点型构成for循环结构构成goto循环结构间接寻址的内部数据存储器构成do...while循环结构基本整数型定义一个中断函数长整数型

分页寻址的内部数据存储器使用CPU内部的`寄存器变量定义一个再入函数函数返回

声明一个可位寻址的变量短整数型

有符号数,二进制的最高位位符号位计算表达式或数据类型的字节数声明一个特殊功能寄存器声明一个16位的特殊功能寄存器静态变量结构类型数据构成switch选择语句重新进行数据类型定义联合数据类型无符号数据

定义芯片的工作寄存器无符号数据

声明该变量在程序执行中可被隐含改变构成while和do...while循环语句外部数据存储器

4.C51的常量和变量1)常量

常量就是在程序运行过程中,其值不能改变的数据,包括整型常量、字符常量、字符串常量、实数常量、位标量等。

(1)整型常量:可以用二进制、八进制、十进制、十六进制表示。

无符号整数常量在一个数字后面加上“u”或“U”表示。长整数型常量在后面加上“l”或“L”,无符号长整数型常量在数字后面加上“ul”或“UL”,实数型常量在后面加“f”或“F”。

(2)字符常量:单引号内的字符,不可以显示的控制字符在前加“”组成专用转义字符。(3)字符串常量:双引号内的字符,当双引号内没有字符时是空字符串。在C语言中,字符串常量是作为字符类型数组来处理的,在存储字符串时,系统在字符串尾部加上转义字符“o”,作为该字符串的结束符。

(4)实数常量:有十进制和指数两种表示形式。指数表示的实数为“[±]数字[.数字]e[±]数字”,[]中的内容为可选项

(5)位标量:位标量的值是一个二进制数。2)变量

变量就是在程序运行过程中,其值可以被改变的数据。必须先用标识符作为变量名,并指出所用的数据类型和存储模式,这样编译系统才能为变量分配相应的存储空间。定义变量的格式:[<存储模式>]<类型定义>[存储器类型]<标识符>;类型定义和标识符是必要的。存储模式有四种,自动(auto)、外部(extern)、静态(static)和寄存器(register),默认类型为自动(auto)。

表3-3C51存储类型与MCS-51单片机存储空间的对应关系及其大小存储类型databdataidatapdataxdatacode

与存储空间的对应关系

直接寻址片内数据存储区,访问速度快(128B)

可位寻址片内数据存储区,允许位与字节混合访问(16B)

间接寻址片内数据存储区,可访问片内全部RAM地址空间(256B)

分页寻址片外数据存储区,由MOVX@Ri访问

寻址片外数据存储区(64KB),由MOVX@DPTR访问

寻址代码存储区(64KB),由MOVC@DPTR访问

长度/bit88881616

长度/byte111122

存储范围0-2550-2550-2550-2550-655350-65535

如果在变量定义时省略了存储类型标识符,则编译器会自动选择默认的存储类型。默认的存储类型进一步由SMALL、COMPACT、和LARGE存储模式指令限制。

存储模式决定了变量的默认存储类型、参数传递区和无明确存储类型说明变量的存储类型。在SMALL模式下,参数传递是在片内数据存储区中完成的。

★ 单片机实验报告的心得体会

★ 实验报告

★ 实验报告 范文

★ 实验报告格式

★ 51短信

上一篇:5·12汶川大地震一周年感想下一篇:数据通信实验总结报告