资源描述
课程名称:综合课程设计
设计题目: 温度检测仪
院 系:
专 业:
年 级:
姓 名:
指导教师:
西南交通大学
2010 年 9月 28 日
课 程 设 计 任 务 书
专 业 姓 名 学 号
开题日期: 完成日期:
题 目 温度监测仪 (热敏电阻)
一、设计的目的
针对热敏电阻设计温度监测仪。通过本次我们自己动手设计制作温度监测仪,增强我们的实际操作动手能力,将我们所学的知识运用到实际的设计中,同时增强我们的创新能力,为我们以后的学习和工作打下基础。
二、设计的内容及要求
主要内容:
1、温度监测方案的总体设计,实现温度的LCD实时显示;
2、完成温度监测仪的传感器选择以及构建测试电路,验证可行性;
3、列元件清单,并购置,;完成实物制作,并答辩验收;
要求:
1、设计以实物和答辩形式提交;
2、小组需定期向指导老师汇报设计进度等情况。
任务分工:
曾云洪:负责电路设计以及PCB电路板的设计;
钱再兴:负责程序设计及调试;
刘高恒:负责测试方案的确定;
吴慧、韩亚红:LCD显示程序的设计。
三、指导教师评语
四、成 绩
指导教师 (签章)
年 月 日
心得体会
在本次课程设计中我和韩亚红同学都是主要负责LCD显示程序的设计。在前期准备工作中,我主要任务是资料的收集和筛选。前期准备活动最主要的任务就是确定我们测温的主要原理,只有确定了合适的原理,这样才能陆续完成后面的工作。在刚开始的时候我们预选好了两个原理方法:频率转换法和电阻分压法。这两种方法都有各自的优缺点,频率法具有测量精度高、测量距离远、电路简单的优点,而它的缺点是计算较为复杂:电压法具有原理和电路简单,容易得到测量温度的优点,
缺点是精度不高,适用于精度要求不高的测量。虽然频率法在各方面看都由于电压法,但是受我们自身的能力和实验的条件所限,我们最后还是选择的电压法来实现热敏电阻测温。电压法是利用串联电阻分压原理,在热敏电阻一端串联一个适当阻值的电阻,然后测量热敏电阻的电压值,测得的电压值经AD转换和数学计算得到了温度值,原理图如附图所示。
在这次的课程设计实践中,我学到了许多以前不知道的东西。从题目的确定到元件的选用、电路的设计再到后来的编程实现全部要考我们自己来完成。在大学四年中我们纵然学了很多理论知识,但是要想成功地完成本次任务,这就要求我们要将以前所学的东西融会贯通,链接在一起才能顺利地完成任务。
通过本次课程设计,我发现了自身存在的许多不足之处。例如说,编写显示程序对于我来说是在是一份很大的挑战,我花了许多时间去攻克它,但是最后还是会有漏洞,从而程序不能实现。当然,我也在网上试着找是否有相似的程序,看能否修改一下就直接运行,结果这种捷径很快被同组的同学否定,这时我们请教了其他优秀的同学协助我们编写程序。最终在大家共同的努力之下,我们完成了本次课程设计。
由于能力所限,我们利用热敏电阻测温完成的温度检测仪做的十分简单,只有最基本的功能,但是我们的基本参数和测温条件精度都达到了预定指标。
附图一:
流程图:
原理图:
参数确定
考虑到AD转换的灵敏度,选取
参考电阻的阻值为10K
热敏电阻参数
B=3950,Ro=10K
成品图:
附二:程序清单
#include<STC12C54.H>
#include<stdio.h>
#include<ctype.h>
#include<intrins.h>
#include<math.h>
#include<1602.h>//LCD显示头文件
#define Channel 0 //选择AD通道0~8;对应P1.0(ADC0)~P1.7(ADC7)
#define R_Buf_Len 32 //设置接收缓冲器长度
#define T_Buf_Len 16 //设置发送缓冲器长度
unsigned char data R_Buf[R_Buf_Len]; //环形接收数据缓冲区
unsigned char data T_Buf[T_Buf_Len]; //环形发送数据缓冲区
unsigned char data R_I_Ptr,R_O_Ptr; //环形接收缓冲区输入、输出指针
unsigned char data T_I_Ptr,T_O_Ptr;//环形发送缓冲区输出、输出指针
void Delay_ms(unsigned int Time_ms);
unsigned char serial_in(void);
void serial_out(unsigned char T_Data);
void string_out_LF_CR(unsigned char *strings_point);
unsigned char bdata Flag; //位变量定义
sbit R_End=Flag^0; //接收标志位
sbit T_End=Flag^1; //发送标志位
//************************************************* // 时延函数
void Delay_ms(unsigned int Time_ms)
{
unsigned int a,b;
for(a=Time_ms;a>0;a--)
for(b=850;b>0;b--);
}
//*************************************************// 串口发送
void serial_out(unsigned char T_Data)
{
while(((T_I_Ptr+1)%T_Buf_Len)==T_O_Ptr);
if(T_End==1) //T_End=1,可以发送下一个数据
{
SBUF=T_Data;
T_I_Ptr=(T_I_Ptr+1)%T_Buf_Len;
T_End=0;
}
else
{
T_Buf[T_I_Ptr]=T_Data;
T_I_Ptr=(T_I_Ptr+1)%T_Buf_Len;
}
}
//************************// 将指针指向的字符串从串行口输出
void string_out_LF_CR(unsigned char *strings_point)
{
while (1)
{
if (*strings_point!=0x00)
{
serial_out(*strings_point);
strings_point++;
}
else
{
break;
}
}
}
/*************************************************// 串行口中断
void serial_int(void) interrupt 4 using 1
{
if(_testbit_(TI)) //发送中断
{
T_O_Ptr=(T_O_Ptr+1)%T_Buf_Len;
if(T_I_Ptr==T_O_Ptr) //发送缓冲区中没有数据
{
T_End=1; //置串行口发送完成标志
}
else
{ //发送缓冲区中有数据
SBUF=T_Buf[T_O_Ptr]; //发送缓冲区中的数据
T_End=0; //清串行口发送完成标志
}
}
}
//********************************************// 串口初始化
void Intil_Serial(void)
{
AUXR&=0x1f;
TMOD=0X20;
SCON=0x50;
TH1=TL1=0xfd;
TR1=1;
EA=1; //开放中断
ES=1; //
T_End=1; //置发送完成标志
R_End=0; //清接收数据标志
R_I_Ptr=0; //接收缓冲区输入、输出指针
R_O_Ptr=R_I_Ptr; //
T_I_Ptr=0; //发送缓冲区输入、输出指针
T_I_Ptr=T_O_Ptr; //
}
//*********************************************//ASCII转换函数
unsigned char hex_to_ascii(unsigned char hex_data)
{
unsigned char ascii_code;
if(hex_data<=9)
{
ascii_code=hex_data+0x30;
}
else
{
ascii_code=hex_data+0x37;
}
return ascii_code;
}
void Process_AD(unsigned char ad_value )
{
float temperature;
unsigned long Rt;
float voltage,Temp;
voltage = ((float)ad_value*5)/255;//AD转换
string_out_LF_CR("由分压得出阻值为:");
Rt = 10000*voltage/(5-voltage);//计算阻值
LCD1602_SetCursor(6,0);
serial_out(hex_to_ascii(Rt/10000%10));
LCD1602_WriteData(hex_to_ascii(Rt/10000%10));
serial_out(hex_to_ascii(Rt/1000%10));
LCD1602_WriteData(hex_to_ascii(Rt/1000%10));
serial_out(hex_to_ascii(Rt/100%10));
LCD1602_WriteData(hex_to_ascii(Rt/100%10));
serial_out(hex_to_ascii(Rt/10%10));
LCD1602_WriteData(hex_to_ascii(Rt/10%10));
serial_out(hex_to_ascii(Rt%10));
LCD1602_WriteData(hex_to_ascii(Rt%10));
string_out_LF_CR("Ω");
serial_out(0x0d);
serial_out(0x0a);
string_out_LF_CR("由曲线关系计算出当前温度为:");
Temp = 11776.925/(2.9815*(log(Rt)-log(10000))+39.50);//计算温度
temperature=Temp-273.15;
LCD1602_SetCursor(6,1);
serial_out(hex_to_ascii((int)temperature/100%10));
serial_out(hex_to_ascii((int)temperature/10%10));
LCD1602_WriteData(hex_to_ascii((int)temperature/10%10));
serial_out(hex_to_ascii((int)temperature%10));
LCD1602_WriteData(hex_to_ascii((int)temperature%10));
serial_out('.');
LCD1602_WriteData('.');
serial_out(hex_to_ascii((int)(temperature*10)%10)); LCD1602_WriteData(hex_to_ascii((int)(temperature*10)%10));
string_out_LF_CR("℃");
serial_out(0x0d);
serial_out(0x0a);
serial_out(0x0d); //换行
serial_out(0x0a);
}
//***********************************************************//
unsigned char Read_AD_Value(void)
{
unsigned char ad_value;
while(!(ADC_CONTR&0x10)); //等待AD值转换完成
ADC_CONTR&=0xef; //清零AD转换完标志位
ADC_CONTR|=0x08; //再次开启AD转换
ad_value=ADC_DATA; //取AD值
return ad_value;
}
//*****************************************// AD初始化
void Intil_AD(void)
{
P1M0=0XFF;
P1M1=0X00; //P1口仅作为输入(高阻)作为A/D使用
ADC_CONTR=0xe8|Channel; //开ADC电源;转换速度为270个时钟周期转换一次
}
//********************************************// 主函数
void main(void)
{
Intil_Serial();//串口初始化;波特率9600;
Intil_AD(); //AD初始化
LCD1602_Init();
LCD1602_ShowString(0,0," ");
LCD1602_ShowString(4,0,"R:00000");
LCD1602_SetCursor(11,0);
LCD1602_WriteData(0xf4);
LCD1602_ShowString(4,1,"T:00.0 C");
LCD1602_SetCursor(10,1);
LCD1602_WriteData(0xdf);
while(1)
{
Process_AD(Read_AD_Value());
Delay_ms(1000); //延时1秒
}
}
显示程序:
#ifndef __LCD1602_H__
#ifndef __INTRINS_H__
#include "intrins.h"
#endif
#define LCD1602_DATA_PORT P2
sbit RS = P3^3;
sbit RW = P3^4;
sbit E = P3^5;
void LCD1602_DelayMs(unsigned int ms);
unsigned char LCD1602_BusyCheck(void);
void LCD1602_WriteCmd(unsigned char cmd);
void LCD1602_WriteData(unsigned char dat);
void LCD1602_SetCursor(unsigned char x, unsigned char y);
void LCD1602_Init(void);
void LCD1602_DelayMs(unsigned int ms)
{
unsigned char i;
while(ms--)
for(i = 0; i< 248; i++);
}
unsigned char LCD1602_BusyCheck(void)
{
unsigned char busy_state;
RS = 0;
RW = 1;
E = 1;
_nop_();
_nop_();
_nop_();
_nop_();
busy_state = (LCD1602_DATA_PORT & 0x80) >> 7;
E = 0;
return busy_state;
}
void LCD1602_WriteCmd(unsigned char cmd)
{
while(LCD1602_BusyCheck());
RS = 0;
RW = 0;
E = 0;
LCD1602_DATA_PORT = cmd;
E = 1;
E = 0;
}
void LCD1602_WriteData(unsigned char dat)
{ //写入字符显示数据到LCD
while(LCD1602_BusyCheck());
RS = 1;
RW = 0;
E = 0;
LCD1602_DATA_PORT = dat;
E = 1;
E = 0;
LCD1602_DelayMs(1);
}
/********************************
// 使用说明:以左上角第一个字符为原点(0,0),第二排最后一个字符坐标为(15,1)
********************************/
void LCD1602_SetCursor(unsigned char x, unsigned char y)
{
x %= 16;
y %= 2;
if(y == 1)
{
x += 0x40;
}
LCD1602_WriteCmd(x | 0x80);
}
/*******************************
// 使用说明:主函数开始必须调用初始化函数
*******************************/
void LCD1602_Init(void)
{
LCD1602_WriteCmd(0x38); // 设置16*2显示,5*7点阵,8位数据接口
LCD1602_DelayMs(3);
LCD1602_WriteCmd(0x0c); // 开显示,不显示光标,光标不闪烁
LCD1602_DelayMs(3);
LCD1602_WriteCmd(0x06); // 设置光标自增模式
LCD1602_DelayMs(3);
LCD1602_WriteCmd(0x01); // 清屏
LCD1602_DelayMs(3);
}
/*******************************
// 使用说明:在指定位置开始显示一个字符串,如果字符串溢出屏幕,溢出的字符将从起始位置继续显示
*******************************/
void LCD1602_ShowString(unsigned char x, unsigned char y, unsigned char *str)
{
unsigned char i;
LCD1602_SetCursor(x,y);
for(i=0; str[i]!=0; i++)
{
LCD1602_WriteData(str[i]);
}
}
#endif
展开阅读全文