- #include<reg52.h> // 晶振为 11.0592MHz
- #define uint unsigned int
- #define uchar unsigned char
- sbit DQ=P2^5;// 接温度传感器
- sbit duan=P2^6;// 数码管段选
- sbit wei=P2^7; // 数码管位选
- uchar code numw[]={0x01,0x02,0x04,0x08,0x10,// 数码管位选
- 0x20,0x40,0x80,0x00};
- uchar code numd[]={0x3f,0x06,0x5b,0x4f,0x66,// 数码管段选显示( 0—9)
- 0x6d,0x7d,0x07,0x7f,0x6f};
- uchar code numdg[]={0xbf,0x86,0xdb,0xcf,0xe6,// 数码管“个”位段选显示因为保留一位小数,
- 0xed,0xfd,0x87,0xff,0xef};// 所以各位后要显示小数点,所以需要重新编码( 0— 9)
- uchar code numfh[]={0x40,0x00}; // 温度 + — 符号位
- /******************1ms 延时函数 ****************/
- void delay0(uint z)
- {
- uchar x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /******************15us 延时函数 ****************/
- void delay(uint z)
- {
- while(z--);
- }
- /****************** 初始化 DS18B20函数 ****************/
- void reset_ds18b20()
- {
- uchar stat=0;
- DQ=1;
- delay(8);
- DQ=0;
- delay(80); //600us/12mhz
- DQ=1;
- delay(8);
- stat=DQ; // 高电平为存在,低电平为不存在( stat 应该为 0)
- delay(4);
- // while(!DQ);/* 等待 DQ 变为高电平
- // 因为存在脉冲检测结束后自动拉高 */
- //return stat;
- }
- /****************** 写一个字节函数 ****************/
- void write_byte(uchar dat)
- {
- uchar i;
- DQ=1; // 先拉高电平,为写作准备
- for(i=0;i<8;i++)
- {DQ=0;
- DQ=dat&0x01;
- delay(4);//DS18B20 采样单片机写给 DQ 线上的数据( 45us) ***************
- DQ=1;
- dat>>=1;
- }
- delay(4);
- }
- /****************** 读一个字节函数 ****************/
- uchar read_byte()
- {
- uchar vaul,i;
- DQ=1; // 先拉高电平,为读作准备
- for(i=0;i<8;i++)
- {
- DQ=0;
- vaul>>=1;
- DQ=1;
- if(DQ)
- vaul|=0x80;
- delay(4);
- }
- return vaul;
- }
- /****************** 读取温度值函数 ****************/
- int read_temper()
- {
- uchar templ,temph, flag;
- int temp;
- reset_ds18b20();// 复位操作
- write_byte(0xcc);// 跳过 ROM
- write_byte(0x44);// 温度转换
- delay(300);//***************************
- reset_ds18b20();// 复位操作
- write_byte(0xcc);// 跳过 ROM
- write_byte(0xbe);// 读内部 RAM 内容
- templ=read_byte();
- temph=read_byte();
- flag=(temph&0x80)>>7;// 判断高字节符号位是 1 还是 0(1 为负温度, 0 为正温度)
- if(flag==0)
- //temp=(temph<<=4)+((templ&=0xf0)>>4);
- temp=(templ+temph*256)*0.625;// 将精度 0.0625 扩大 10 倍,因为 temp 为整形,小数部分读不到
- // 此项目需要保留一位小数,所以 x10,小数点后移一位
- // 所以可得要保留几位小数点就扩大 10 的几次方
- else
- temp=(~((templ+temph*256)-1))*(-0.625);
- return temp;}
- /****************** 显示函数 ****************/
- void display(int num)
- {
- uchar i,zf,bai,shi,ge,fen;
- if(num<0)
- {
- zf=0;// 温度 — 符号位
- num=num*(-1);
- }
- else
- zf=1;// 温度 + 符号位
- bai=num/1000;
- shi=num%1000/100;
- ge=num%100/10;
- fen=num%10;
- for(i=0;i<6;i++)
- {
- duan=1;
- switch(i)
- {
- case 0: if(zf==0)
- P0=numfh[zf];
- else
- if(bai!=0)
- P0=numd[bai];
- else
- if(shi!=0)
- P0=numd[shi];
- else
- P0=numdg[ge];
- break;
- case 1: if(zf==0&&shi!=0)
- P0=numd[shi];
- else
- if(zf==0&&shi==0)
- P0=numdg[ge];
- else
- if(zf!=0&&bai!=0)
- P0=numd[shi];
- else
- if(zf!=0&&bai==0&&shi!=0)
- P0=numdg[ge];
- else
- if(zf!=0&&bai==0&&shi==0)
- P0=numd[fen];
- break;
- case 2: if(zf==0&&shi!=0)
- P0=numdg[ge];
- else
- if(zf==0&&shi==0)
- P0=numd[fen];
- else
- if(zf!=0&&bai!=0)
- P0=numdg[ge];
- else
- if(zf!=0&&bai==0&&shi!=0)
- P0=numd[fen];
- else
- if(zf!=0&&bai==0&&shi==0)
- P0=0x63;
- break;
- case 3: if(zf==0&&shi!=0)
- P0=numd[fen];
- else
- if(zf==0&&shi==0)
- P0=0x63;
- else
- if(zf!=0&&bai!=0)
- P0=numd[fen];
- else
- if(zf!=0&&bai==0&&shi!=0)
- P0=0x63;
- else
- if(zf!=0&&bai==0&&shi==0)
- P0=0x39;
- break;
- case 4: if(zf==0&&shi!=0)
- P0=0x63;
- else
- if(zf==0&&shi==0)
- P0=0x39;
- else
- if(zf!=0&&bai!=0)
- P0=0x63;
- else
- if(zf!=0&&bai==0&&shi!=0)
- P0=0x39;
- else
- P0=0x00;
- break;
- case 5: if(zf==0&&shi!=0)
- P0=0x39;else
- if(zf!=0&&bai!=0)
- P0=0x39;
- else
- P0=0x00;
- break;
- }
- duan=0;
- P0=0x00;// 消影
- wei=1;
- P0=numw[i];
- wei=0;
- P1=0x00;// 消影
- delay0(10);
- }
- }
- /****************** 主函数 ****************/
- void main()
- {
- while(1)
- {
- display(read_temper());
- }
- }
复制代码 |