📄 18b20.c
字号:
//延时子程序****************************************************************************************
void delay(unsigned int i)
{ while(i--);}
void beep( bit i)
{ Beep=i;}
//读温度*********************************************************************************************
ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的*作
WriteOneChar(0x44); //启动温度转换
delay(125); //转换需要一点时间,延时
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的*作
WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
tempL=ReadOneChar(); //读出温度的低位LSB
tempH=ReadOneChar(); //读出温度的高位MSB
temperature=(tempH*256)+tempL; //温度转换,把高低位做相应的运算转化为实际温度
return(temperature);
}
//DS18B20初始化程序********************************************************************************************
Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ先置高
delay(8); //稍延时
DQ=0; //发送复位脉冲
delay(85); //延时(>480us)
DQ=1; //拉高数据线
delay(14); //等待(15~60us)
x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
delay(20);
}
//读一个字节*****************************************************************************************
ReadOneChar(void) //主机数据线先从高拉至低电平1ms以上,再使数据线升为高电平,从而产生读信号
{unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1ms以上的高电平恢复期
unsigned char dat=0;
for (i=8;i>0;i--) //一个字节有8位
{DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);}
return(dat);}
//写一个字节*************************************************************************************
WriteOneChar(unsigned char dat)
{ unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15ms之内将所需写的位送到数据线上,
for(i=8;i>0;i--) //在15~60ms之间对数据线进行采样,如果是高电平就写1,低写0发生。
{DQ=0; //在开始另一个写周期前必须有1ms以上的高电平恢复期。
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;}
delay(4);}
//键盘扫描程序**************************************************************************************
unsigned char getkey()
{
P2=0xff;
P2=0xfe;
if ((P2&0xff)!=0xfe)
{
delay(5000);
if((P2&0xff)!=0xfe)
return P2;
else P2=0xfd;
}
else P2=0xfd;
if ((P2&0xff)!=0xfd)
{
delay(5000);
if ((P2&0xff)!=0xfd)
return P2;
else P2=0xfb;
}
else P2=0xfb;
if ((P2&0xff)!=0xfb)
{
delay(5000);
if ((P2&0xff)!=0xfb)
return P2;
else P2=0xf7;
}
else P2=0xf7;
if ((P2&0xff)!=0xf7)
{
delay(5000);
if ((P2&0xff)!=0xf7)
return P2;
else return P2=0xfe;
}
}
Inter0_process() interrupt 2 //外部中断1
{
unsigned char key;
int i;
unsigned char dis=0x01;
unsigned int j;
for(j=5000;j>0;j--)
{
key = getkey(); //取键值
if (key == 0xee) //如1键按下温值递增
{ warning++;
delay(8000);
}
if (key==0xed)
{ //5按下递减
warning--;
delay(8000);
}
if(key==0x77) //16键退出中断
j=1;
for(i=0;i<2;i++) //设置两位报警值在LED上显示
{
P1=dis;
dis<<=1;
if(i==0)
P0=tab[warning%10];
else
P0=tab[warning/10];
delay(200);
}
dis=0x01;
}
}
//主程序***********************************************************************************************
main()
{
unsigned char i,npos=0x01;
P0=0xff;
P2=0xff;
P1=0xff;
EX1=1; //开中断一
IT1=1; //下降沿触发
ET1=1;
EA=1; //开总中断
while(1)
{
if((temperature&0xf000)==0xf000) //判断是否是负温度
{
ReadTemperature();
for(i=0;i<4;i++) //四位显示
{
negtemper=(~temperature)+1; //取原码
Dispbuf(negtemper); //取位值
P1=npos;
npos<<=1; //循环使能
if(i==1) //第二位显示有点
{
P0=tab1[dispbuf[i]]; //查表显示
delay(700);
}
else if(i==3) //显示负号
P0=0xbf;
else
{
P0=tab[dispbuf[i]];
delay(700);
}
}
npos=0x01;
}
else //如不是负温度
{
for(i=0;i<3;i++) //为负则显示三位
{
ReadTemperature(); //读温值
Dispbuf(temperature);
if(((temperature>>4)&0xff)>=warning) //温值大于报警温值则报警
beep(on); //蜂鸣器响
else beep(off); //不响
P1=npos;
npos<<=1; //循环显示
if(i==1)
P0=tab1[dispbuf[i]];
else
P0=tab[dispbuf[i]];
delay(100);
}
npos=0x01;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -