标题:
单片机数字温度计仿真程序 带负温度显示
[打印本页]
作者:
无底价
时间:
2020-10-29 18:26
标题:
单片机数字温度计仿真程序 带负温度显示
功能说明
1.数码管显示 DS18B20设置的问题
2.报警设置初始值为30 上电默认30 K1按键按下进入报警温度设置 K2+温度 K3-温度 K4恢复显示
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
捕获.PNG
(31.89 KB, 下载次数: 50)
下载附件
2020-10-29 18:29 上传
单片机源程序如下:
#include "reg52.h"
typedef unsigned int uint;
//对数据类型进行声明定义
typedef unsigned char uchar;
sbit beep = P1^5;
sbit DSPORT =P3^7;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;
uint DisplayData[8];
uint code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint warn = 30;
uint tt = 30;//记录温度
uint warns[8];
void delay(uint i){ //延迟ius
while(i--);
}
//延迟函数
void Delay1ms(uint y)
{
uint x;
for( ; y>0; y--)
{
for(x=110; x>0; x--);
}
}
//初始化函数
uchar Ds18K20Init()
{
uchar i;
DSPORT = 0;
//将总线拉低480us~960us
i = 73;
while(i--);//延时642us
DSPORT = 1;
//然后拉高总线,如果DS18K20做出
//反应会将在15us~60us后总线拉低
i = 0;
while(DSPORT)
{//等待DS18K20拉低总线
Delay1ms(1);
i++;
if(i>5)//等待>5ms
{
return 0;//初始化失败
}
}
return 1;//初始化成功
}
//向传感器写字节
void Ds18K20WriteByte(uchar dat)
{
uint i, j;
for(j=0; j<8; j++)
{
DSPORT = 0;
//每写入一位数据之前先把总线拉低1us
i++;
DSPORT = dat & 0x01;
//然后写入一个数据,从最低位开始 0000 0001
i=6;
while(i--);
//延时68us,持续时间最少60us
DSPORT = 1;
//然后释放总线,至少1us给总线恢复时
//间才能接着写入第二个数值
dat >>= 1;
//传输完最低位,数据右移,传输次低
//位,依次循环 1000 1001 -> 0100 0100
}
}
//从传感器读字节
uchar Ds18K20ReadByte()
{
uchar byte, bi;//bi保存单位数据
uint i,j;
for(j=8; j>0; j--)
{
DSPORT = 0;//先将总线拉低1us
i++;
DSPORT = 1;//总线拉高,然后释放总线
i++;
i++;//延时6us等待数据稳定
bi = DSPORT; //读取数据,从最低位开始读取
byte = (byte >> 1) | (bi << 7);
/*如,byte=0000 0000,bi读取到一个最低位有效数字0000 0001,
左移七位1000 0000,byte右移一位0000 0000,和byte或,
byte=1000 0000,bi读取到一个最低位有效数字0000 0001,
左移七位1000 0000,byte右移一位0100 0000,和byte或,
byte=1100 0000,以此类推
*/
while(i--);//延时45us
}
return byte;
}
//温度转换函数指令
void Ds18K20ChangTemp()
{
Ds18K20Init();
Delay1ms(1);
Ds18K20WriteByte(0xcc);
//跳过ROM操作命令
Ds18K20WriteByte(0x44);
//温度转换命令
//Delay1ms(100);
//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
}
//读取温度数据指令
void Ds18K20ReadTempCom()
{
Ds18K20Init();
Delay1ms(1);
Ds18K20WriteByte(0xcc);
//跳过ROM操作命令
Ds18K20WriteByte(0xbe);
//发送读取温度命令
}
//报警函数
void Alarm(uint t){
uint i = 10;
if(t>=warn){
while(i--){
beep=~beep;
}
}
}
//温度读取函数
int Ds18K20ReadTemp()
{
int temp = 0;
//注意这里int是2字节16位
uchar tmh, tml;
//分别用于存放温度的低字节和高字节数据
Ds18K20ChangTemp();
//先写入转换命令
Ds18K20ReadTempCom();
//然后等待转换完后发送读取温度命令
tml = Ds18K20ReadByte();
//读取温度值共16位,先读低字节
tmh = Ds18K20ReadByte();
//再读高字节
temp = tmh;
//先读取高八位 0000 0000
temp <<= 8;
//将读取到的数据从temp低八位移位至高八位
temp |= tml;
//以或的形式读取低八位
return temp;
}
//数据处理函数
void datapros(int temp)
{ uint ge,shi,bai;
float tp;
//保存温度
if(temp< 0)//当温度值为负数
{
DisplayData[0] = 0x40; // -
//因为读取的温度是实际温度的补码
//,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为
//C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5
//之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
else
{
DisplayData[0] = 0x00;
tp=temp;
//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮
//点数转换为整型的时候把小数点后面的数自动去掉,
//不管是否大于0.5,而+0.5之后大于0.5的就是进1了,
//小于0.5的就算加上0.5,还是在小数点后面。
}
bai=temp / 10000;
shi=temp % 10000 / 1000;
ge= temp % 10000 % 1000/100;
DisplayData[1] = smgduan[bai]; //百位
DisplayData[2] = smgduan[shi]; //十位
DisplayData[3] = smgduan[ge]|0x80; //个位
DisplayData[4] = smgduan[temp % 100 / 10];
DisplayData[5] = smgduan[temp % 100 % 10];
tt=bai*100+10*shi+ge;
}
void dealWaring(){//警戒处理函数
if(warn>0){
warns[0] = 0x00;
warns[1] = smgduan[warn/100];
warns[2] = smgduan[warn%100/10];
warns[3] = smgduan[warn%10];
}else{
warns[0]= 0x40; // -
warns[1] = smgduan[warn/100];
warns[2] = smgduan[warn%100/10];
warns[3] = smgduan[warn%10];
}
}
void keyScan()//键盘控制
{
uint flag;
if(K1==0)//按下按键1进入警戒值调整
{
Delay1ms(10);
if(K1==0)
{
dealWaring();
while(flag){
uchar i;
for(i=0;i<6;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=1;LSB=1;LSC=1; break;//显示第0位
case(1):
LSA=0;LSB=1;LSC=1; break;//显示第1位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第2位
case(3):
LSA=0;LSB=0;LSC=1; break;//显示第3位
case(4):
LSA=1;LSB=1;LSC=0; break;//显示第4位
case(5):
LSA=0;LSB=1;LSC=0; break;//显示第5位
case(6):
LSA=1;LSB=0;LSC=0; break;//显示第6位
case(7):
LSA=0;LSB=0;LSC=0; break;//显示第7位
}
P0=warns[i];//发送段码
delay(50); //间隔一段时间扫描
P0=0x00;//消影
}
if(K2==0)
{
Delay1ms(10);
if(K2==0)
{
warn++;
dealWaring();
while(!K2);
}
}
if(K3==0)
{
Delay1ms(10);
if(K3==0)
{
warn--;
dealWaring();
while(!K3);
}
}
if(K4==0)
{
Delay1ms(10);
if(K4==0)
{
flag=0;
while(!K4);
}
}
}
}
}
}
//显示数字
void DigDisplay()
{
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
基于DS18B20的温度传感器设计.zip
(109.91 KB, 下载次数: 41)
2020-10-29 18:26 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1