求STC89C51单片机和DS18B20温度程序,用四位共阳数码管显示,74HC573驱动

求STC89C51单片机和DS18B20温度程序,用四位共阳数码管显示,74HC573驱动,第1张

//#include <at89x51.h>//用AT89C51时就用这个头文件

#include <reg52.h>//用华邦W78E58B时必须用这个头文件

sbit DQ = P3^7 //定义DQ引脚为P3.7

/***********ds18b20延迟子函数(晶振12MHz )*******/

/************DS18B20对时间要求很严,但只能长不能短

*************在11.0592M下也行,因为时间长些********/

void delay_18B20(unsigned int i)

{

while(i--)

}

/**********ds18b20初始化函数**********************/

void Init_DS18B20(void)

{

 unsigned char x=0

 DQ = 0          //单片机将DQ拉低

 delay_18B20(80) //精确延时 大于 480us

 DQ = 1          //拉高总线

 delay_18B20(14)

 x=DQ            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败

 delay_18B20(20)

}

/***********ds18b20读一个字节**************/

unsigned char ReadOneChar(void)

{

unsigned char i=0

unsigned char dat = 0

for (i=8i>0i--)

 {

  DQ = 0 // 给脉冲信号

  dat>>=1

  DQ = 1 // 给脉冲信号

  if(DQ)

  dat|=0x80

  delay_18B20(4)

 }

return(dat)

}

/*************ds18b20写一个字节****************/

void WriteOneChar(unsigned char dat)

{

unsigned char i=0

for (i=8 i>0 i--)

{

DQ = 0

DQ = dat&0x01

delay_18B20(5)

DQ = 1

dat>>=1

}

}

/****************设置DS18B20工作盯笑状态*******************

TH和TL分别是上限报警和下限报警温度,RS是显示分辨率的设置

*******************************************************/

void setds18b20(unsigned char TH,unsigned char TL,unsigned char RS)

{

Init_DS18B20()

WriteOneChar(0xCC)     // 跳过读序号列号的 *** 作

WriteOneChar(0x4E)  // //写入"写暂存器"命令,修改TH和TL和分辩率配置寄存器

//先写TH,再写TL,最后写配置寄存器

WriteOneChar(TH) //写入想设定的温度报警上限

WriteOneChar(TL) //写入想设定的温度报警下限

WriteOneChar(RS) //写配置寄存器,格式为0 R1 R0 1,1 1 1 1

//R1R0=00分斗世辨率娄9位,R1R0=11分辨率为12位

}

/**************读取ds18b20当前温度************/

unsigned char *ReadTemperature(void)

{ unsigned char tt[2]

Init_DS18B20()

WriteOneChar(0xCC)     // 跳过读序号列号的 *** 作

WriteOneChar(0x44)  // 启动温度转换

delay_18B20(70)       // 温度转化要一段时间

Init_DS18B20()

WriteOneChar(0xCC)  //跳过读序号列号的 *** 作

WriteOneChar(0xBE)  //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

//delay_18B20(70)

tt[0]=ReadOneChar()     //读取温度空则肢值低位

tt[1]=ReadOneChar()    //读取温度值高位

return(tt)

}

//#include <at89x51.h>//用AT89C51时就用这个头文件

#include <reg52.h>//用华邦W78E58B时必须用这个头文件

#include <intrins.h>//此函数为库函数,里面有_nop_函数,相当于汇编中的NOP

//Port Definitions**********************************************************

sbit LcdRs = P2^0

sbit LcdRw = P2^1

sbit LcdEn   = P2^2

sfr  DBPort  = 0x80 //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

//内部等待函数**************************************************************************

void LCD_Wait(void)

{

LcdRs=0 //RS=0表示选择指令寄存器

LcdRw=1 _nop_()//RW=1表示进行读 *** 作

LcdEn=1 _nop_()//在EN为下降沿的时候锁存数据

while(DBPort&0x80)

{

LcdEn=0

_nop_()

    _nop_()

LcdEn=1

_nop_()

    _nop_()

}

LcdEn=0

}

//向LCD写入命令或数据************************************************************

#define LCD_COMMAND 0      // Command

#define LCD_DATA 1      // Data

#define LCD_CLEAR_SCREEN 0x01      // 清屏

#define LCD_HOMING   0x02      // 光标返回原点

