51测温度并显示华氏和摄氏程序

发布者:BlissfulMoments最新更新时间:2016-09-14 来源: eefocus关键字:51测温度  显示华氏  摄氏 手机看文章 扫描二维码
随时随地手机看文章
///////头文件区//////////////////////////////////////

#include"reg51.h"
#include"intrins.h"
////////////////////////////////////////////////////
/////对于按键的位定义//////////////////////////////
sbit k_TH=P1^0;   // 10 16         *
sbit k_TL=P1^1; //11   15        * 
sbit k_E=P1^2;    //12       14                     *
////////////////////////////////////////////////////
/////对于温度传感器DS18B20的引脚及全局变量定义////////
sbit DQ_D=P3^2;
char TH=10;    //定义高位寄存器   需要符号
char TL=0;    //定义低位寄存器   需要符号
float T=0;     //定义全局温度值寄存器
bit flag_h=0;    //定义高温报警标志   1有效
bit flag_l=0;    //定义低温报警标志   1有效
sbit HEATER=P1^5; //低电平有效
sbit FAN=P1^3;   //低电平有效
sbit SPEAKER=P1^6; //低电平有效 P15               *
unsigned int n=0; //风扇速度采集当中 定时器1用到的倍数软件计数器
bit flag_COUNTER=0; //计数器0溢出中断标志 不使用查询方式 节省系统资源
bit flag_capture=0; //速度采样是否完成标志
unsigned int speed=0;//风扇速度
/////////////////////////////////////////////
/////对于液晶显示的引脚及全局变量定义//////////////
//////////////////////////////////////////////////
#define DQ_L P2   //声明数据端口
sbit BG=P2^6;   //低电平有效
sbit E=P1^2;
sbit RW=P1^1;
sbit RS=P1^0;
unsigned char code fig[10]={"0123456789"};
unsigned char code tab0[]={"CTemper:"};
unsigned char code tab1[]={"HTemper:"};                                     
///////////////////////////////////////////
//////////中断标志////////////////////////
bit flag_X0=0;
////////////////////////////////////////////
void delay_us(unsigned int us)
{
while(us--)
   {
   _nop_();
}
return;
}
void delay_ms(unsigned int ms)
{
unsigned char i=0; 
while(ms--)
{
   for(i=0;i<250;i++)
   {
    _nop_();
    _nop_();
    _nop_();
    _nop_();
   }
}
return;
}
void delay(unsigned int i)
{
while(i--);
}
///////////////////以上是通用代码区//////////////////////
////////下列程序是对温度传感器DS18B20控制的实现//////////
//初始化函数
Init_DS18B20(void)
{
unsigned char x=0;
DQ_D=1; //DQ复位
delay(8); //稍做延时
DQ_D=0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ_D=1; //拉高总线
delay(14);
x=DQ_D; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//读一个字节
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ_D=0; // 给脉冲信号
dat>>=1;
DQ_D=1; // 给脉冲信号
if(DQ_D)
dat|=0x80;
delay(4);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ_D=0;
DQ_D=dat&0x01;
delay(5);
DQ_D=1;
dat>>=1;
}
}
//读取温度
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625; //将温度的高位与低位合并 赋予tt的是测得的温度 是一个单精度的浮点数据
T=tt;
////////////   写温度标记
if(T>TH)
{
flag_h=1;
flag_l=0;
}
else if(T {
flag_h=0;
flag_l=1;

}
else if(T>=TL&&T<=TH)
{
flag_h=0;
flag_l=0;
}
///////////////////
t=tt*10+0.5; //对结果进行4舍5入           //这部算法非常重要
return(t);
}
void DS18B20_deal_data()     //温度数据处理

unsigned char high,mid,low,high1,mid1,low1;
unsigned int temp,temp2,l=0,l1=0;
   void DisplayOneChar(unsigned char x,unsigned char y,unsigned char __data);
