




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
科信学院单片机应用系统(三级)项目设计说明书(2012/2013学年第二学期)题 目 : 基于热敏电阻的数字温度计 _专业班级 : 电子信息工程1021 设计周数 : 两周 设计成绩 : 2013年6月28日基于热敏电阻的数字温度计目录1实验设计目的22系统软件设计22.1软件总体流程设计22.2系统设计及主要程序32.2.1系统主函数32.2.2汉显lcd1286442.2.3时钟芯片ds130262.2.4adc0832112.3上位机设计及主要代码142.3.1serialport 组件142.3.2串口操作152.3.3数据的接收152.3.4保存数据与清空数据173系统硬件电路设计173.1恒温桥电路173.2信号放大电路183.3a/d转换电路183.4控制电路193.5显示电路204总结与展望20参考文献211实验设计目的 随着以知识经济为特征的信息化时代的到来人们对仪器仪表的认识更加深入,温度作为一个重要的物理量,是工业生产过程中最普遍,最重要的工艺参数之一。随着工业的不断发展,对温度的测量的要求也越来越高,而且测量的范围也越来越广,对温度的检测技术的要求也越来越高,因此,温度测量及其测量技术的研究也是一个很重要的课题。本系统的温度测量采用的就是热阻效应。温度测量模块主要为温度测量电桥,当温度发生变化时,电桥失去平衡,从而在电桥输出端有电压输出,但该电压很小。将输出的微弱电压信号通过op07放大,将放大后的信号输入ad转换芯片,进行a/d转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来。单片机显示模块电 源 模 块测温模块信号放大模块ad转换模块图1-1系统框图2系统软件设计2.1软件总体流程设计软件设计采用c语言编程,运用模块化程序设计思想,对不同功能模块的程序进行分别编程,以便移植或调用,这样使软件层次结构清晰,有利于软件的调试修改。数字温度计系统软件部分采用模块化设计思想,将系统分为主程序、初始化处理模块、中断检测模块、延时处理模块、数据处理模块、显示模块,其软件系统的主程序实现流程如下图所示: 开 始ds1302时钟信息采集数据处理12864显示结 束系统初始化pt100温度采集图2-1系统软件流程2.2系统设计及主要程序2.2.1系统主函数程序的入口,分别调用了其他头文件,实现了lcd12864汉显的显示,ds1302时钟芯片时间的运行,adc0832模数转换。主要代码实现如下:#include reg52.h#include intrins.h#include lcd12864.h#include ds1302.h#include adc0832.h#define uchar unsigned char#define uint unsigned intvoid main( void )com_init();v_lcd12864init_f() ;v_lcd12864putstring_f( 1,0, 年) ;v_lcd12864putstring_f( 3,0, 月) ;v_lcd12864putstring_f( 5,0, 日) ;v_lcd12864putstring_f( 1,1, 时) ;v_lcd12864putstring_f( 3,1, 分) ;v_lcd12864putstring_f( 5,1, 秒) ;v_lcd12864putstring_f( 5,2, );while(1)run_ds1302();displayadc ();send(); _nop_; 2.2.2汉显lcd12864 主要实现汉显lcd12864接收时钟芯片ds1302与a/d转换模块传递来的温度与时间,并显示在液晶屏上。主要代码实现如下:#includelcd12864.h#include intrins.h #define uchar unsigned char#define uint unsigned intvoid v_lcd12864checkbusy_f( void ) /忙检测函数 unsigned int ntimeout = 0 ; set_inc set_read clr_en set_en while( ( io_lcd12864_dataport & 0x80 ) & ( +ntimeout != 0 ) ) ; clr_en set_inc set_readvoid v_lcd12864sendcmd_f( unsigned char bycmd ) /发送命令 v_lcd12864checkbusy_f() ; set_inc set_write clr_en io_lcd12864_dataport = bycmd ; _nop_(); _nop_(); set_en _nop_(); _nop_(); clr_en set_read set_incvoid v_lcd12864senddata_f( unsigned char bydata ) /发送数据 v_lcd12864checkbusy_f() ; set_data set_write clr_en io_lcd12864_dataport = bydata ; _nop_(); _nop_(); set_en _nop_(); _nop_(); clr_en set_read set_incvoid v_delayms_f( unsigned int ndelay ) /延时 unsigned int i ; for( ; ndelay 0 ; ndelay- ) for( i = 125 ; i 0 ; i- ) ; void v_lcd12864init_f( void ) /初始化 v_lcd12864sendcmd_f( 0x30 ) ; /基本指令集 v_delayms_f( 50 ) ; v_lcd12864sendcmd_f( 0x01 ) ; /清屏 v_delayms_f( 50 ) ; v_lcd12864sendcmd_f( 0x06 ) ; /光标右移 v_delayms_f( 50 ) ; v_lcd12864sendcmd_f( 0x0c ) ; /开显示void v_lcd12864setaddress_f( unsigned char x, y ) /地址转换 unsigned char byaddress ; switch( y ) case 0 : byaddress = 0x80 + x ; break; case 1 : byaddress = 0x90 + x ; break ; case 2 : byaddress = 0x88 + x ; break ; case 3 : byaddress = 0x98 + x ; break ; default : break ; v_lcd12864sendcmd_f( byaddress ) ;void v_lcd12864putstring_f( uchar x, uchar y, uchar *pdata ) v_lcd12864setaddress_f( x, y ) ; while( *pdata != 0 ) v_lcd12864senddata_f( *pdata+ ) ; 2.2.3时钟芯片ds1302 主要为汉显12864提供时间输出。主要代码实现如下:#includeds1302.h#includeintrins.h#includelcd12864.h#define uchar unsigned char#define uint unsigned intvoid v_rtinputbyte(uchar ucda)/ 功能 : 往ds1302写入1byte数据uchar i;acc = ucda;t_rst = 1;for(i=8; i0; i-)t_io = acc0;t_clk = 1;t_clk = 0;acc = acc 1;uchar uc_rtoutputbyte(void)/从ds1302读取1byte数据 uchar i;t_rst = 1;for(i=8; i0; i-)acc = acc 1;t_io=1;acc7 = t_io;t_clk = 1;t_clk = 0;return(acc);void v_w1302(uchar ucaddr, uchar ucda) /往ds1302写入数据 ucaddr: ds1302地址, ucda: 要写的数据t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(ucaddr); / 写地址 _nop_();_nop_();v_rtinputbyte(ucda); / 写1byte数据t_clk = 1;t_rst = 0;uchar uc_r1302(uchar ucaddr) /读取ds1302某地址的数据 ucaddr: ds1302地址uchar ucda;t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(ucaddr); /写地址,命令_nop_();_nop_();ucda = uc_rtoutputbyte(); /读1byte数据t_clk = 1;t_rst = 0;return(ucda); /ucda :读取的数据void v_burstw1302t(uchar *psecda) /往ds1302写入时钟数据uchar i;v_w1302(0x8e, 0x00); /控制命令,wp=0,写操作t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(0xbe); /0xbe:时钟多字节写命令for(i=8; i0; i-) /8byte = 7byte 时钟数据 + 1byte 控制v_rtinputbyte(*psecda); /写1byte数据psecda+;t_clk = 1;t_rst = 0;void v_burstr1302t(uchar *psecda) /读取ds1302时钟数据uchar i;t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(0xbf); /0xbf:时钟多字节读命令for(i=8; i0; i-)*psecda = uc_rtoutputbyte(); /读1byte数据psecda+;t_clk = 1;t_rst = 0;void v_burstw1302r(uchar *preda) /往ds1302寄存器数写入数据 preda: 寄存器数据地址uchar i;v_w1302(0x8e,0x00); /控制命令,wp=0,写操作t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(0xfe); /0xbe:时钟多字节写命令for(i=31; i0; i-) /31byte 寄存器数据v_rtinputbyte(*preda); /写1byte数据preda+;t_clk = 1;t_rst = 0;void v_burstr1302r(uchar *preda) /读取ds1302寄存器数据 preda: 寄存器数据地址uchar i;t_rst = 0;t_clk = 0;t_rst = 1;v_rtinputbyte(0xff); /0xbf:时钟多字节读命令for(i=31; i0; i-) /31byte 寄存器数据*preda = uc_rtoutputbyte(); /读1byte数据preda+;t_clk = 1;t_rst = 0;/* 输入 : psecda: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年* 7byte (bcd码) 1b 1b 1b 1b 1b 1b 1b*/void v_set1302(uchar *psecda) /设置初始时间 uchar i;uchar ucaddr = 0x80;v_w1302(0x8e, 0x00); /控制命令,wp=0,写操作for(i=7; i0; i-)v_w1302(ucaddr, *psecda); / 秒 分 时 日 月 星期 年psecda+;ucaddr += 2;v_w1302(0x8e, 0x80); /控制命令,wp=1,写保护void v_get1302(uchar uccurtime)/读取ds1302当前时间 uccurtime: 保存当前时间地址。 bcd码uchar i;uchar ucaddr = 0x81;for(i=0; i= 10) dec -= 10; bcd+; bcd 1;data1 += bcd 3; /用位移代替乘法运算return data1;void write_ds1302init(void) /写入数据 初始化v_w1302(0x8e,0);v_w1302(0x80,0x50);/写入秒v_w1302(0x8e,0);v_w1302(0x82,0x59);/写入分v_w1302(0x8e,0);v_w1302(0x84,0x07);/写入小时v_w1302(0x8e,0);v_w1302(0x86,0x08);/写入日v_w1302(0x8e,0);v_w1302(0x88,0x06);/写入月v_w1302(0x8e,0);v_w1302(0x8a,0x05);/写入星期v_w1302(0x8e,0);v_w1302(0x8c,0x13);/写入年void run_ds1302()uchar sec, min, hour, day, month, year , week;v_w1302(0x8f, 0);sec = bcdtodec(uc_r1302(0x81); /读出ds1302中的秒v_w1302(0x8f, 0);min = bcdtodec(uc_r1302(0x83); /读出ds1302中的分v_w1302(0x8f, 0);hour = bcdtodec(uc_r1302(0x85); /读出ds1302中的小时v_w1302(0x8f, 0);day = bcdtodec(uc_r1302(0x87); /读出ds1302中的日v_w1302(0x8f, 0);month = bcdtodec(uc_r1302(0x89); /读出ds1302中的月v_w1302(0x8f, 0);year = bcdtodec(uc_r1302(0x8d); /读出ds1302中的年v_w1302(0x8f,0);week = bcdtodec(uc_r1302(0x8b); /读出 星期v_lcd12864setaddress_f(0,0) ;v_lcd12864senddata_f( year /10 % 10 + 48 ) ;v_lcd12864senddata_f( year% 10 + 48 ) ;v_lcd12864setaddress_f(2,0) ;v_lcd12864senddata_f( month / 10 % 10 + 48 ) ;v_lcd12864senddata_f( month % 10 + 48 ) ;v_lcd12864setaddress_f(4,0) ;v_lcd12864senddata_f( day / 10 % 10 + 48 ) ;v_lcd12864senddata_f( day % 10 + 48 ) ;v_lcd12864setaddress_f(6,0);v_lcd12864senddata_f( week + 48);v_lcd12864setaddress_f(0,1) ;v_lcd12864senddata_f( hour /10 % 10 + 48 ) ;v_lcd12864senddata_f( hour % 10 + 48 ) ;v_lcd12864setaddress_f(2,1) ;v_lcd12864senddata_f( min /10 % 10 + 48 ) ;v_lcd12864senddata_f( min % 10 + 48 ) ;v_lcd12864setaddress_f(4,1) ;v_lcd12864senddata_f( sec /10 % 10 + 48 ) ;v_lcd12864senddata_f( sec % 10 + 48 ) ; 2.2.4adc0832 本系统最重要的模块,是实现本项目数字温度计系统基本功能的核心模块,在本模块中传递出0255共256个数字,然后通过分段计算得出温度。本模块代码中还加入了串口通信,串口初始化为方式二,9600比特率。主要代码实现如下:#include adc0832.h#include intrins.h#includelcd12864.h#define uchar unsigned char#define uint unsigned int uchar l_temp; unsigned char lcdbuf110=;uchar adc0832_read(uchar ch)uchar i;uchar adc_buff=0;adc0832_cs = 1;adc0832_dio = 1; /启动位adc0832_clk = 0;adc0832_cs = 0;_nop_();adc0832_clk = 1; _nop_();adc0832_clk = 0;adc0832_dio = 1; /送 sgl/dif 位 _nop_();adc0832_clk = 1;_nop_();adc0832_clk = 0;if(ch=0) adc0832_dio = 0; /送转换通道值else adc0832_dio = 1;adc0832_clk = 1;_nop_();adc0832_clk = 0;_nop_(); adc0832_dio = 1; /释放dio端口,转由adc控制for(i=0;i8;i+)_nop_();adc0832_clk = 0;_nop_();adc0832_clk = 1;_nop_();if(adc0832_dio=1) adc_buff=adc_buff+1; /读取8位数据adc_buff=adc_buff= 0) for(i=6;temp0;i-) lcdbuf1i=temp%10+48; temp/=10; if(temp 0;i-) lcdbuf1i=w%10+48; w/=10; if(i=0&temp -10) lcdbuf1i = 0; i-; lcdbuf1i = -; i-; for(;i=0;i-) lcdbuf1i= ; for(i=0;i5;i+) lcdbuf1i=lcdbuf1i+1; if(lcdbuf14= )lcdbuf14=0; lcdbuf15=.; v_lcd12864putstring_f( 0,2,lcdbuf1 );void com_init(void) /串口初始化 tmod = 0x20; pcon = 0x00; scon = 0x50; th1 = 0xfd; /波特率9600=11.0592*1000000/12/(0x100-0xfd)/32 tl1 = 0xfd; tr1 = 1;void send_char_com( unsigned char ch) /发送一个字符 sbuf=ch; while (ti= 0 ); ti= 0 ; void send_string_com( unsigned char *str, unsigned int strlen) /向串口发送一个字符串,strlen为该字符串长度 unsigned int k= 0 ; do send_char_com(*(str + k); k+; while (k strlen); void send()send_string_com(lcdbuf1, 10);2.3上位机设计及主要代码上位机即简易的串口小助手,主要用于对串口的管理及对下位机数据的接收。本程序有c#编写,方便简洁。2.3.1serialport 组件在 visual studio 2008 开发工具中,可以不再采 用第三方控件的方法来设计串口通讯程序。net framework 2.0 类库包含了 serialport 类,方便地实现了所需要串口通讯的多种功能,可以实现mscomm 编程方法快速转换到以 serialport 类为核心的串口通讯。本上位机选用固定串口com1,波特率为9600,器件属性如图2-2所示:图2-2设置串口属性2.3.2串口操作在程序中添加一个打开串口按钮btnopen,btnopen.text 初始化为“打开串口”。在btnopen 响应函数中加入以下代码:private void btnopen_click(object sender, eventargs e) if (btnopen.text = 打开串口) btnopen.text = 关闭串口; serialport1.open(); else btnopen.text = 打开串口; serialport1.close(); 设置窗体响应事件,代码如下: private void form1_load(object sender, eventargs e) btnopen.text = 打开串口; 这时该程序已经具有开关串口的作用,可以用单片机虚拟串口互连方法方法进行串口测试。2.3.3数据的接收数据接收大体有两种方案:1、主动定时读取;2、事件响应驱动。事件响应驱动这种方式是串口通信上位机制作的主要方式,其采用中断思想而成,当串口输入缓冲区中的字节数据大于某个设定的个数时,触发串口输入中断,这时在中断程序中读取串口输入缓冲区中的数据,具有实时性和灵活性,是个常用的较好的方法。本程序也是采用这种方法来进行串口输入缓冲区的实时数据读取。 .net 中封装了serialport 类表示串行端口资源。 命名空间: system.io.ports 程序集: system(在system.dll 中) 除了前面用到的串口常规属性设置(buadrate,portname),这里用到了一个新的串口属性:receivedbytesthreshol 获取或设置datareceived 事件发生前内部输入缓冲区中的字节数。这个receivebytesthreshold 属性即是设置串口输入缓冲区中的数据字节大于receivebytesthreshold 时触发datareceived 事件。主要代码如下:string serialreadstring; private void serialport1_datareceived(object sender, serialdatareceivedeventargs e) serialreadstring = serialport1.readexisting(); this.rtb_receive.invoke ( new methodinvoker ( delegate this.rtb_receive.appendtext(serialreadstring); ) ); 此时接收功能已经实现,如图2-3所示:图2-3上位机接收数据 2.3.4保存数据与清空数据本模块仅为完善上位机功能,程序简单,主要代码实现如下:private void btnsave_click(object sender, eventargs e) try system.io.filestream objfile; savefiledialog1.showdialog(); objfile = system.io.file.create(savefiledialog1.filename); objfile.close(); objfile.dispose(); system.io.streamwriter objfil = new system.io.streamwriter(savefiledialog1.filename); objfil.write(rtb_receive.text); objfil.close(); objfil.dispose(); catch messagebox.show(数据未保存!); private void btnclear_click(object sender, eventargs e) rtb_receive.clear(); 3系统硬件电路设计系统由五大部分组成:(1)测温电桥温量电路;(2)数据采集,滤波,放大,ad转换电路;(3)单片机at89c51控制及数据计算电路;(4)电源电路;(5)温度实时显示电路。3.1恒温桥电路本次课程设计的测温电路为测温电桥,测温电桥的主要部分是热敏电阻。本次设计采用的是正温度系数的热电阻pt100,它是最常用的温度传感器之一,它具有较好的长期稳定性,利用适当的数据处理设备就可以传输、显示并记录其温度输出。因为热敏电阻的阻值和温度呈正比关系,我们只需将已知电流流过该电阻就可以得到与温度成正比的输出电压。pt100是电阻式温度传感器,测温的本质其实是测量传感器的电阻,通常是将电阻的变化转换成电压或电流等模拟信号,然后再将模拟信号转换成数字信号,再由处理器换算出相应温度。测温电路原理图如图3-1所示:图3-1测温电路原理图电桥原理图如图3-2所示:图3-2电桥原理图3.2信号放大电路本次课程设计,放大模块采用的是lm324放大集成电路。lm324是四运放集成电路,它采用14脚双列直插塑料封装,外形如图所示。它的内部包含四组形式完全相同的运算放大器,除电源共用外,四组运放相互独立。3.3a/d转换电路此次课程设计的a/d转换电路,负责将放大后的模拟电压信号转化为可供单片机识别的数字信号。此次课程设计选用adc0832芯片。adc0832为8位分辨率a/d转换芯片,其最高分辨可达256级,可以适应一般的模拟量转换要求。其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在05v之间。芯片转换时间仅为32s,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。通过di数据输入端,可以轻易的实现通道功能的选择。正常情况下adc0832与单片机的接口应为4条数据线,分别是cs、clk、do、di。但由于do端与di端在通信时并未同时有效并与单片机的接口是双向的,所以电路设计时可以将do和di并联在一根数据线上使用。电路原理图如图3-3所示: 图3-3a/d转换电路由于adc0832是8位分辨率,返回的数值在0255之间,对应模拟数值为05v,因此每一档对应的电压值约为0.0196v。3.4控制电路at89c51单片机最小系统由
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年企业物资供应与管理模拟题集及解析
- 电力基本知识培训课件
- 2025年信息技术在物资储备仓库的应用及面试模拟题解析
- 2025年软件编程实战题集及解析指南
- 2025年软件测试工程师实战技能提升教程
- 2025年初级美容师笔试模拟题及答题技巧解析
- 2025年初中地理教学设计与模拟题集解析
- 电信安全知识培训资料课件
- 2025年税务局招聘考试模拟试题及答案解析手册
- 电井安全知识培训内容课件
- 枢纽经济:区域经济发展新动能
- 积极心理学全套课件
- 临床实验中不良事件的管理
- 如何开展课题研究
- 炼钢厂电工应知应会考试题库500题(含各题型)
- bc-6800产品中心医院
- GB/T 5069-2007镁铝系耐火材料化学分析方法
- GB/T 40565.2-2021液压传动连接快换接头第2部分:20 MPa~31.5 MPa平面型
- GB/T 11446.10-1997电子级水中细菌总数的滤膜培养测试方法
- 旅游区奖惩制度管理办法
- 儿童生长发育监测课件
评论
0/150
提交评论