void LCD_Write(bit style, unsigned char input)

{

LcdEn=0

LcdRs=style

LcdRw=0 _nop_()

DBPort=input _nop_()//注意顺序

LcdEn=1 _nop_()//注意顺序

LcdEn=0 _nop_()

LCD_Wait()

}

//设置显示模式************************************************************

#define LCD_SHOW 0x04    //显示开

#define LCD_HIDE 0x00    //显示关

#define LCD_CURSOR 0x02  //显示光标

#define LCD_NO_CURSOR 0x00    //无光标

#define LCD_FLASH 0x01    //光标闪动

#define LCD_NO_FLASH 0x00    //光标不闪动

void LCD_SetDisplay(unsigned char DisplayMode)

{

LCD_Write(LCD_COMMAND, 0x08|DisplayMode)

}

//设置输入模式************************************************************

#define LCD_AC_UP 0x02

#define LCD_AC_DOWN 0x00      // default

#define LCD_MOVE 0x01      // 画面可平移

#define LCD_NO_MOVE 0x00      //default

void LCD_SetInput(unsigned char InputMode)

{

LCD_Write(LCD_COMMAND, 0x04|InputMode)

}

//初始化LCD************************************************************

void LCD_Initial()

{

LcdEn=0

LCD_Write(LCD_COMMAND,0x38)           //8位数据端口,2行显示,5*7点阵

LCD_Write(LCD_COMMAND,0x38)

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR)    //开启显示, 无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN)   //清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE)       //AC递增, 画面不动

}

//************************************************************************

void GotoXY(unsigned char x, unsigned char y)

{

if(y==0)

LCD_Write(LCD_COMMAND,0x80|x)

if(y==1)

LCD_Write(LCD_COMMAND,0x80|(x-0x40))

}

void Print(unsigned char *str)

{

while(*str!='\0')

{

LCD_Write(LCD_DATA,*str)

str++

}

}

void LCD_Print(unsigned char x, unsigned char y, unsigned char *str)

{

GotoXY(x,y)

Print(str)

}

#include <reg52.h>

//#include <at89x52.h>

//unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成相应的BCD码

//                          0x66,0x6d,0x7d,0x07,

//                          0x7f,0x6f,0x77,0x7c,

//                          0x39,0x5e,0x79,0x71}

//unsigned char code KEY[]={0x00,0x00,0x01,0x02,0x03,//此处是为使程序通用,当键值不是按

//       0x04,0x05,0x06,0x07,//这个排列时,把此表更改即可

//    0x08,0x09,0x0a,0x0b,//最前面的那个0x00是为了查表方便,

//    0x0c,0x0d,0x0e,0x0f}//因为键值是从1开始的

sfr key_port=0x90     //定义P1口为键盘扫描口

//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

bit key_ok=0        //有键按下的标志

/*************延时子程序*************

****调用一次用时18微秒,t每加1,用时增加6微秒*/

void delay(unsigned char t)

{

while(t--)

}

unsigned char r_left(unsigned char x)//循环左移一位

{

x<<=1

x++

return(x)

}

/*************粗判有无键按下**********

****有键按下则将key_ok置1************/

void scan_full(void)

{

unsigned char temp

key_port=0xf0  //低半字节为行线,高半字节为列线

temp=P1

if(temp!=0xf0)

key_ok=1

else key_ok=0

}

/************键盘扫描程序*************************

****功能:返回键值,当无键按下时,返回0*************/

unsigned char key_scan(void)

{

unsigned char temp,count=0x01,key_value//按键返回值

unsigned char x_scan=0xfe,y_scan=0xef//行、列扫描码

unsigned char i,j,y //行数和列数

while(1)

{

scan_full()   //粗判是否有键按下

if(key_ok==1)

{

key_ok=0

delay(200) //延时去抖动

scan_full() //再次粗判是否有键按下

if(key_ok==1)

{

for(i=0i<4i++) //扫描4行

{

  key_port=x_scan

for(j=0j<4j++) //每行4列

{

temp=key_port

   temp=temp&0xf0

   y=y_scan&0xf0

   if(temp==y)

   {

while(key_ok!=0)//等待按键松开

{

scan_full()

}

    key_value=count

    return(key_value)//找到键值,马上返回

   }

   else

   {

    count++

    y_scan=r_left(y_scan)

   }

  }

y_scan=0xef //扫描完一列,重新对列扫描量赋初值

  x_scan=r_left(x_scan)//行扫描码左移一位,扫描下一行  

}

}

}

return(key_value)//没键按下,返回0

}

}