//////////////温度数据处理////////////////
    temp=ReadTemperature();   
   temp2=(temp-10)*9/5+50;
   if(temp>=1000)
   { 
   temp/=10;l=1; 
   }
   if(temp2>=1000)
   {
   temp2/=10; l1=1;
   }
   high=temp/100%10;
   mid=temp/10%10;
   low=temp%10;
   high1= temp2/100%10;
   mid1= temp2/10%10;
   low1= temp2%10;
    ///////////数据显示/////////////////////////////////////////       
   if(temp<0) DisplayOneChar(0x08,0,'-'); 
   if(l==1)
   { 
   DisplayOneChar(0x09,0,'1');/////位数显示
   DisplayOneChar(0x0a,0,fig[high]);  
   DisplayOneChar(0x0b,0,fig[mid]);  
   DisplayOneChar(0x0c,0,'.');
   DisplayOneChar(0x0d,0,fig[low]);
   }
   else
   {
   DisplayOneChar(0x09,0,fig[high]);/////位数显示
   DisplayOneChar(0x0a,0,fig[mid]);  
   DisplayOneChar(0x0b,0,'.');
   DisplayOneChar(0x0c,0,fig[low]);
   }
   if(temp2<0)
   DisplayOneChar(0x48,1,'-');
   if(l1==1)
   {
   DisplayOneChar(0x49,1,'1');/////位数显示
   DisplayOneChar(0x4a,1,fig[high]);  
   DisplayOneChar(0x4b,1,fig[mid]);  
   DisplayOneChar(0x4c,1,'.');
   DisplayOneChar(0x4d,1,fig[low]);
   }
   else
   {
   DisplayOneChar(0x49,1,fig[high1]);/////位数显示
   DisplayOneChar(0x4a,1,fig[mid1]);
   DisplayOneChar(0x4b,1,'.');
   DisplayOneChar(0x4c,1,fig[low1]);
   }
}
/////////////////////////////////////////////////////////////////
///////////////////以下是液晶代码区/////////////////////////////
//////////////////////////////////液晶指令集/////////////
void lcd_findbusy()             //忙查询
{
E=0;
RS=0;
RW=1;
E=1;
while(DQ_L&0x80);
delay_us(4);
E=0;
}
void lcd_wcmd(unsigned char cmd)//写命令
{
lcd_findbusy();
delay_us(1);
E=0;
RS=0;
RW=0;
DQ_L=cmd;
E=1;
   lcd_findbusy();
delay_us(4);
E=0;
}
void lcd_wdata(unsigned char _data) //写数据
{
lcd_findbusy();
delay_us(1);         
E=0;
RS=1;
RW=0;
DQ_L=_data;
E=1;
   lcd_findbusy();
delay_us(4);
E=0;
}
void lcd_pos(unsigned char adress)             //设定显示位置
{
lcd_findbusy();
delay_us(1);
lcd_wcmd(adress|0x80);                    //注意用或运算,否则第一位不是1,地址数据写入错误
lcd_findbusy();
return; 

void lcd_first()                     //液晶显示初始化                             
{                                              
BG=0;
delay_ms(1);                                        
lcd_wcmd(0x38);                   //显示设置   双行 8线 5*10点阵                                        
delay_ms(1);                                        
lcd_wcmd(0x08);                   //显示关闭                                        
delay_ms(1);                                        
lcd_wcmd(0x01);        //显示清屏                                  
delay_ms(1);                                        
lcd_wcmd(0x06);        //光标移动设置__向右                                  
delay_ms(1);
lcd_wcmd(0x0c);                   //显示开   不显示光标   光标不闪烁
delay_ms(1);
lcd_findbusy();
return;   
}
void DisplayOneChar(unsigned char x,unsigned char y,unsigned char __data)
{
y=y&0x01;
x=x&0x0f;
if(y)
   x=x|0x40;/// 如果要显示第二行  
lcd_pos(x);
lcd_wdata(__data);
return;
}
void DisplayListChar(unsigned char x,unsigned char y,unsigned char code *__data)
{
unsigned char j=0;
y=y&0x01;
x=x&0x0f;
while(x<=0x0f&&__data[j]!='\0')
{  
   DisplayOneChar(x,y,__data[j]);
   j=j+1;
   x=x+1;  
}
j=0;
return;
}
/////////////////////////////////////////////////////////////////////////////////
///////////////////////以下是高温低温触发报警程序及其附带显示///////////////////////////////////////////
void alert()
{
if(flag_h==1)   //高温触发
   {
     HEATER=1; //加热器关
     FAN=0;    //风扇开
     SPEAKER=0;//蜂鸣器开
   }
else if(flag_l==1)
   {
    SPEAKER=1;//蜂鸣器关
    HEATER=0;   //加热器开
    FAN=1;      //风扇关
   }
else if((flag_l&&flag_h)==0)
{
   FAN=1;      //风扇关
   SPEAKER=1;//蜂鸣器关
   HEATER=1; //加热器关

}
////////////以下是中断初始化///////////
void interrupt_first()
{
/////////中断允许设置////////////// 
EA=1;
EX0=1;   //外中断0中断允许   进入设置
// ET0=1;   //计数器0中断允许
   ET1=1;   //定时器1中断允许
////////////////////////////////////
/////////中断方式设置//////////////
IT0=0;   //外中断0为低电平触发方式
//////////////////////////////////
//////////中断优先设置//////////////////////
PX0=1;
// PT0=1;   //计数器0中断为高中断优先级
PT1=0;   //定时器中断为低中断优先级
}
///////////////计数器和定时器初始化///////
void C_T_first()
{
TMOD=0x25;   //00100110   1为定时器 0为计数器   都使用第二种工作方式 //00100101
TH1=0x19;    //预置0.25ms
TL1=0x19;
TL0=0x00;   
TH0=0x00;
}
///////////////////////////////////////
////////////按键初始化///////////
void key_first()
{
k_TH=1;
   k_TL=1;
   k_E=1;
}
///////////////////////////////
/////////////////////所有初始化程序打包///////
void all_first()
{
interrupt_first();//中断初始化
Init_DS18B20();   //DS18B20初始化
lcd_first();   //液晶初始化
key_first();      //按键初始化
C_T_first();      //计数器0及定时器1初始化
DisplayListChar(0x00,0,tab0);//显示标签tab0[]={"CTemper:"}
    DisplayListChar(0x00,1,tab1);//显示标签tab0[]={"HTemper:"} 
}
/////////////////////////////////////////////
//////////////////////////以下是主函数区//////////////////////////////////
void main()
{
all_first();
   while(1)
{  
   DS18B20_deal_data();    //DS18B20处理数据 
   alert();                //报警查询 
}   
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////中断函数区/////////////////////////////////////////
void interrupt_TIMER1() interrupt 3 using 2   //定时器1中断

TR1=0;
n=n+1;
   TR1=1;
   if(n==2000)
{
   TR0=0;
   TR1=0;
   flag_COUNTER=1;  
}
}

关键字:51测温度  显示华氏  摄氏 引用地址:51测温度并显示华氏和摄氏程序

上一篇:查询方式蜂鸣器(1秒精确间隔)
下一篇:如何向单片机写字符串

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved