|
本帖最后由 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();
}
}
|
|