include"temp.h" /******************************************************************************** 函 数 名 : main* 函数功能 : 主函数* 输 入 : 无* 输 出 : 无*******************************************************************************/void main(){ P2M1=0; //推挽输出 P2M0=0x03; init(); while(1) { display(Get_Tmp()); pulse_RL(); }}#include"stc12c5a60s2.h"#include #define uchar unsigned char#define uint unsigned int//--定义使用的IO口--//sbit DQ = P3^7; sbit PB0=P3^2; // PB0按钮接至P3.2(INT0)sbit PB1=P3^3; // PB1按钮接至P3.3(INT1)sbit relay = P3^4; // 声明继电器的位置uchar code table_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示,共阳/******************************************************************************** 函 数 名 : Delay1ms* 函数功能 : 延时函数* 输 入 : 无* 输 出 : 无*******************************************************************************/uint wendu,atme;void display(int);void Delay1ms(uint y){ uint x; for( ; y>0; y--) { for(x=110; x>0; x--); }}/******************************************************************************** 函 数 名 : Ds18b20Init* 函数功能 : 初始化* 输 入 : 无* 输 出 : 初始化成功返回1,失败返回0*******************************************************************************/ void Delay(unsigned char a1,b1,c1){ unsigned char a,b,c;for(a=0;a
Delay(1,1,1); //稍做延时 10usDQ = 0; //单片机拉低总线Delay(6,1,63); //600 us //精确延时,维持至少480us//Delay(1,1,15); //20usDQ = 1; //释放总线,即拉高了总线Delay(5,1,63); //500us //此处延时有足够,确保能让DS18B20发出存在脉冲}uchar Read_One_Byte() //读取一个字节的数据read a byte date //读数据时,数据以字节的最低有效位先从总线移出{uchar i = 0;uchar dat = 0;for(i=8;i>0;i--) { DQ = 0; //将总线拉低,要在1us之后释放总线 //单片机要在此下降沿后的15us内读数据才会有效。
_nop_(); //至少维持了1us,表示读时序开始 dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位 DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上 Delay(1,1,1); //延时10us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分 if(DQ) //控制器进行采样 { dat |= 0x80; //若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0 } Delay(1,1,8); //20us //此延时不能少,确保读时序的长度60us}return (dat);}void Write_One_Byte(uchar dat){uchar i = 0;for(i=8;i>0;i--){ DQ = 0; //拉低总线 _nop_(); //至少维持了1us,表示写时序(包括写0时序或写1时序)开始 DQ = dat&0x01; //从字节的最低位开始传输 //指令dat的最低位赋予给总线,必须在拉低总线后的15us内, //因为15us后DS18B20会对总线采样。
Delay(1,1,15); //必须让写时序持续至少60us DQ = 1; //写完后,必须释放总线, dat >>= 1; Delay(1,1,1);}}uint Get_Tmp() //获取温度get the wenduerature{float tt;uchar a,b;Init_Ds18b20(); //初始化Write_One_Byte(0xcc); //忽略ROM指令Write_One_Byte(0x44); //温度转换指令Init_Ds18b20(); //初始化Write_One_Byte(0xcc); //忽略ROM指令Write_One_Byte(0xbe); //读暂存器指令a = Read_One_Byte(); //读取到的第一个字节为温度LSBb = Read_One_Byte(); //读取到的第一个字节为温度MSBwendu = b; //先把高八位有效数据赋于wenduwendu <<= 8; //把以上8位数据从wendu低八位移到高八位wendu = wendu|a; //两字节合成一个整型变量tt = wendu*0.0625; //得到真实十进制温度值 //因为DS18B20可以精确到0.0625度 //所以读回数据的最低位代表的是0.0625度wendu = tt*10+0.5; //放大十倍wendu=wendu/10; //这样做的目的将小数点后第一位也转换为可显示数字 //同时进行一个四舍五入操作。
return wendu;}void init() //中断初始化{ IT0=1; IT1=1; EX0=1; EX1=1; EA=1;}void INT0() interrupt 0 { EX0=0; Delay1ms(5); if(PB0==0) { atme++; while(!PB0) { if(PB1==0&&PB0==0) {atme=Get_Tmp();} display(atme); } } EX0=1;}void INT1() interrupt 2{ EX1=0; Delay1ms(5); if(PB1==0) { atme--; while(!PB1) { if(PB1==0&&PB0==0) {atme=Get_Tmp();} display(atme); } } EX1=1;}void pulse_RL() //继电器控制{ if(wenduatme) { relay=0; }}void display(int temp1) //显示温度{ P1=table_du[temp1 / 10]; P2=0x02; Delay1ms(10); P1=table_du[temp1 % 10]; P2=0x01; Delay1ms(10); }。