如何用cc2530接ds18b20来获取温度数据
答案:1 悬赏:50 手机版
解决时间 2021-10-15 01:21
- 提问者网友:世勋超人
- 2021-10-14 17:16
如何用cc2530接ds18b20来获取温度数据
最佳答案
- 五星知识达人网友:归鹤鸣
- 2021-10-14 17:57
DS18B20是温度传感器,读写数据有一定的时序: 1、写操作 (1) 数据线先置低电平“0”。 (2) 延时确定的时间为15微秒。 (3) 按从低位到高位的顺序发送字节(一次只发送一位)。 (4) 延时时间为45微秒。 (5) 将数据线拉到高电平。 (6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。 (7) 最后将数据线拉高。 2、读操作 (1)将数据线拉高“1”。 (2)延时2微秒。 (3)将数据线拉低“0”。 (4)延时3微秒。 (5)将数据线拉高“1”。 (6)延时5微秒。 (7)读数据线的状态得到1个状态位,并进行数据处理。 (8)延时60微秒。 3、例程 //温度传感器:DS18B20 //显示方式:LED #include <reg51.h> #define uchar unsigned char sbit keyup=P1^0; sbit keydn=P1^1; sbit keymd=P1^2; sbit out=P3^7;//接控制继电器 sbit DQ = P3^4;//接温度传感器18B20 uchar t[2],number=0,*pt;//温度值 uchar TempBuffer1[4]={0,0,0,0}; uchar Tmax=18,Tmin=8; uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7}; uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp; bit flag; void t0isr() interrupt 1 { TH0=(65536-5000)/256; TL0=(65536-5000)%256; switch(number) { case 0: P2=0x08; P0=distab[TempBuffer1[0]]; break; case 1: P2=0x04; P0=distab[TempBuffer1[1]]; break; case 2: P2=0x02; P0=distab[TempBuffer1[2]]&0x7f; break; case 3: P2=0x01; P0=distab[TempBuffer1[3]]; break; default: break; } number++; if(number>3)number=0; } void delay_18B20(unsigned int i) { while(i--); } void Init_DS18B20(void) { bit x=0; do{ DQ=1; delay_18B20(8); DQ = 0; //单片机将DQ拉低 delay_18B20(90); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(14); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败,继续初始化 }while(x); delay_18B20(20); } unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat》=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); } return(dat); } void WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat》=1; } } unsigned char *ReadTemperature(unsigned char rs) { unsigned char tt[2]; delay_18B20(80); Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0x44); //启动温度转换 delay_18B20(80); Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度 tt[0]=ReadOneChar(); //读取温度值低位 tt[1]=ReadOneChar(); //读取温度值高位 return(tt); } void covert1(void)//将温度转换为LED显示的数据 { uchar x=0x00,y=0x00; t[0]=*pt; pt++; t[1]=*pt; if(t[1]&0x080) //判断正负温度 { TempBuffer1[0]=0x0c; //c代表负 t[1]=——t[1]; t[0]=——t[0]; x=t[0]+1; t[0]=x; if(x==0x00)t[1]++; } else TempBuffer1[0]=0x0a;//A代表正 t[1]《=4;//将高字节左移4位 t[1]=t[1]&0xf0; x=t[0];//将t[0]暂存到X,因为取小数部分还要用到它 x》=4;//右移4位 x=x&0x0f;//和前面两句就是取出t[0]的高四位 y=t[1]|x;//将高低字节的有效值的整数部分拼成一个字节 TempBuffer1[1]=(y%100)/10; TempBuffer1[2]=(y%100)%10; t[0]=t[0]&0x0f;//小数部分 TempBuffer1[3]=t[0]*10/16; //以下程序段消去随机误检查造成的误判,只有连续12次检测到温度超出限制才切换加热装置 if(currtemp>Tmin)xiaodou1=0; if(y<Tmin) { xiaodou1++; currtemp=y; xiaodou2=0; } if(xiaodou1>12) { out=0; flag=1; xiaodou1=0; } if(currtemp<Tmax)xiaodou2=0; if(y>Tmax) { xiaodou2++; currtemp=y; xiaodou1=0; } if(xiaodou2>12) { out=1; flag=0; xiaodou2=0; } out=flag; } void convert(char tmp) { uchar a; if(tmp<0) { TempBuffer1[0]=0x0c; a=——tmp+1; } else { TempBuffer1[0]=0x0a; a=tmp; } TempBuffer1[1]=(a%100)/10; TempBuffer1[2]=(a%100)%10; } void keyscan( ) { uchar keyin; keyin=P1&0x07; if(keyin==0x07)return; else if(keymd==0) { dismod++; dismod%=3; while(keymd==0); switch(dismod) { case 1: convert(Tmax); TempBuffer1[3]=0x11; break; case 2: convert(Tmin); TempBuffer1[3]=0x12; break; default: break; } } else if((keyup==0)&&(dismod==1)) { Tmax++; convert(Tmax); while(keyup==0); } else if((keydn==0)&&(dismod==1)) { Tmax--; convert(Tmax); while(keydn==0); } else if((keyup==0)&&(dismod==2)) { Tmin++; convert(Tmin); while(keyup==0); } else if((keydn==0)&&(dismod==2)) { Tmin--; convert(Tmin); while(keydn==0); } xiaodou1=0; xiaodou2=0; } main() { TMOD=0x01; TH0=(65536-5000)/256; TL0=(65536-5000)%256; TR0=1; ET0=1; EA=1; out=1; flag=0; ReadTemperature(0x3f); delay_18B20(50000);//延时等待18B20数据稳定 while(1) { pt=ReadTemperature(0x7f); //读取温度,温度值存放在一个两个字节的数组中 if(dismod==0)covert1(); keyscan(); delay_18B20(30000); } }
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