关于18B20
时间:10-02
整理:3721RD
点击:
程序可以运行,用的数码管是串行YL-2 晶振11MHZ 但就是温度显示出来的数值不正确。
附上程序。求各位大神帮帮忙
- #include <AT89x51.H>
- #define uchar unsigned char
- uchar xsm=0;
- unsigned int tcount;
- static unsigned char second,minute;
- uchar code xsfseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xa7};
- uchar code xssegbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
- uchar xsdisbuf[8]={0,0,0,0,0,0,0,0};
- sbit DQ=P2^7; //数据传输线接单片机的相应的引脚
- uchar tempL=0; //临时变量低位(无符号字符变量)
- uchar tempH=0; //临时变量高位
- unsigned int tempa; //温度值(整型变量)
- void DS18_delay(int useconds)//延时函数
- {
- int s;
- for (s=0; s<useconds;s++);
- }
- void xssdata(void)
- {unsigned char xsb=0,xsc,xsnum;
- if(xsm!=8)
- {
- if(xsb==0)
- {
- xsb++;
- xsnum=xssegbit[xsm];
- for(xsc=0;xsc<8;xsc++)
- {P3_2=0;
- P3_3=xsnum&0x80;
- xsnum<<=1;
- P3_2=1;
- }
- }
- if(xsb==1)
- {
- xsb--;
- if(xsm==2)
- { xsnum=xsfseg[xsdisbuf[xsm]]-0x80;}
- else
- {xsnum=xsfseg[xsdisbuf[xsm]];}
- for(xsc=0;xsc<8;xsc++)
- { P3_2=0;
- P3_3=xsnum&0x80;
- xsnum<<=1;
- P3_2=1;
- }
- xsm++;
- }
- }
- if(xsm==8)
- {xsm=0;
- }
- }
- //数据传输//
- //延时0.1ms个单位//
- void delay (unsigned char xsh)
- { while(xsh--);
- }
- //延时0.1ms个单位//
- //数据输出//
- void xsout(void)
- {P3_4=0;
- delay(40);
- P3_4=1;
- }
- //数据输出//
- //按键控制//
- unsigned char Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ=0; //发送复位脉冲
- DS18_delay(29); //延时(>480ms)
- DQ=1; //拉高数据线
- DS18_delay(3); //等待(15~60ms) 等待存在脉冲
- x=DQ; //获得存在信号(用于判断是否有器件)
- DS18_delay(25); // 等待时间隙结束
- return(x); //返回存在信号,0 = 器件存在, 1 = 无器件
- }
- ReadOneChar(void)//读一个字节
- {
- unsigned char i=0;
- unsigned char dat=0;
- for (i=8;i>0;i--)
- {
- DQ=1;
- DS18_delay(1);
- DQ=0;
- dat>>=1;//复合赋值运算,等效dat=dat>>1(dat=dat右移一位后的值)
- DQ=1;
- if(DQ)
- dat|=0x80;
- DS18_delay(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)//有参函数,功能是"写",而写的内容就是括号内的参数
- {
- unsigned char i=0;
- for(i=8;i>0;i--)
- {
- DQ=0;
- DQ=dat&0x01;
- DS18_delay(5);
- DQ=1;
- dat>>=1;//复合赋值运算,等效dat=dat>>1(dat=dat右移一位后的值)
- }
- delay(4);
- }
- unsigned int ReadTemperature(void)//返回读取的温度.
- {
- Init_DS18B20(); //初始化,调用初始化函数
- WriteOneChar(0xcc); //跳过读序列号的操作,调用写函数,写0xcc指令码(跳过读序列号)
- WriteOneChar(0x44); //启动温度转换,调用写函数,写0x44指令码(启动温度转换)
- DS18_delay(125); //转换需要一点时间,延时
- Init_DS18B20(); //初始化,调用初始化函数
- WriteOneChar(0xcc); //跳过读序列号的操作,调用写函数,写0xcc指令码(跳过读序列号)
- WriteOneChar(0xbe); //调用写函数,写0xbe指令码,读温度寄存器(头两个值分别为温度的低位和高位)
- tempL=ReadOneChar(); //读出温度的低位LSB
- tempH=ReadOneChar(); //读出温度的高位MSB
- //tempa=tempL*0.625+0.5; //温度转换,扩大100返回
- // DS18_delay(20);
- tempH<<=8; //高八位右移8位
- tempH=tempH|tempL; //合并
- tempa=tempH*0.625+0.5; //得到真实温度
- //tempa=tempL+tempH;
- //t=b;
- //t<<=8;
- //t=t|a;
- //tt=t*0.0625; //将温度的高位与低位合并
- // t= tt*10+0.5; //对结果进行4舍5入
- return(tempa);//运算结果返回到函数
- }
- void xsbcon(void)
- {
- unsigned int temp;
- temp=ReadTemperature()>>1;
- xsdisbuf[0]=10;
- xsdisbuf[1]=(temp/100)%10;
- xsdisbuf[2]=(temp/10)%10;
- xsdisbuf[3]=temp%10;
- }
- void main()
- {
- TMOD=0x02;
- TH0=0x06;
- TL0=0x06;
- TR0=1;
- ET0=1;
- EA=1;
- xsbcon(); //温度送入缓冲区
- while(1)
- {
- if(second==1)
- {
- ET0=0;
- EA=0;
- xsbcon();
- second=0;
- ET0=1;
- EA=1;
- }
- xssdata(); //将缓冲区数据送去寄存器
- xsout();
- }
- }
- void t0(void) interrupt 1 using 0
- {
- tcount++;
- if(tcount==4000)
- {
- tcount=0;
- second++ ;
- }
- }
自己解决了这个问题,要考虑使用芯片是18B20还是1820,一个是输出12位有效一个是9位有效。