目录
前言... 2
第一章 温度测量与单片机现状... 3
1.1温度控制系统的发展及现状... 3
1.2 单片机实现温控系统的现状... 3
1.3 温室大棚设计... 4
第二章 系统的硬件设计... 5
2.1 系统总体设计... 5
2.2 AT89C51单片机... 6
2.3 ADC转换芯片ADC0832. 7
2.4LED显示部分... 8
2.5 键盘部分... 9
2.6 传感器连接电路... 10
第三章 系统软件设计... 11
3.1软件总体设计... 11
3.2 AD转换程序设计... 12
3.3 键盘程序设计... 12
3.4 LED显示程序设计... 12
3.5 程序运行结果... 12
第四章 系统误差分析与处理... 14
4.1 电路部分... 14
4.2 软件部分... 15
第五章 小结... 15
参考文献:... 16
附录... 17
前言
在工业生产中,电流、电压、温度、压力、流量、流速和开关量都是常用的主要被控参数。其中,温度控制也越来越重要。在工业生产的很多领域中,人们都需要对各类加热炉、热处理炉、反应炉和锅炉中的温度进行检测和控制。采用单片机对温度进行控制不仅具有控制方便、简单和灵活性大等优点,而且可以大幅度提高被控温度的技术指标,从而大大的提高产品的质量和数量。因此,单片机对温度的控制问题是工业生产中经常会遇到的控制问题。
温度是工业生产中常见的工艺参数之一, 任何物理变化和化学反应过程都与温度密切相关, 因此温度控制是生产自动化的重要任务。 对于不同生产情况和工艺要求下的温度控制, 所采用的加热方式, 控制方式都不同。 随着单片机的飞速发展, 通过单片机对被控对象进行控制日益广泛, 具有体积小、功能强、性价比高等特点, 把单片机应用于温度控制系统中可以起到更好的控温作用, 电热恒温烘箱是使用单片机进行温度控制的典型应用, 采用单片机做主控单元, 无触点控制, 可完成对温度的采集和控制等的要求[1]。
我国北方冬季寒冷而漫长,大力推广蔬菜大棚种植蔬菜能够更好地满足人民生活水平日益提高的需要。冬季蔬菜大棚管理最重要的一个因素就是温度的控制。温度管理一般把一天分为午前、午后、前半夜和后半夜4 个时段来进行温度调节。午前以促进光合作用、增加同化量为主,一般应将棚温保持在25~30℃为宜;午后光合作用呈下降趋势,应将温度比午前降低5℃左右,以20 ~25℃为好,避免高温下养分消耗过多。日落后4~5h内,要将棚内温度从20℃逐渐降到15℃上下,以促进体内同化物的运转。此后,再将夜温降到10~12℃,以抑制呼吸、减少消耗、增加积累。但不可把温度降得过低,以免发生低温危害。另外,阴雨天光照不足,光合作用不能正常进行棚内温度也应比晴天低5℃左右,以降低呼吸消耗。单片机是一种集CPU、RAM、ROM、I/O接口和中断系统等部分于一体的器件,只需要外加电源和晶振就可实现对数字信息的处理和控制。因此,单片机广泛用于现代工业控制中。控制具有体积小、重量轻、价格低、可靠性高、耗电少和灵活机动等许多优点,因此如果能利用单片机进行温度的测量和控制,将会大大提高温度测量和控制的可靠性和灵活性。
第一章 温度测量与单片机现状1.1温度控制系统的发展及现状
温度控制广泛应用于社会生活的各个领域,如家电、汽车、材料、电力电子等。常用的控制方法、电路以及所使用的测量方式根据应用场合和所要求的性能指标有所不同。最近十年来,在温度控制方法上有了快速的发展。己从传统的直接控制转变成PID控制、模糊控制、神经网络控制和遗传算法等控制方法。
温度测量是工业、农业、国防和科研等部门最普遍的测量项目。它在工农业生产、现代科学研究及高新技术开发过程中也是一个极其普遍而重要的测量参数。
温度测量首先是由温度传感器来实现的。测温仪器通常由温度传感器和信号处理两部分组成。温度测量的过程就是通过温度传感器将被测对象的温度值转换成电的或其它形式的信号,传递给信号处理电路进行信号处理转换成温度值显示出来。温度传感器随着温度变化而引起变化的物理参数有:膨胀、电阻、电容、热电动势、磁性能、频率、光学特性及热噪声等等。随着生产的发展,新型温度传感器还会不断出现,目前,国内外通用的温度传感器及测温仪大致有以下几种:热膨胀式温度计,电阻温度计,热电偶,辐射式测温仪表。
热电阻是利用导体或半导体的电阻值随温度变化而变化的特性来测量温度的一种感温元件。使用热电阻作感温元件的温度计常称为电阻温度计。热电阻具有体积小、反应快、使用方便的优点,通过热电阻,可以把温度及其变化转换成电学量或电学量的变化加以测量。所以,它被广泛应用于工、农、医、交通、军事、科研等各个领域的温度测量和控制工作中。本次课程设计中就采用铂热电阻PT100传感器。
1.2 单片机实现温控系统的现状
单片机是一种集CPU、RAM、ROM、I/O接口和中断系统等部分于一体的器件,只需要外加电源和晶振就可实现对数字信息的处理和控制。因此,单片机广泛用于现代工业控制中。控制具有体积小、重量轻、价格低、可靠性高、耗电少和灵活机动等许多优点,因此如果能利用单片机进行温度的测量和控制,将会大大提高温度测量和控制的可靠性和灵活性。单片机对温度测量控制过程是借助于传感器、A/D转换器以及扩展接口和执行机构来进行的。在闭环型过程控制中,过程的实时参数由传感器和A/D转换器来实时采集,并由单片机自动记录、处理并控制执行机构动作来进行调节和控制。因此需要对单片机进行扩展和开发,来形成整个单片机温度控制系统。
通过单片机来控制加热的过程促进生产过程自动化。而生产过程自动化是保持生产稳定、降低消耗、改善劳动条件、保证生产安全和提高劳动生产率的重要手段。采用温度控制系统来控制温度对企业具有重要的意义:
1.降低劳动强度,改善劳动条件。采用单片机系统后,不再需要工人不停的对加热炉进行检查。
2.提高控制精度。单片机可以对温度进行实时的控制,降低温度加热的滞后性,以此提高加热的精度。
3.提高工作效率,降低成本,采用单片机系统控制可以更快的达到恒温控制的效果,提高工作效率、节省能源、降低成本。
4.提高企业对可控制电加热技术的应用水平,锻炼企业技术人员的开发、应用能力。
1.3 温室大棚设计
菜的生长发育受到温度的影响,因此对于蔬菜温室大棚来说,在蔬菜的整个生长过程中,要随时检测温度的变化,以便对温度进行控制,保证蔬菜所处的环境温度符合蔬菜生长发育的要求,提高蔬菜的产量和质量。大棚设计规格为40m*8m的规格,,以西红柿的生长环境为例。它对生长环境的要求十分严格,如果温度太高或太低、通风不及时、湿度过大都会引起农作物的病虫害,白天温度要求25℃~28℃,夜间温度要求13℃~15℃。由于大棚的范围较大一个温度传感器的测量数据可能不足以反映大棚内的实际情况。所以经过查阅资料,大棚的温度检测区域分成4块,每块规格为10m×8m,在大棚的四个区域安装4个温度传感器。传感器的高度在0.3m到0.4m,监测大棚内的温度。温度传感器采用铂热电阻PT100,其阻值会随着温度的变化而改变。PT后的100即表示它在0℃时阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。它的工业原理:当PT100在0摄氏度的时候他的阻值为100欧姆,它的的阻值会随着温度上升它的阻值是成匀速增涨的。Pt100 温度传感器还具有抗振动、稳定性好、准确度高、耐高压等优点。铂热电阻的线性较好,最大非线性偏差小。广泛应用与汽车空调、冰箱、冷柜、饮水机、咖啡机,烘干机以及中低温干燥箱、恒温箱,满足温室大棚的测量要求。大棚设计要求测量温度有零下30到60度的范围,由于考虑到我国广大地区温度差异较大,冬天与夏天温度差别也很大,有些地区冬天温度能达到零下30多度 ,和测量余量的考虑,所以设计传感器的测量范围为零下50度到80度。测量温度范围能覆盖我国广大地区的实际温度。
第二章 系统的硬件设计2.1 系统总体设计
系统采用了C51单片机作为处理器,具有四个温度测量模块,信号转换模块,数字显示模块,键盘控制模块。温度测量是由四个温度传感器完成,采用 铂热电阻PT100传感器,传感器接入三运放高共模抑制比放大电路。三运放高共模抑制比放大电路能有效的抑制电路的共模信号,提高整个系统的抗干扰能力。通过放大电路后接入AD转换芯片AD0832,AD0832是8为AD转换芯片,能将放大电路输入的模拟信号转化为数字信号,供给单片机处理。单片机每次会接收四个温度传感器测量的温度信号,对信号进行处理,根据测量温度和设定温度的比较输出不同的信号。8位数码管会对结果进行显示。单片机根据处理结果控制加热和制冷设备自动调节大棚内的温度。
图 2.1 系统整体框图
2.2 AT89C51单片机
89C51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。STC89C51是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、有效的解决方案。具有以下标准功能: 8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。
设计中选用STC 89C51单片机,共有四个8位的I/O口,P0口接入8为数码管的段选口,决定数码管显示的内容。P2口接入8位数码管的位选口,决定点亮哪一个数码管。P1口接入键盘电路,对整个系统进行控制和设定大棚内保持的温度。P3口主要接入AD转换芯片,接收传感器采集的温度数据。
图2.2单片机及接口
2.3 ADC转换芯片ADC0832
ADC0832是美国国家半导体公司生产的一种8位分辨率、双通道A/D转换芯片。由于它体积小,兼容性强,性价比高。ADC0832为8位分辨率A/D转换芯片,其最高分辨可达256级。可以适应一般的模拟量转换要求。在此次课程设计中由于温度控制系统在温室大棚内使用,对于温度控制精度要求不高。采用了数码管显示,由于单片机IO口数量有限,只显示到温度的个位,忽略小数位,所以8位ADC芯片能满足设计的精度要求。ADC0832内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。芯片转换时间仅为32μS,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。通过DI数据输入端,可以轻易的实现通道功能的选择。ADC0832芯片有两个通道,每个芯片可以接入两个温度传感器,通过单片机的程序控制可以分别对两个传感器进行AD转换,可以节约芯片成本。
图2.3 ADC0832芯片
2.4LED显示部分
LED数码管由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp来表示。当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的字样。LED数码管具有功耗小,无热量,耐冲击,长寿命等优点,配合控制器,即可实现流水,渐变,跳变,追逐等效果。在本次课程设计中由于需要显示的内容较多,所以采用8位数码管。每两个数码管一组,显示显示对应的温度值,设定的温度,报警及对加热制冷设备的控制状态。
图 2.4 8位数码管
第一和第二个数码管为一组,显示四个传感器测得温度的平均值。第三和第四个数码管为一组,用于显示设定的温度值及用键盘改变设定温度时的显示。第五和第六个数码管为一组,会轮流显示四个传感器测的的温度值及当传感器测得的温度异常时不会显示具体温度值,会显示“——”,进行报警。第七和第八个数码管为一组,显示对制冷和加热设备的控制状态。当显示1,2,3时表示对大棚进行加热,且测得温度与设定温度相差越大时,显示的值也越大。当显示“00”时表示设定温度与测得温度相同。当显示—1,—2,—3时表示对大棚进行制冷,设定温度与实际测得温度相差越大,显示数字也越大。
2.5 键盘部分
键盘部分当键盘按钮不按下去时对应的IO口输入为高电平,当按下按钮时IO口与地接通,对应接口输入为低电平。键盘部分有四个按钮,第一个按钮为开关按钮,按下第一个按钮后传感器和AD芯片及数码管开始工作,进行数模转
图2.5 键盘按钮
换,显示测定的温度。只有按下第一个按钮后按下其他的按钮才有效。第一次按下第二个按钮后,进入设定大棚温度的模式。每次按下第三个按钮,设定的温度值加一,每次按下第四个按钮时设定的温度减一。设定的温度值范围在0到50
循环。当第二次按下第二个按钮时,退出当前设定温度的模式,正常执行程序。
2.6 传感器连接电路
温度元件与单片机连接电路是一个三运放高共模抑制比放大电路。它具有很好的抗共模干扰的能力,提高温度测量的精度。
图2.6 三运放高共模抑制比放大电路
第三章 系统软件设计3.1软件总体设计
软件是单片机的关键。设计一个单片机系统,在硬件平台确定之后,就可以通过设计不同的软件,实现不同的单片机功能。在设计、实现单片机的软件系统时,需要考虑众多因素,如硬件需求、计算机硬件、操作系统等。由于选用专用的开发软件,必须具有一定的单片机以及数据采集设备配合使用。
控制系统加电后主控单片机启动,然后调用键盘扫描程序,判断有无按键按下。当检测到第一个按键按下后,再进行键盘扫描,若检测到第二个键按下则转入键盘控制程序部分。检测第三个和第四个按键是否按下,对设定温度的数值进行设置,当再次检测到第二个按键按下后退出键盘控制程序部分,转入数据处理和显示部分程序。若没有检测到第二个键按下,直接进入数据处理和显示部分。调用AD转换程序,获得传感器测量的数据,对测量数据进行处理。判断传感器测得数据是否异常,若有异常在进一步判断后显示“——”进行报警。若没有异常则显示最终的温度数据,并对每个传感器测得数据进行轮流显示。并将测得温度与设定温度进行比较,对加热和制冷设备进行控制。
开始
开关是否按下?
图 3.1 程序总体框图
3.2 AD转换程序设计
在本次课程设计中由于热电阻传感器输入信号为连续的电压量,是连续的模拟信号,需要进行AD转换变为数字量,单片机才能进行处理。所以需要AD转换芯片进行AD转换。在设计中有四个输入信号,由于采用了ADC0832芯片,每个芯片有两个输入通道,所以需要2个AD芯片。在程序设计中,按照芯片时序图对芯片写入命令,选择传感器对应的通道对输入信号进行AD转换。
3.3 键盘程序设计
在本次课程设计中,一共定义了四个按键。分别是开关,设定,加,减。分别接在P1.0到P1.3四个接口。当按下开关键后,单片机开始接收传感器采集的数据,进行处理和显示。设定和加减用于对大棚设定温度的控制。按下设定键后,在按下加,减对设定温度进行调整,再次按下设定键退出对温度的设定。
3.4 LED显示程序设计
由于程序中需要显示的数据量较多,所以采用了8位数码管进行显示。由于单片机的接口数量有限,采用动态显示模式。P0口接入数码管位选接口,P2口接入8位数码管的段选接口。P0口输入需要显示的数字,P2口决定点亮哪一个数码管。
3.5 程序运行结果
当单片机接电开始工作后,有键盘开关按钮来启动。由键盘设定按钮来蔬菜大棚所要达到的设定值。温度传感器时事测定当前温度,若当前温度小于设定值,则加热设备开始工作,直到当前温度达到设定值;若当前温度大于设定值,则加热炉停止工作,制冷设备开始工作。温度开始下降,直到当前温度等于设定值;设定值等于当前温度 ,通过对加热和制冷设备的控制保持大棚的温度稳定。
当实时温度小于设定值时,数码管显示为正数,此时加热炉作,从而提高大棚的温度:。数码管显示数字为1,2,3,数字越大加热功率越高。
图3.2 实际温度小于设定温度
当实时温度与设定值相等时,不采取任何措施:,数码管显示为—0。
图3.3 实际温度等于设定温度
当实时温度大于设定值时,加热装置停止工作,制冷装置开始工作。:温度差别越大,显示数字越小。
图 3.4 实际温度大于设定温度
第四章 系统误差分析与处理4.1 电路部分
由于在本次课程设计中传感器采用热电阻,采用三运放高共模抑制比放大电路抑制电路的共模干扰信号。三运放高共模抑制比放大电路是由三个集成运算放大器组成,其中左边两个运放输入阻抗,共模抑制比和增益等性能一致。构成平衡对称差动放大输入级,右边运放构成双端输入单端输出的输出级,用来进一步抑制电路的共模信号,并适应接地负载的需要。
图4.1 三运放高共模抑制比放大电路
当左边两个运放性能一致时,输入级的差动输出及其差模增益只与差模输入电压有关,而其共模输出,失调及漂移均在电路中抵消。因此电路具有良好的干扰抑制能力。
本次课程设计采用的温度元件是铂热电阻PT100,其阻值会随着温度的变化而改变。PT后的100即表示它在0℃时阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。厂家提供有PT100在各温度下电阻值值的分度表,在此可以近似取电阻变化率为 0.385Ω/℃。向PT100输入稳恒电流,再通过A/D转换后测PT100两端电压,即得到PT100的电阻值,进而算出当前的温度值。 采用50mA的电流源对PT100进行供电,然后用运算放大器LM324搭建的放大电路将其电压信号放大10倍后输入到ADC0832中。由于ADC0832是8位AD转换芯片,所以转换精度5/255=0.0196V。由于放大电路将输入电压放大10倍,所以 0.0196/10/0.05/0.385=0.1度。由于温度显示部分精度只要求到度,所以测量精度满足要求。
4.2 软件部分
在设计中采用了四个温度传感器,进行测量时会读取四个传感器的数据。每次测量后延时1秒,再次进行测量,一共进行四次测量。对每个传感器测量值去平均数,减小测量的误差。然后会对四个温度数据进行处理,若有两个及以上数据与设定温度值偏差太大会进行报警。若只有一个传感器测量温度异常,会在延时后在测量三次,若数据仍然异常,会进行报警。若数据没有异常,程序会对四个传感器测量值再次去平均值,减小误差,然后进行显示。
第五章 小结
通过此次课程设计,使我更加扎实的掌握了单片机,程序设计,传感器等方面的知识,知道了许多东西我们以前不知道知识。在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。实践出真知,通过亲自动手设计程序,使我们掌握的知识不再是纸上谈兵。在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。最终的检测调试环节,本身就是在践行过而能改,善莫大焉的知行观。这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在查找资料后,许多问题终于游逆而解,但也有的没有弄懂。在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
参考文献:
[1]胡汉才.单片机原理及其接口技术[M].北京:清华大学出版社,2004.
[2]张国雄.测控电路.机械工业出版社,2008.3
[3]许海峰.C51单片机项目式教程.—北京:清华大学出版社,2011.4
[4]张福学.传感器应用及其电路精选[M].北京:电子工业出版社,2003.
[5]臧春华.现代电子技术基础[M].北京:北京航空航天大学出版社,2005.
[6]单成祥.传感器的理论与设计基础及其应用[M].国际工业出版社,1999.
附录
程序:
#include<reg51.h> //头文件
#include<intrins.h> //_nop_()头文件
#define uchar unsigned char
#define uint unsigned int
uchar celiangzhi[4][4];
uchar shedingwendu = 25; ///设定温度
uchar jianpan = 0; ///判断键盘哪个键按下的变量
uchar sheding = 0; //设定温度的时的标志变量
uchar tem1, tem2, tem3, tem4; //存放传感器测定值的变量
uchar shuchuwendu; //存放传感器测定温度的平均值,最后用数码管显示
uchar shuchu; //bijiao()函数执行结果的标志
int k; //判断有几个传感器测定值异常的标志
//ADC0832端口引脚定义
sbit CS = P3 ^ 0; ////将CS位定义为P3.0引脚
sbit CLK = P3 ^ 1; //将CLK位定义为P3.1引脚
sbit DIO = P3 ^ 2; //将DIO位定义为P3.2引脚
sbit CS1 = P3 ^ 3;
sbit CLK1 = P3 ^ 4;
sbit DIO1 = P3 ^ 5;
uchar code led[11] = {0xc0,0xf9,0xa4,0xb0,0x99, // 共阳数码管段码表0到9和-
0x92,0x82,0xf8,0x80,0x90,0xbf };
void delay1ms() //延时函数
{
unsignedchar i, j;
for(i = 0; i<10; i++)
for(j = 0; j<33; j++);
}
void delaynms(unsigned char n) //延时n ms
{
unsignedchar i;
for(i = 0; i<n; i++)
delay1ms();
}
/////*****************************************************
unsigned char A_D() //进行AD转换的函数
{
unsignedchar i, dat;
uchara, b;
CS= 1; //一个转换周期开始 CS为片选使能口,0使能
CLK= 0; //为第一个脉冲作准备
CS= 0; //CS置0,片选有效
DIO= 1; //DIO置1,规定的起始信号
CLK= 1; //第一个脉冲
CLK= 0; //第一个脉冲的下降沿,此前DIO必须是高电平
//////////////////////////第一个脉冲结束
DIO= 1; //DIO置1, 通道选择信号
CLK= 1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
CLK= 0; //第二个脉冲下降沿
DIO= 0; //DI置0,选择通道0 DI0输入10时 选择0通道,输入11时选择1通道
CLK= 1; //第三个脉冲
CLK= 0; //第三个脉冲下降沿
DIO= 1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK= 1; //第四个脉冲
for(i = 0; i<8; i++) //高位在前
{
CLK= 1; //第四个脉冲
CLK= 0;
dat<<= 1; //将下面储存的低位数据向右移
dat|= (unsigned char)DIO; //将输出数据DIO通过或运算储存在dat最低位
}
CS= 1; //片选无效
a =dat / 51;
b =(dat % 51) * 10 / 51;
a =a * 10 + b;
returna;
}
/////************************************************
unsigned char A_D1()
{
unsignedchar i, dat;
uchara, b;
CS= 1; //一个转换周期开始 CS为片选使能口,0使能
CLK= 0; //为第一个脉冲作准备
CS= 0; //CS置0,片选有效
DIO= 1; //DIO置1,规定的起始信号
CLK= 1; //第一个脉冲
CLK= 0; //第一个脉冲的下降沿,此前DIO必须是高电平
//////////////////////////第一个脉冲结束
DIO= 1; //DIO置1, 通道选择信号
CLK= 1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
CLK= 0; //第二个脉冲下降沿
DIO= 1; //DI置0,选择通道0 DI0输入10时 选择0通道,输入11时选择1通道
CLK= 1; //第三个脉冲
CLK= 0; //第三个脉冲下降沿
DIO= 1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK= 1; //第四个脉冲
for(i = 0; i<8; i++) //高位在前
{
CLK= 1; //第四个脉冲
CLK= 0;
dat<<= 1; //将下面储存的低位数据向右移
dat|= (unsigned char)DIO; //将输出数据DIO通过或运算储存在dat最低位
}
CS= 1; //片选无效
a =dat / 51;
b =(dat % 51) * 10 / 51;
a =a * 10 + b;
returna;
}
unsigned char A_D2()
{
unsignedchar i, dat;
uchara, b;
CS1= 1; //一个转换周期开始 CS为片选使能口,0使能
CLK1= 0; //为第一个脉冲作准备
CS1= 0; //CS置0,片选有效
DIO1= 1; //DIO置1,规定的起始信号
CLK1= 1; //第一个脉冲
CLK1= 0; //第一个脉冲的下降沿,此前DIO必须是高电平
//////////////////////////第一个脉冲结束
DIO1=1; //DIO置1, 通道选择信号
CLK1= 1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
CLK1= 0; //第二个脉冲下降沿
DIO1= 0; //DI置0,选择通道0 DI0输入10时 选择0通道,输入11时选择1通道
CLK1= 1; //第三个脉冲
CLK1= 0; //第三个脉冲下降沿
DIO1= 1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK1= 1; //第四个脉冲
for(i = 0; i<8; i++) //高位在前
{
CLK1= 1; //第四个脉冲
CLK1= 0;
dat<<= 1; //将下面储存的低位数据向右移
dat|= (unsigned char)DIO1; //将输出数据DIO通过或运算储存在dat最低位
}
CS1= 1; //片选无效
a =dat / 51;
b =(dat % 51) * 10 / 51;
a =a * 10 + b;
returna;
}
/////************************************************
unsigned char A_D3()
{
unsignedchar i, dat;
uchara, b;
CS1= 1; //一个转换周期开始 CS为片选使能口,0使能
CLK1= 0; //为第一个脉冲作准备
CS1= 0; //CS置0,片选有效
DIO1= 1; //DIO置1,规定的起始信号
CLK1= 1; //第一个脉冲
CLK1= 0; //第一个脉冲的下降沿,此前DIO必须是高电平
//////////////////////////第一个脉冲结束
DIO1= 1; //DIO置1, 通道选择信号
CLK1= 1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
CLK1= 0; //第二个脉冲下降沿
DIO1= 1; //DI置0,选择通道0 DI0输入10时 选择0通道,输入11时选择1通道
CLK1= 1; //第三个脉冲
CLK1= 0; //第三个脉冲下降沿
DIO1= 1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK1= 1; //第四个脉冲
for(i = 0; i<8; i++) //高位在前
{
CLK1= 1; //第四个脉冲
CLK1= 0;
dat<<= 1; //将下面储存的低位数据向右移
dat|= (unsigned char)DIO1; //将输出数据DIO通过或运算储存在dat最低位
}
CS1= 1; //片选无效
a =dat / 51;
b =(dat % 51) * 10 / 51;
a =a * 10 + b;
returna;
}
void display1(uchar num, uchar dis_w) //数码管显示函数,第一二位数码管显示数字,显示最后的温度结果
{
ucharj;
for(j = 0; j < 2; j++)
{
P0= 0xff;
P2= dis_w;
if(j > 0)
P0= led[num / 10];
else
P0= led[num % 10];
dis_w= dis_w >> 1;
delaynms(5);
}
}
void display2(uchar num) // 数码管显示函数,第三四位数码管显示数字,显示设定的温度值
{
P0= 0xff;
delaynms(5);
P2= 0x04;
P0= led[num / 10];
delaynms(5);
P2= 0x08;
P0= led[num % 10];
delaynms(5);
}
void display6(uchar num) // 第五六位显示数字,用来显示四个传感器测定的温度
{
P0= 0xff;
delaynms(5);
P2= 0x10;
P0= led[num / 10];
delaynms(5);
P2= 0x20;
P0= led[num % 10];
delaynms(5);
}
void display3() // 第五六位显示数字,当传感器测定的温度异常时报警
{
P0= 0xff;
delaynms(5);
P2= 0x10;
P0= led[10];
delaynms(5);
P2= 0x20;
P0= led[10];
delaynms(5);
}
void display4(uchar i) // 第七八位显示数字,用来显示处理结果,显示1 2 3
{
P0= 0xff;
delaynms(5);
P2= 0x40;
P0= led[0];
delaynms(5);
P2= 0x80;
P0= led;
delaynms(5);
}
void display5(uchar i) // 第七八位显示数字,用来显示处理结果,显示-1 -2 -3 0
{
P0= 0xff;
delaynms(5);
P2= 0x40;
P0= led[10];
delaynms(5);
P2= 0x80;
i =i - 4;
P0= led;
delaynms(5);
}
/////////////////////////////////////////////////
void celiang() //调用AD()函数,用四个传感器测量温度。每个传感器隔一段时间进行一次测量
{ //每个传感器测试四次,对测量结果取平均值,存放在四个变量中
inti = 0; //
intj = 0;
for(i = 0; i < 4; i++)
{
celiangzhi[j][0]= A_D(); celiangzhi[j][1] = A_D1();
celiangzhi[j][2]= A_D2(); celiangzhi[j][3] = A_D3();
j++;
}
tem1= celiangzhi[0][0] + celiangzhi[1][0] + celiangzhi[2][0] + celiangzhi[3][0];
tem1= tem1 / 4;
tem2= celiangzhi[0][1] + celiangzhi[1][1] + celiangzhi[2][1] + celiangzhi[3][1];
tem2= tem2 / 4;
tem3= celiangzhi[0][2] + celiangzhi[1][2] + celiangzhi[2][2] + celiangzhi[3][2];
tem3= tem3 / 4;
tem4= celiangzhi[0][3] + celiangzhi[1][3] + celiangzhi[2][3] + celiangzhi[3][3];
tem4= tem4 / 4;
}
void kongzhi() //将最终的温度结果与设定的温度进行比较,根据比较结果输出不同的值
{
inti;
i =shuchuwendu - shedingwendu;
if(i < -5)
shuchu= 3;
if((-5 < i)&(i < -2))
shuchu= 2;
if((-2 < i)&(i < 0))
shuchu= 1;
if(i >5)
shuchu= 7;
if((2 < i)&(i < 5))
shuchu= 6;
if((0 < i)&(i < 2))
shuchu= 5;
if(i == 0)
shuchu= 4;
}
int bijiao() //判断每个传感器的测量结果有没有超过合理的范围
{
ucharxiaxian, shangxian;
inti = 0, j = 0;
ucharbijiao[4];
xiaxian= (shedingwendu - 15);
shangxian= (shedingwendu + 15);
bijiao[0]= tem1; bijiao[1] = tem2; bijiao[2] = tem3;
bijiao[3]= tem4;
for(i = 0; i < 4; i++)
{
if(xiaxian < bijiao && bijiao < shangxian)
{
k++;
}
}
returnk;
}
void keyscan() //键盘扫描函数,判断哪个键按下
{
if((P1 & 0x0f) == 0x0f)
jianpan= 0;
if((P1 & 0x0f) == 0x0e)
jianpan= 1;
if((P1 & 0x0f) == 0x0d)
jianpan= 2;
if((P1 & 0x0f) == 0x0b)
jianpan= 3;
if((P1 & 0x0f) == 0x07)
jianpan= 4;
// return jianpan;
}
main(void)
{
int i;
ucharkaiguan = 0;
// ucharceshi = 12;
while(1)
{
keyscan();
if(jianpan == 1)
kaiguan= 1;
while(kaiguan == 1)
{
keyscan();
if(jianpan == 2)
{
sheding= 1;
while(jianpan == 2)
{
keyscan();
}
while(jianpan == 0)
{
keyscan();
display2(shedingwendu);
}
}
while(sheding == 1)
{
keyscan();
if(jianpan == 3)
{
shedingwendu= shedingwendu + 1;
if(shedingwendu > 50)
{
shedingwendu= 1;
}
while(jianpan == 3)
{
keyscan();
}
while(jianpan == 0)
{
keyscan();
display2(shedingwendu);
}
}
if(jianpan == 4)
{
shedingwendu= shedingwendu - 1;
if(shedingwendu <1)
{
shedingwendu= 50;
}
while(jianpan == 4)
{
keyscan();
}
while(jianpan == 0)
{
keyscan();
display2(shedingwendu);
}
}
keyscan();
if(jianpan == 2)
sheding= 0;
while(jianpan == 2)
{
keyscan();
}
}
celiang();
bijiao();
////////////////// 显示四个传感器的测量值
for(i = 0; i < 20; i++)
{
delay1ms();
display6(tem1);
}
for(i = 0; i < 20; i++)
{
delay1ms();
display6(tem2);
}
for(i = 0; i < 20; i++)
{
delay1ms();
display6(tem3);
}
for(i = 0; i < 20; i++)
{
delay1ms();
display6(tem4);
}
///////////////////////////////////////////////////////////////////
if(k < 2)
{
display3();
for(i = 0; i < 20; i++)
{
delay1ms();
display3();
}
///////////////////
}
if(k == 3)
{
inti = 0;
intj = 0;
k= 0;
for(i = 0; i < 3; i++)
{
///////////////////////////////
delaynms(500);
//////////////////////////////////////
celiang();
bijiao();////////////////
if(k == 3)
{
j++;
k= 0;
}
}
if(j == 3)
{
for(i = 0; i < 20; i++)
{
delay1ms();
display3();
}
////////////////////////////////////////
}
}
if(k == 4)
{
////////////////////////////////////////////////////
shuchuwendu= tem1 + tem2 + tem3 + tem4;
shuchuwendu= shuchuwendu / 4;
for(i = 0; i < 50; i++)
{
delay1ms();
display1(shuchuwendu,0x02);
}
kongzhi();
if(shuchu < 4)
{
for(i = 0; i < 50; i++)
{
delay1ms();
display4(shuchu);
}
}
else
{
for (i = 0; i < 50; i++)
{
delay1ms();
display5(shuchu);
}
}
}
for(i = 0; i < 20; i++)
{
delay1ms();
display2(shedingwendu);
}
display2(shedingwendu);
k= 0;
}
}
}
|