1、设计需求及目标
具有温度上下限范围,并可以手动调整;
-
初始化后显示温度信息与上下限信息;
-
模数转换芯片使用分辨率10位以上A/D芯片;
-
采用液晶显示;
2、设计思路及方案
本设计以51系列单片机STC89C52为控制核心,以液晶显示模块、键盘为人机接口,负温度系数热敏电阻器(NTC)为采样传感器,实现了一个基于51单片机的热敏电阻测温设计。
3、 主要代码
#include<reg52.h> //头文件
#include<intrins.h>
#include"eeprom52.h" //调用STC89C52单片机的EEPROM控制程序
#include "math.h"
#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
#define LCD1602_dat P0 //LCD1602的数据传输IO口
sbit LCD1602_rs=P2^5;//LCD1602命令数据控制IO
sbit LCD1602_rw=P2^6; //LCD1602读写IO控制
sbit LCD1602_e=P2^7; //数据脉冲输入
sbit beep=P2^0; //蜂鸣器IO
sbit led_1=P1^5; //超上限指示灯
sbit led_2=P1^6;//超下限指示灯
sbit key_1=P3^5; //设置按键
sbit key_2=P3^6;//加按键
sbit key_3=P3^7;//减按键
sbit TCL2543_EOC = P1^0; //转换结束标志IO口
sbit TCL2543_CLK = P1^1; //I/O时钟输入
sbit TCL2543_ADIN = P1^2; //串行数据输入端
sbit TCL2543_DOUT = P1^3; //串行数据输出端
sbit TCL2543_CS = P1^4; //片选脚IO
float zhi; //暂存读取的输入变量
int temp; //读取DS18B20的温度数据
char temp_h,temp_l; //温度上下限制存储变量
uchar state,ms; //系统设置项变量、50ms定时变量
bit s1,beep1; //设置闪烁标志位、报警标志位
void delay(uint T) //系统延时程序
{
while(T--);
}
// 其中 port 为通道: 通道0:port = 0x01 通道1:port = 0x02 通道2:port = 0x04 ...
// 片子操作文本地址 http://wenku.baidu.com/link?url=WTp8rj93fYDbqM6kYbynkqTrI5MGQFQGtgk6aDrMMdfcB0K2Q9HIrVOs-SSSCLUMOKLOS31ENJAadBSdrVMHg_YxXPYcXWC7T0rb-rINptW
uint read2543(unsigned char port) //读取TCL2543对应模拟输入口的AD数据,并返回数据
{
unsigned int i; //上电时,EOC=“1”,CS=“1”
uint ad_value=0;
TCL2543_CLK=0;
TCL2543_CS=0; //使能TCL2543片选
TCL2543_EOC=1;
port<<=4;
for(i=0;i<12;i++) //读取12位的模拟量的数字数据
{
if(TCL2543_DOUT) ad_value|=0x01; //前次转换结果的MSB即A11位数据输出到Dout供读数
TCL2543_ADIN=(bit)(port&0x80);
TCL2543_CLK=1; //
_nop_();
_nop_();
_nop_();
TCL2543_CLK=0;
_nop_();
_nop_();
_nop_();
port=port<<1;
ad_value=ad_value<<1;
}
TCL2543_CS=1; //锁定片子
ad_value=ad_value>>1;
return ad_value; //返回读取的AD值
}
/********************************************************************
* 名称 : LCD1602_write(uchar order,dat)
* 功能 : 1602写如数据函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void LCD1602_write(uchar order,dat) //1602 一个字节 处理
{
LCD1602_e=0;
LCD1602_rs=order;
LCD1602_dat=dat;
LCD1602_rw=0;
LCD1602_e=1;
delay(1);
LCD1602_e=0;
}
/********************************************************************
* 名称 : LCD1602_writebye(uchar *prointer)
* 功能 : 1602写入数据函数 指针式
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void LCD1602_writebyte(uchar *prointer) //1602 字符串 处理
{
while(*prointer!='\0')
{
LCD1602_write(1,*prointer);
prointer++;
}
}
/********************************************************************
* 名称 : LCD1602_cls()
* 功能 : 初始化1602液晶
* 输入 : 无
* 输出 : 无
***********************************************************************/
void LCD1602_cls() //1602 初始化
{
LCD1602_write(0,0x01); //1602 清屏 指令
delay(1500);
LCD1602_write(0,0x38); // 功能设置 8位、5*7点阵
delay(1500);
LCD1602_write(0,0x0c); //设置 光标 不显示开关、不显示光标、字符不闪烁
LCD1602_write(0,0x06);
LCD1602_write(0,0xd0);
delay(1500);
}
/********************************************************************
* 名称 : show()
* 功能 : LCD1602液晶显示程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void show() //显示数据
{
LCD1602_write(0,0x80); //显示位置设定
LCD1602_writebyte("Temp:"); //显示当前温度值
if(temp>=0) //显示温度整数部分
{
if(temp>999)LCD1602_write(1,0x30+temp/1000%10);
else LCD1602_writebyte(" ");
if(temp>99)LCD1602_write(1,0x30+temp/100%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+temp/10%10);
LCD1602_writebyte(".");
LCD1602_write(1,0x30+temp%10);
}else
{
LCD1602_writebyte("-"); //显示温度负数部分
if(temp*-1>99)LCD1602_write(1,0x30+(temp*-1)/10%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+(temp*-1)%10);
LCD1602_writebyte(".");
LCD1602_write(1,0x30+temp%10);
}
LCD1602_write(1,0xdf);
LCD1602_writebyte("C ");
LCD1602_write(0,0xC0); //第二行显示温度上下限值
LCD1602_writebyte("H:");
if(state==1&&s1==1) //对应设置项设置时闪烁控制 //上限
{
LCD1602_writebyte(" ");
}else //显示上限值
{
if(temp_h>=0)
{
if(temp_h>99)LCD1602_write(1,0x30+temp_h/100%10);
else LCD1602_writebyte(" ");
if(temp_h>9)LCD1602_write(1,0x30+temp_h/10%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+temp_h%10);
}else
{
LCD1602_writebyte("-");
if(temp_h*-1>9)LCD1602_write(1,0x30+(temp_h*-1)/10%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+(temp_h*-1)%10);
}
}
LCD1602_write(1,0xdf);
LCD1602_writebyte("C L:");
if(state==2&&s1==1) //对应设置项设置时闪烁控制 //下限
{
LCD1602_writebyte(" ");
}else
{
if(temp_l>=0) //显示下限值
{
if(temp_l>99)LCD1602_write(1,0x30+temp_l/100%10);
else LCD1602_writebyte(" ");
if(temp_l>9)LCD1602_write(1,0x30+temp_l/10%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+temp_l%10);
}else
{
LCD1602_writebyte("-");
if(temp_l*-1>9)LCD1602_write(1,0x30+(temp_l*-1)/10%10);
else LCD1602_writebyte(" ");
LCD1602_write(1,0x30+(temp_l*-1)%10);
}
}
LCD1602_write(1,0xdf);
LCD1602_writebyte("C");
}
/********************************************************************
* 名称 : proc()
* 功能 : 系统指示灯与报警处理
* 输入 : 无
* 输出 : 无
***********************************************************************/
void proc()
{
if(temp>temp_h*10) //如果当前温度高于上限温度
{
led_1=0; //对应指示灯点亮
}else //否则 熄灭
{
led_1=1;
}
if(temp<temp_l*10) //如果当前温度低于下限温度
{
led_2=0; //对应指示灯点亮
}else //否则 熄灭
{
led_2=1;
}
if(temp>temp_h*10||temp<temp_l*10) //如果当前温度 值不处于 上下限温度之间 这报警标志位值1 反之 置0
{
beep1=1; //开始报警
}else
{
beep1=0; //停止报警
}
}
/********************************************************************
* 名称 : key()
* 功能 : 系统控制按键控制检测程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void key()
{
if(!key_1) //判断按键是否按下
{
delay(888); //延时去抖
if(!key_1) //再次判断按键是否按下
{
state=(state+1)%3; //切换设置项
while(!key_1); //按键判断释放
}
}
if(state!=0) //如果系统非设置状态 则
{
if(!key_2) //判断按键是否按下//如果加按键按下
{
delay(888); //延时去抖
if(!key_2) //再次判断按键是否按下
{
while(!key_2) show(); //按键判断释放
switch(state) //判断当前设置项
{
case 1: //如果是上限设置
if(temp_h<99)temp_h++;
SectorErase(0x2000); //保存上限值
byte_write(0x2000,temp_h);
break;
case 2: //如果是下限设置
if(temp_h>temp_l+1)temp_l++;
SectorErase(0x2200); //保存上限值
byte_write(0x2200,temp_l);
break;
}
}
}
if(!key_3) //判断按键是否按下 如果减按键按下
{
delay(888); //延时去抖
if(!key_3) //再次判断按键是否按下
{
while(!key_3) show(); //按键判断释放
switch(state) //判断当前设置项
{
case 1: //如果是上限设置
if(temp_h>temp_l+1)temp_h--;
SectorErase(0x2000); //保存上限值
byte_write(0x2000,temp_h);
break;
case 2: //如果是下限设置
if(temp_l>-40)temp_l--;
SectorErase(0x2200); //保存上限值
byte_write(0x2200,temp_l);
break;
}
}
}
}
}
/********************************************************************
* 名称 : float TempCalculate(float Rx,float B,float Revise,float BasicRx)
* 功能 : 根据当前热敏电阻的阻值、以及参数、通过Sin曲线求出当前系统的温度值 并返回浮点型的温度值
* 输入 : 无
* 输出 : 无
***********************************************************************/
float TempCalculate(float Rx,float B,float Revise,float BasicRx){
/*
Rx: 热敏电阻当前阻值
B: 热敏电阻参数B值
Revise: 校正温度
BasicRx: 热敏电阻25度时电阻(标称电阻数值)
返回: 摄氏度
*/
Rx = Rx / BasicRx;
Rx = log(Rx);
Rx = (Rx) / B;
Rx = Rx + 0.003356;
Rx = 1 / Rx;
Rx = Rx - 273.13;
Rx = Rx + Revise;
return Rx;
}
/********************************************************************
* 名称 : void main()
* 功能 : 系统主程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
float Rad; //生成运算暂存变量
LCD1602_cls();//LCD1602初始化程序调用
TMOD=0x01; //定时器0初始化配置
TH0=0x4c;
TL0=0x00; //定时初值赋值
ET0=1; //定时器0中断打开
TR0=1; //打开定时器0
EA=1; //打开总中断
temp_h=byte_read(0x2000); //读取EEPROM中存储的温度上下限值
temp_l=byte_read(0x2200);
if(temp_h>99||temp_l>99||temp_l>=temp_h) //判断读取的温度上下限值是否错误 如果是 则重新赋值
{
temp_h=30;
temp_l=10;
}
while(1)
{
zhi=(float)read2543(0)/819.0; //计算电压值
Rad=zhi/((5.0-zhi)/10000.0); //计算热敏电阻当前阻值
temp=(int)((temp * 0.5) + (TempCalculate(Rad,3950.0,0,10000.0) * 0.5)*10);//求出当前系统的当前温度
show(); //显示函数
key(); //按键处理程序
proc(); //超限处理程序
}
}
/********************************************************************
* 名称 : void UART_1() interrupt 1
* 功能 : 定时器0中断服务程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void UART_1() interrupt 1
{
TH0=0x4c; //重新赋值
TL0=0x00;
ms++; //50ms定时变量计时
if(ms%5==0) //区分250ms定时
{
s1=!s1; //闪烁标志位切换
if(beep1==1) beep=!beep; //判断报警标志位是否报警
else beep=1;
}
if(ms>19) //1s定时
{
ms=0;
}
}
完整资料:
https://market.m.taobao.com/app/idleFish-F2e/widle-taobao-rax/page-detail?wh_weex=true&wx_navbar_transparent=true&id=614761731864&ut_sk=1.WUpxx7gpwUoDAMmnnrBIzAno_12431167_1585215931516.Copy.detail.614761731864.1828622527&forceFlush=1