//unsigned char key(void)

//{

// unsigned char x

// unsigned char y

// x=key_scan()

// return(x)

//y=KEY[x]

//return y

//}

//#include <at89x51.h>//用AT89C51时就用这个头文件

#include <reg52.h>//用华邦W78E58B时必须用这个头文件

//#include <absacc.h>

//#include <ctype.h>

//#include <math.h>

//#include <stdio.h>

//#include <string.h>

#include <DS18B20.h> //测温头文件

#include <LCD1602.h> //液晶显示头文件

#include <keyscan.h> //键盘扫描头文件

sbit alarm=P2^6 //报警信号

//sbit DQ = P3^7 //定义DQ引脚为P3.7

unsigned char key_value            //存放键盘扫描值

bit up_one,down_one  //加1和减1标志

bit alarm_up_flag,alarm_down_flag //上限报警和下限报警设置标志

bit set_temper_flag //设置控制标志温度标志

bit alarm_switch //报警开关

unsigned char user_temper  //用户标定温度

unsigned char TH=110,TL=-20,RS=0x3f //上限温度110,下限-20,分辨率10位,也就是0.25C

unsigned char t[2],*pt //用来存放温度值,测温程序就是通过这个数组与主函数通信的

unsigned char  TempBuffer1[17]={0x2b,0x20,0x30,0x30,0x2e,0x30,0x30,0x20,

0x53,0x45,0x54,0x2b,0x20,0x30,0x30,0x43,'\0'}

//显示实时温度,上电时显示+ 00.00 SET+ 00C

unsigned char  TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x20,0x30,0x30,0x20,

0x54,0x4c,0x3a,0x2b,0x20,0x30,0x30,0x43,'\0'}

//显示温度上下限,上电时显示TH:+ 00 TL:+ 00C

unsigned char code dotcode[4]={0,25,50,75}

/***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法*******

再将表值分离出十位和个位后送到十分位和百分位********************/

/***********用户设定温度转换为LCD显示数据**************

*功能:将用户设定温度user_temper,分离出符号位,百、十、个位

  并将它们转化为ACSII码,送到液晶显示缓冲区

******************************************************/

void user_temper_LCD(unsigned char temper)

{

if(temper>0x7f) //判断正负,如果为负温,将其转化为其绝对值

{

TempBuffer1[11]=0x2d //0x2d为"-"的ASCII码

temper=~temper //将负数的补码转换成绝对值

temper++

}

else TempBuffer1[11]=0x2b ////0x2B为"+"的ASCII码

TempBuffer1[12]=temper/100+0x30              //分离出temper的百十个位

if( TempBuffer1[12]==0x30) TempBuffer1[12]=0xfe     //百位数消隐

TempBuffer1[13]=(temper%100)/10+0x30      //分离出十位

TempBuffer1[14]=(temper%100)%10+0x30        //分离出个位

}

/***************温度上下限转换为LCD显示数据************

*功能:将上下限报警温度,分离出符号位,百、十、个位

  并将它们转化为ACSII码,送到液晶显示缓冲区

******************************************************/

void alarm_LCD( unsigned char TH, unsigned char TL)

{

if(TH>0x7F)                    //判断正负,如果为负温,将其转化为其绝对值

{

TempBuffer0[3]=0x2d      //0x2d为"-"的ASCII码

TH=~TH  //将负数的补码转换成绝对值

TH++

}

else TempBuffer0[3]=0x2b //0x2B为"+"的ASCII码

if(TL>0x7f)

{

TempBuffer0[11]=0x2d      //0x2d为"-"的ASCII码

TL=~TL+1

}

else TempBuffer0[11]=0x2b //0x2B为"+"的ASCII码

TempBuffer0[4]=TH/100+0x30              //分离出TH的百十个位

if( TempBuffer0[4]==0x30) TempBuffer0[4]=0xfe //百位数消隐

TempBuffer0[5]=(TH%100)/10+0x30 //分离出十位

TempBuffer0[6]=(TH%100)%10+0x30   //分离出个位

TempBuffer0[12]=TL/100+0x30              //分离出TL的百十个位

if( TempBuffer0[12]==0x30) TempBuffer0[12]=0xfe //百位数消隐

TempBuffer0[13]=(TL%100)/10+0x30 //分离出十位

TempBuffer0[14]=(TL%100)%10+0x30   //分离出个位

}

