-- ------ --- - …… 时 & 诫吠 --- -- ------- --
单片机温度采集程序
用一片DS18B20构成测温系统,测量的温度精度达到 0.1度,测 量的温度 的范围在—20度到+ 100度之间,用8位数码管显示 出来。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数 据位有着严 格的时序要求。DS18B20有严格的通信协议来保证各 位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始 化时序、读时序、写时序。所有时序
都是将主机作为主设备,单总
是从主机主动启
线器件作为从设备。而每一次命令和数据的传输都
动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主 机需启动读时序完成数据接收。数据和命令的传输都是低位在先。
DS18B20的读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。 对于DS18B20的读时隙是从主机把单总线拉低之后,在 之内就得释放单总线,以让
15秒
DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
对于DS18B20的写时序仍然分为写 0时序和写1时序两个过 程。 对于DS18B20写0时序和写1时序的要求不同,当要写0时 序时,单总线 要被拉低至少60us,保证DS18B20能够在15us到 45us之间能够正确地采样IO总线上的“ 0 ”电平,当要写1时
-- ------- -- --- 时 & 诫吠 ... ..... ... ...
序时,单总线被拉低之后,在 15us之内就得释 放单总线。
本程序实现温度的采集并且实时在数码管上显示出来。 具体程序如下:
/* --------------------------------------------- 名称:18B20温度传感器 日期:2009.5 修改:无
内容:18B20单线温度检测的应用样例程序
,请将18b20插紧,
然后在数码管可以显示 XX.XC,C表示摄氏度,如显示 25.3C表示当前温度
度
----------------------------------------------- */ #in clude
#in clude
#defi ne uint un sig ned int;
************************************************************** /*
定义端口
*/
**************************************************************
sbit seg 仁 P2A0; sbit seg2=P2Al; sbit seg3=P2A2;
sbit DQ=P1A3;//ds18b20 端口
sfr dataled=0x80;〃 显示数据端口
/**************************************************************** /*
全局变量
*/
**************************************************************
uint temp;
uchar flag_get,co unt,num,minu te,sec ond;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//7段数码管段码表共阳
uchar str[6];
************************************************************** /*
函数声明
*/
************************************************************** void delay1(uchar MS);
un sig ned int ReadTemperature(void); void In it_DS18B20(void);
un sig ned char ReadO neChar(void);
25.3
-- ------ --- --- 时 & 诫吠 --- ---- ---- -----
void Write On eChar( un sig ned char dat);
void delay (un sig ned int i);
/******************************************************************/ /* 主函数
/******************************************************************/ main ()
{
un sig ned char TempH,TempL; TMOD|=0x01;〃定时器设置 TH0=0xef; TL0=0xf0; IE=0x82; TR0=1; P2=0x00; coun t=0; while(1) {
str[5]=0x39;
//显示 C 符号
str[1]=tab[TempH/100]; // 十位温度 str[2]=tab[(TempH0)/10]; // 十位温度
str[3]=tab[(TempH0)]|0x80; // 个位温度,带小数点 str[4]=tab[TempL]; if(flag_get==1)
〃定时读取当前温度
{
temp=ReadTemperature(); if(temp&0x8000)
{
str[O]=Ox4O;〃 负号标志 temp=~temp; // 取反加 1 temp +=1; } else
str[O]=O; TempH=temp>>4; TempL=temp&0x0F;
TempL=TempL*6/10;〃小数近似处理 flag_get=0; } } }
************************************************************** /*
定时器中断
/******************************************************************/
*/
*/
void tim(void) in terrupt 1 usi ng 1〃 中断,用于数码管扫描和温度检测间隔 { TH0=0xef;〃定时器重装值 TL0=0xf0; nu m++; if (num==50)
{num=0;
flag_get=1;〃标志位有效 second++; if(seco nd>=60) {sec on d=0; minu te++; }
}
coun t++; if(coun t==1)
{P2=0;
dataled=str[0];}〃 数码管扫描 if(coun t==2)
{P2=1;
dataled=str[1];} if(coun t==3)
{ P2=2;
dataled=str[2]; }
if(coun t==4)
{ P2=3;
dataled=str[3]; }
if(coun t==5)
{ P2=4;
dataled=str[4]; }
if(coun t==6)
{ P2=5;
dataled=str[5]; coun t=0;}
}
/******************************************************************/ /* 延时函数
/******************************************************************/ void delay(unsigned int i)〃 延时函数 {
*/
-- ------ --- --- 时 & 诫吠 --- ---- ---- -----
while(i--);
}
/******************************************************************/ /* 初始化
/******************************************************************/ void Init_DS18B20(void) {
un sig ned char x=0; DQ = 1; 〃DQ 复位 delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低 delay(80); //精确延时大于480us
DQ = 1; //拉高总线
delay(10); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay(5);
} /******************************************************************/ /* 读一个字节
/******************************************************************/ un sig ned char ReadO neChar(void) {
un sig ned char i=0; un sig ned char dat = 0; for (i=8;i>0;i--) {
DQ = 0; //给脉冲信号 dat>>=1;
DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay(5); }
return(dat); }
/**************************************************************** /* 写一个字节
/**************************************************************** void Write On eChar( un sig ned char dat) { un sig ned char i=0; for (i=8; i>0; i--)
*/
*/
*/