|
本帖最后由 markjet 于 2017-3-28 19:09 编辑
/*这是DS18B20 数码管显示温度的第五个版本了。
期间参考了好多大神的代码,但都是显示在1602液晶上的,遗憾手上没有,如此就显示在数码管上。
有一段时间老是显示85,我还以为是DS18B20坏了,经过排查最后在延时函数上找到了破绽!
同样的延时函数,大神都是十几个微妙,尔我的才2微妙。所以老是初始化失败P3^7=1; */
#include <stc12c2052ad.h>
#include <intrins.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ = P3^2;
sbit C1 = P3^4; //从1到0再次锁存
sbit C2 = P3^5;
sbit led = P3^7;
uchar Tempvalue;
uchar code table[]=
{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 };
void delayus(uint x) // 2us
{ do{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}while(--x);
}
void delay(uint x)
{
uint i,j;
for(i = x;i>0;i--)
for(j = 114;j>0;j--);
}
//初始化ds18b20
bit ds18b20init(void)
{
bit flag;
DQ = 1;
delayus(1);
DQ = 0; //单片机将数据线拉低为低电平0
delayus(350); //延时720us(时间范围480us-960us之间)
DQ = 1; //单片机将数据线置为高电平1 (释放总线)
delayus(40); //延时等待15us—60us
flag = DQ;
if(flag)
{led = 0;}
delayus(210);
DQ = 1;
return flag;
}
void WriteByte(uchar dat)
{
uchar i;
for(i = 0;i < 8;i++)
{
DQ = 0;
DQ = dat&0x01;
delayus(15);
DQ = 1;
dat = dat>>1;
}DQ = 1;
delayus(20);
}
uchar ReadByte(void)
{
uchar value,i;
DQ = 1;delayus(4);
for(i =0;i<8;i++)
{
DQ = 0;_nop_();
value = value>>1;
DQ = 1;
if(DQ)
value = value | 0x80;
delayus(22);
}DQ = 1;
return value;
}
uchar Readtemp(void)
{
uchar a,b;
ds18b20init();
WriteByte(0xCC);
WriteByte(0x44);
delayus(400);
ds18b20init();
WriteByte(0xCC);
WriteByte(0xBE);
//按顺序读
a = ReadByte(); //低8位
b = ReadByte(); //高8位
b<<=4; //
b+=(a&0xF0)>>4;
return b;
}
void display(void)
{
P1 = 0xFF;
C1=0; C2=1; //个位显示十位不显示
P1=table[Tempvalue%10]; //显示ge位
delay(10);
C1=1;C2=0; //个位不显示十位显示
P1=table[Tempvalue/10]; //显示shi位
delay(10);
}
void main(void)
{
while(1)
{
Tempvalue = Readtemp();
display();
}
}
|
|