/**********温度转换为LCD显示数据****************

*功能:将两个字节的温度值,分离出符号位,整数及小数

  并将它们转化为ACSII码,送到液晶显示缓冲区

************************************************/

void temper_LCD(void)

{

unsigned char x=0x00,y=0x00

t[0]=*pt

pt++

t[1]=*pt

if(t[1]>0x07)                    //判断正负温度

{

TempBuffer1[0]=0x2d      //0x2d为"-"的ASCII码

t[1]=~t[1]  /*下面几句把负数的补码*/

t[0]=~t[0]   /* 换算成绝对值*********/

x=t[0]+1  /***********************/

t[0]=x  /***********************/

if(x>255)                /**********************/

t[1]++  /*********************/

}

else TempBuffer1[0]=0x2b //0xfe为变"+"的ASCII码

t[1]<<=4 //将高字节左移4位

t[1]=t[1]&0x70 //取出高字节的3个有效数字位

x=t[0] //将t[0]暂存到X,因为取小数部分还要用到它

x>>=4 //右移4位

x=x&0x0f //和前面两句就是取出t[0]的高四位

t[1]=t[1]|x //将高低字节的有效值的整数部分拼成一个字节

TempBuffer1[1]=t[1]/100+0x30              //+0x30 为变 0~9 ASCII码

if( TempBuffer1[1]==0x30) TempBuffer1[1]=0xfe //百位数消隐

TempBuffer1[2]=(t[1]%100)/10+0x30 //分离出十位

TempBuffer1[3]=(t[1]%100)%10+0x30   //分离出个位

t[0]=t[0]&0x0c //取有效的两位小数

t[0]>>=2 //左移两位,以便查表

x=t[0]

y=dotcode[x] //查表换算成实际的小数

TempBuffer1[5]=y/10+0x30 //分离出十分位

TempBuffer1[6]=y%10+0x30 //分离出百分位

}

/*********键盘命令处理函数************

*功能:把键盘值转化成相应的功能标志位

*备注:为了提高程序的健壮性,在功能标志位无效时,

**up_one和down_one都无效,并且各功能标志之间

**采用互锁处理,虽然这样麻烦,特别是功能标志较多时

**更是麻烦,但各功能标志之间是同级别的

**也可采用多重if else方法,虽然简单,

**但各功能标志之间有了明显的优先级差别

**************************************/

void key_command(unsigned char x)     

{

switch(x)

{

case 1: up_one=1break

case 2: down_one=1break

case 5: alarm_up_flag=!alarm_up_flagbreak

case 6: alarm_down_flag=!alarm_down_flagbreak

case 7: set_temper_flag=!set_temper_flagbreak

case 8: alarm_switch=!alarm_switchbreak

default: break

}

if(!(alarm_up_flag||alarm_down_flag||set_temper_flag))

{

up_one=0x00 //在没有相应功能标志有效时

down_one=0x00 //up_one和down_one都被锁定

}

if(alarm_up_flag&&(!alarm_down_flag)&&(!set_temper_flag))//设置上限报警

{

if(up_one)//上限报警加1

{

TH++up_one=0

if(TH>=100)//超过100度,回零到20度

TH=20

}

if(down_one)//上限报警减1

{

TH--down_one=0

if(TH<=20)//小于20度,回零到20度

TH=20

}

}

if((!alarm_up_flag)&&(alarm_down_flag)&&(!set_temper_flag))//设置下限报警

{

if(up_one)

{

TL++up_one=0

if(TL>=20)//高于20度,回零到0度

TL=0

}

if(down_one)

{

TL--down_one=0

if(TL<=0)//低于0度,回零到0度

TL=0

}

}

if((!alarm_up_flag)&&(!alarm_down_flag)&&(set_temper_flag))//设置用户标定温度

{

if(up_one)

{

user_temper++up_one=0

if(user_temper>=60)//高于60度,回零到0度

user_temper=0

}

if(down_one)

{

user_temper--down_one=0

if(user_temper<=0)//低于0度,回零到0度

user_temper=0

}

}

//if(alarm_switch)

}

main()

{

setds18b20(TH,TL,RS)     //设置上下限报警温度和分辨率

delay(100) 

while(1)

{

pt=ReadTemperature()    //测温函数返回这个数组的头地址

 //读取温度,温度值存放在一个两个字节的数组中,

temper_LCD()  //实测温度转化为ACSII码,并送液晶显示缓冲区

user_temper_LCD(user_temper)  //用户设定温度转化为ACSII码,并送液晶显示缓冲区

alarm_LCD(TH,TL)  //上下限报警温度转化为ASCII码,并送液晶显示缓冲区

LCD_Initial() //第一个参数列号,第二个为行号,为0表示第一行

//为1表示第二行,第三个参数为显示数据的首地址

LCD_Print(0,0,TempBuffer0)

LCD_Print(0,1,TempBuffer1)

scan_full()                     //看有无键按下

if(key_ok) //如有键按下则看到底哪个键按下

{

key_value=key_scan()  //调用键盘扫描程序

key_command(key_value)  //键盘命令处理函数

}

}

}

觉得能运行,我试过了,自己看图

温度测量点的数量和温度传感器数量是相同的

要实现128点温度饥春测量

必须要有128个温度传感器

温度传感器(temperature transducer)是指能感受温度并转换成可用输出信号的传感器。

温度传感器是温度测量仪表的核心部分,品种繁多。

进入21世纪后,温度传感器正朝着高精度、多功能、总线标准化、高可靠性及安全性、开发虚拟传感器和网络传感器、研制单片测温系统等高科技的方向迅速发展。温度传感器的总线技术也实现了标准化、可作为从机可通过专用总线接口与主机进烂枣耐行通信。岩游

按测量方式可分为接触式和非接触式两大类,按照传感器材料及电子元件特性分为热电阻和热电偶两类。

近期室外温度骤减,据天气预报12月29日后室外温度将降至-30℃。能不能度过一个舒适的冬天,室内温度的确是一个关键指标,供暖温度达到多少为合格温度?

根据国家建设部1996年第51号令《宽派握城市集中供暖企业资质标准》规定,用户室内采暖温度应为18℃±2℃,不低于16℃。

为什么国家标准供热温度定在18℃±2℃呢?

据我国供暖创新发展联盟的专家组研究表明,最适合人居住的室内温度冬季为16~18℃,夏季为24~26℃,当室内温度超过22°C之后,会影响人体自身的体温调节功能,造成体温上升,血管扩张,心率加快,内分泌紊乱等。同时,温度过高也会提高家具、地板、石材等装饰材料里面有毒有害气体的挥发排放。

那么石河子垦区的供暖温度是如何规定的呢?

按照民用建筑供暖通风与空气调节设计规范的要求,石河子垦区冬季供暖室外计算温度为-22.2℃,室内设计温度为18℃。

同时,依据《新疆维吾尔自治区民用建筑供热节能办法》第十九条、第二十条规定:供热企业应当根据国家、自治区冬季采暖标准和特许经营协议、供热合同约定的内容供热,不得任意降低或者提高供热温度。民用建筑供热节能应当转变用热观念,以保证建筑使用功能和室内热环境质量为前提,居住建筑供热温度应当控制在22℃以内;除学校、医院、幼儿园、养老院等具有特殊温度要求以外的其他公共建筑,供热温度应当控制在20℃以内。

如何正确的测量家中温度是否合格呢?

有些居民反应,为什么供热部门和我在家用的温度计测出的温度不一样呢?供热部门测温的标准到底是什么?

测量供热室内慎庆温度,应符合以下要求:使用经检定合格的环境测温仪,测温时选取被测房间中心位置(对角线交点)距地1.4米的高度为测温点,测温过程中关闭室内所有门窗,待房间温度稳定后开始测温,测温仪表示值稳定时结束测温。

如果测温不合格应如何处理呢?

用户在供暖期如因供暖企业的原因,经工作人员测温,室羡桥内温度达不到16℃的,供热部门会及时安排维修人员到用户家中进行处理,尽快使用户室内温度恢复到规定温度。如一个采暖季3次以上测温均不达标,客户可以依据测温记录,到所在片区的供热营业所提出减免报告,落实情况属实后,将根据相关文件规定予以扣减。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12150333.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存