单片机中使用DS18B20温度传感器C语言程序文件
C51DS18B20数字温度计C语言
C51--DS18B20数字温度计--C语言#include;#include;#define uint unsigned int#define uchar unsigned charsbit DQ=P2^6;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit lcden=P1^2;void disp(uint a);void init(void);void delay(uint i);uchar ds18b20_init(void);void write_byte(uchar byte);uchar read_byte(void);uint read_ds18b20(void);void delay50us(void);void delayms(uint a);void lcd1602_wr_com(uchar com);void lcd1602_wr_data(uchar dat);void lcd_init(void);uchar code str[]="temperature"; void main(void){init();while(1){disp(read_ds18b20());delayms(50);}}void init(void)uchar i;lcd_init();lcd1602_wr_com(0x80+0x02); //显示的地址for(i=0;i;>;=1; //右移一位DQ=1;}delay(4);}uchar read_byte(void){uchar i,temp;for(i=0;i;>;=1; //右移一位DQ=1; //主机释放信号线_nop_();if(DQ)temp|=0x80; //将读出数据放在最高位,如果是0,信号线会设备继续拉低,1则为高delay(4);}return temp; //返回读出的一字节数据}uint read_ds18b20(void)uchar numh,numl;uint value;if(ds18b20_init()==0) //判断设置是否正常,0为正常{write_byte(0xcc); //跳过ROM序列号读取write_byte(0x44); //启动温度转换if(ds18b20_init()==0) //再次初始化{write_byte(0xcc);//跳过ROM序列号读取write_byte(0xbe);//读温度寄存器numl=read_byte();//读低位数据numh=read_byte();//读高位数据value=numh;value=value;0;i--)for(j=122;j>;0;j--);}void lcd1602_wr_com(uchar com){lcdrs=0;P0=com;delayms(2);lcden=1;delay50us();lcden=0;}void lcd1602_wr_data(uchar dat){lcdrs=1;P0=dat;delayms(2);lcden=1;delay50us();lcden=0;}void lcd_init(void){lcden=0;lcdrw=0;lcd1602_wr_com(0x38); //显示模式设置lcd1602_wr_com(0x0c); //开显示,不显示光标lcd1602_wr_com(0x06); //写字符后地址指针加1,整屏显示不移动lcd1602_wr_com(0x01); //清屏}。
DS18B20 c语言程序
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;
for (i=0; i<8; i++) //8位计数器
{
dat >>= 1;
DQ = 0; //开始时间片
DelayXus(1); //延时等待
DQ = 1; //准备接收
}
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;
for (i=0; i<8; i++) //8位计数器
**************************************/
void DelayXus(BYTE n)
{
while (n--)
{
_nop_();
_nop_();
}
}
/**************************************
void main()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成
我的51单片机之 温度传感器18B20 的C语言和汇编编程
{
TCZ=TCZ%100;//只显示小于 100 的整数温度
}
TC[1]=TCZ/10;
TC[0]=TCZ%10;
}
Hale Waihona Puke }void main() {
LEDCODE=0xFF; LED1=0; while(1) {
ReadTemp(); Disp(); } }
四、汇编程序: ;********************************************************************
温度传感器 18B20 实验
一、功能: 插上 18B20,上电后,数码管显示相应的环境温度。
二、电路图:
三、C 程序: //******************************************************************** //读取 18B20 输出的温度数据(2 位)并在数码管上显示;made by luqichao //********************************************************************
unsigned char Reset(); unsigned char ReadByte(); void WriteByte(unsigned char Data); void ReadTemp(); //延时 void delay(unsigned char n) {
unsigned char i; for(i=0;i<n;i++) { } }
Data>>=1; CLK=0; NOP();NOP();NOP();NOP();NOP();NOP();//6us CLK=1; NOP();NOP();NOP();NOP();NOP();//4us Temp=CLK; if(Temp) {
温度传感器ds18b20(c语言版)函数以及头文件
//读温度值(低位放 tempL;高位放 tempH;) float ReadTemperature(void)
{
float sdate;
unsigned char tempL,tempH;
unsigned int tt;
//*********************** **写一个字节**************************// void WriteOneChar(unsigned char dat);
//读温度值(低位放 tempL;高位放 tempH;) float ReadTemperature(void) ; #endif
if(tempH>0x7f)
//最高位为 1 时温度是负
{ tempL=~tempL;
//补码转换,取反加一
tempH=~tempH+1;
fg=0;
//读取温度为负时 fg=0
}
tt=tempL+tempH*256;
sdate=tt*0.0625;
return sdate;
}
//头文件 #ifndef _ds18b20_h_ #define _ds18b20_h_
void delay(unsigned char i);
//***********************************************************
//
延时子程序
//************************************************************ void delay1ms();
DS18B20温度传感器C程序
DS18B20温度传感器C程序单片机型号:STC89C54RD+, STC89C52RC测试通过。
晶震频率:11.05924使用时只需要修改对应的外部管脚即可。
MAIN.C:#include <reg52.h>#include <intrins.h>sbit IO_18B20 = P3^2; //18B20通讯引脚。
extern void DelayX10us(unsigned char t);extern bit Get18B20Temp(int *temp);extern bit Get18B20Ack();extern bit Start18B20();unsigned char code LedChar[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E}; //数码管编码0-F unsigned char LedBuff[12] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};int temp=1;unsigned char flg;unsigned char T0RH,T0RL;void ConfigTimer0(unsigned int ms) //开内部定时器延时,到时间后触发中断。
{unsigned long tmp;tmp = 11059200 / 12;tmp = (tmp * ms) / 1000;tmp = 65536 - tmp;tmp = tmp + 18;T0RH = (unsigned char)(tmp>>8);T0RL = (unsigned char)tmp;TMOD &= 0xF0;TMOD |= 0x01;TH0 = T0RH;TL0 = T0RL;ET0 = 1;TR0 = 1;}void LedScan() //数码管扫描程序。
应用DS18B20编写的C程序
#include<reg52.h>#include<stdio.h>#define uchar unsigned char#define uint unsigned intsbit ds=P2^2; //温度控制器sbit dula=P2^6; //段锁存器sbit wela=P2^7; //位锁存器sbit relay=P1^0; //继电器sbit key1=P3^4; //设置键sbit key2=P3^5; //加键sbit key3=P3^6; //减键sbit key4=P3^7; //确定键uint num=20; //初始温度值uint temp;float f_temp;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};void relaycontrol(uint actualtemp,uint settemp) //actualtemp 实际温度,settemp 设置温度{if(actualtemp>settemp) //实际温度>设置温度,继电器吸合{relay=1;}else if(actualtemp<(settemp-10)) //实际温度<设置温度,继电器松开{relay=0;}}void delay(uint zms) //延迟函数zms就是z毫秒{uint x,y;for(x=zms;x>0;x--)for(y=110;y>0;y--);}void dsreset() //温度传感器复位{uint i;ds=0; //将数据线拉为低电平0i=100; //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间约为8.72us while(i>0)i--; //保持低电平约870us 资料要求480~960usds=1; //将数据线拉为高电平1i=4;while(i>0)i--; //保持高电平约35us,等待应答脉冲}bit tempreadbit() //温度传感器位读取{uint i;bit dat;ds=0; //将数据线拉为低电平0i++; //保持低电平约8us,资料要求至少保持1usds=1; //将数据线拉为高电平1i++;i++; //延时约16us, 资料要求至少延时15us以上dat=ds;i=8;while(i>0)i--; //延时约64us, 资料要求不低于60usreturn(dat);}uchar tempreadbyte() //温度传感器字节读取{uchar i,j,dat;dat=0;for(i=1;i<=8;i++) //分8次读出8位,首先读出一位给j,然后左移7位,再将dat右移一位,与左移后的j进行按位或后赋值给dat{j=tempreadbit();dat=(j<<7)|(dat>>1);}return(dat); //8次循环后读完一个字节}void tempwritebyte(uchar dat) //温度传感器写字节{uint i;uchar j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01; //将字节末位取出dat=dat>>1; //将字节数据右移一位,等待下次取出if(testb) //对位进行测试,如果为"1",写"1"{ds=0; //将数据线拉为低电平0i++;i++; //保持低电平约16us,资料要求保持15~60usds=1; //将数据线拉高i=8;while(i>0)i--; //延时约64us, 资料要求不低于60us }else //对位进行测试,如果为"0",写"0"{ds=0; //将数据线拉为低电平0i=8;while(i>0)i--; //延时约64us, 资料要求不低于60usds=1;i++;i++;}}}void tempchange() //温度转换{dsreset(); //复位初始化操作delay(1);tempwritebyte(0xcc); //跳过ROM指令tempwritebyte(0x44); //温度转换命令}uint gettemp(){uchar a,b;dsreset(); //复位初始化操作delay(1);tempwritebyte(0xcc); //跳过ROM指令tempwritebyte(0xbe); //读暂存器指令a=tempreadbyte(); //读一个字节b=tempreadbyte(); //再读一个字节temp=b;temp<<=8; //将第二个字节左移8位到头temp=temp|a; //将第一、二个字节合并在一起f_temp=temp*0.0625; //将温度转换为十进制temp=f_temp*10+0.5; //保留小数点后一位return(temp);}void display(uchar we,uchar du) //数码管显示{uchar i;dula=0;P0=table[du];dula=1;dula=0;wela=0;i=0xff;i=i&(~((0x01)<<(we))); //位选择P0=i;wela=1;wela=0;delay(1);}void displaytemp(uint t) //显示温度{uchar i;i=t/100;display(0,i);delay(2);i=t%100/10;display(1,i+10);delay(2);i=t%100%10;display(2,i);}void displayset(uchar num) //温度设置显示{uchar shi,ge;shi=num/10;ge=num%10;dula=1;P0=table[shi];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delay(5);dula=1;P0=table[ge];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delay(5);}uint keyscan() //温度键盘设置{uint x=0,y=0;if(key1==0){delay(10);if(key1==0){x=~x;y=~y;while(!key1);}}while(y){if(key2==0){delay(10);if(key2==0){num++;if(num>=25)num=25;while(!key2);}}if(key3==0){delay(10);if(key3==0){num--;if(num<=15)num=15;while(!key3);}}if(key4==0){delay(10);if(key4==0){y=~y;while(!key4);}}displayset(num);}return(num*10);}void main(){dula=0;wela=0;while(1){keyscan();tempchange();displaytemp(gettemp());relaycontrol(gettemp(),keyscan());}}。
18B20温度传感器C语言编程实例
温度传感器C语言编程实例#include <reg52.h>#include<intrins.h> //含有——nop_();#include <stdio.h> //含有运算#define uchar unsigned char#define uint unsigned intsbit DQ=P3^7;//数据、时钟线uchar duanma[]={0XFC,0X60,0XDA,0XF2,0X66,0XB6,0XBE,0XE0,0XFE,0XF6};uint wendu; //定义温度值存储位置// uchar bdata date; 原来是用来移动数据的float f_num; //因为温度传感器的精度为0.0625所以设一个float行的变量// sbit d=date^0;void delay_ms(uint ms){uchar i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}void delay_us() //25us延时{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/****************************************************** init()初始化复位程序变量i;还有—nop是用来延时的时序:1、2us、0、480us、等待确认;在延时20us、1******************************************************/void init(){uint i;DQ=1;_nop_();DQ=0;delay_us();//1delay_us();//2delay_us();//3delay_us();//4delay_us();//5delay_us();//6delay_us();//7delay_us();//8delay_us();//9DQ=1;i=10;while((i--)&&(DQ==1));i=10;while(i--);DQ=1;}/******************************************************字节写:write_byte变量x用来产生for循环在写的过程中,0和一是分开写的时序:0、15us、把数据植入、45us、1、重复前面、1当进行写数据时0和1是分开写的;但是时序也要分开写;******************************************************/void write_byte(uchar date)//传递过来的参数是操作指令例如:0xcc,0x44;0xbe {uchar x;bit testb;for(x=0;x<8;x++){testb=date&0x01; //数据处理,它的作用是将数据的最低取出一直去完八位date>>=1;//没去一次向左移动一次if(testb){DQ=0;_nop_();_nop_();DQ=1;delay_us();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();DQ=1;delay_us();}else{DQ=0;_nop_();_nop_();DQ=0;delay_us();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();DQ=1;}}DQ=1;}/******************************************************位读程序:这样做的目的是为了把程序写的更有条理性而且程序的类型是bit型的,因此返回值为bit型的时序:0、15us、把数据置入、45us、1******************************************************/bit read_bit(){bit bt;DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_();bt=DQ;return bt;}/****************************************************** 字节读程序:为了将上面的位读程序组合起来变量:shuju是用来将独处的数据存入******************************************************/ uchar read_byte(){uchar n,k,shuju;shuju=0;for(n=0;n<8;n++){k=read_bit();shuju=(k<<7)|(shuju>>1); //这是一个将位数据转换成字节数据,先接受的是低位}delay_us();return shuju;}/******************************************************启动温度转换:在进行对传感器操作之前必须先写入初始化程序先写入跳跃器件地址指令0xcc再写入启动温度转换指令0x44******************************************************/void start(){init();delay_ms(1);write_byte(0xcc);write_byte(0x44);//向18b20写入启动温度转换指令}/******************************************************温度转换及处理程序:他的做用是将温度值读出因为读出0的数据是两个char型数据需要将它转换成一个uint型的这样才能把显示做出来******************************************************/uint wenduchange(){uchar a,b;init(); // 初始化;必须要有的delay_ms(1);write_byte(0xcc);// 向18b20写入跳跃地址指令write_byte(0xbe);//向18b20写入读取温度指令a=read_byte(); //先读低八位b=read_byte();//再读高八位P0=b; //程序标志!检测用wendu=b;wendu<<=8;wendu=wendu|a;f_num=wendu*0.0625; //读出的温度值乘以18b20的精度wendu=f_num*10+0.5;// 保留一位小数,加0.5为了四舍五入f_num=f_num+0.5; // 在设定变量时一定注意F_num的类型为float型return wendu;}/****************************************************** 显示程序:运用的并口显示方式******************************************************/ void display(uint datt){P2=0xfd;P0=duanma[datt/100];delay_ms(5);P2=0xff;P2=0xfb;P0=duanma[datt/10%10];delay_ms(5);P2=0xff;P2=0xf7;P0=duanma[datt%10];delay_ms(5);P2=0xff;}/****************************************************** 主函数:用来把所有的子程序汇集起来!!******************************************************/ void main(){uint date;while(1){start();delay_ms(5);date=wenduchange();display(date);}}。
51单片机与DS18B20测温的C程序——完整版
/*-----------------------------------------------名称:18B20温度传感器修改:无内容:18B20单线温度检测的应用样例程序,请将18b20插紧,然后在数码管可以显示XX.XC,C表示摄氏度,如显示25.3C表示当前温度25.3度------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<math.h>#include<INTRINS.H>#define uchar unsigned char#define uint unsigned int/******************************************************************//* 定义端口*//******************************************************************/sbit seg1=P2^0;sbit seg2=P2^1;sbit seg3=P2^2;sbit DQ=P1^3;//ds18b20 端口sfr dataled=0x80;//显示数据端口/******************************************************************//* 全局变量*//******************************************************************/uint temp;uchar flag_get,count,num,minute,second;uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数码管段码表共阳uchar str[6];/******************************************************************//* 函数声明*//******************************************************************/void delay1(uchar MS);unsigned int ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);void delay(unsigned int i);/******************************************************************//* 主函数*//******************************************************************/main(){unsigned char TempH,TempL;TMOD|=0x01;//定时器设置TH0=0xef;P2=0x00;count=0;while(1){str[5]=0x39; //显示C符号str[1]=tab[TempH/100]; //十位温度str[2]=tab[(TempH%100)/10]; //十位温度str[3]=tab[(TempH%100)%10]|0x80; //个位温度,带小数点str[4]=tab[TempL];if(flag_get==1) //定时读取当前温度{temp=ReadTemperature();if(temp&0x8000){str[0]=0x40;//负号标志temp=~temp; // 取反加1temp +=1;}elsestr[0]=0;TempH=temp>>4;TempL=temp&0x0F;TempL=TempL*6/10;//小数近似处理flag_get=0;}}}/******************************************************************/ /* 定时器中断*/ /******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效second++;if(second>=60){second=0;minute++;if(count==1){P2=0;dataled=str[0];}//数码管扫描if(count==2){P2=1;dataled=str[1];}if(count==3){ P2=2;dataled=str[2];}if(count==4){ P2=3;dataled=str[3];}if(count==5){ P2=4;dataled=str[4];}if(count==6){ P2=5;dataled=str[5];count=0;}}/******************************************************************/ /* 延时函数*/ /******************************************************************/ void delay(unsigned int i)//延时函数{while(i--);}/******************************************************************/ /* 初始化*/ /******************************************************************/ void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(5);/******************************************************************/ /* 读一个字节*/ /******************************************************************/ 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(5);}return(dat);}/******************************************************************/ /* 写一个字节*/ /******************************************************************/ void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}delay(5);}/******************************************************************/ /* 读取温度*/ /******************************************************************/ unsigned int ReadTemperature(void){unsigned char a=0;unsigned int b=0;unsigned int t=0;Init_DS18B20();WriteOneChar(0x44); // 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //低位b=ReadOneChar(); //高位b<<=8;t=a+b;return(t);}。
单片机DS18B20温度计C语言程序
{ dsInit(); //初始化 DS18B20, 无论什幺命令, 首先都要发起初始化 dsWait(); //等待 DS18B20 应答 delay(1); //延时 1ms, 因为 DS18B20 会拉低 DQ 60~240us 作为应答信号 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom writeByte(0x44); //写入温度转换命令字 Convert T } //向 DS18B20 发送读取数据命令 void sendReadCmd() { dsInit(); dsWait(); delay(1);
单片机 DS18B20 温度计 C 语言程序
#include #include #include //要用到取绝对值函数 abs() //通过 DS18B20 测试当前环境温度, 并通过数码管显示当前温度值, 目前显 示范围: -55~ +125 度 sbit wela = P2; //数码管位选 sbit dula = P2; //数码管段选 sbit ds = P2 ; int tempValue; //0-F 数码管的编码(共阳极) unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99, 0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
i = 8; while(i>0) i--; //延时约 64us, 符合写时隙不低于 60us 要求 } else //写 0, 将 DQ 拉低 60us~120us ds = 0; i = 8; while(i>0) i--; //拉低约 64us, 符号要求 ds = 1; i++; i++; //整个写 0 时隙过程已经超过 60us, 这里就不用像写 1 那样, 再延 时 64us 了 } } //向 DS18B20 发送温度转换命令 void sendChangeCmd()
ds18b20测温c程序
#include<reg52.h>#include<intrins.h>#include<ZLG7289.h>#define uint unsigned int#define uchar unsigned charuchar mod,x,dat,m,t;uchar pres_temp[]={9,9,9,9},old_temp[]={0,0,0,0};sbit dq=P3^6;sbit P1_1=P1^1;sbit P1_2=P1^2;sbit P1_5=P1^5;sbit P1_6=P1^6;uint temp;uchar ID[2][8]={0x28,0x08,0x34,0x31,0x02,0x00,0x00,0xac,0x28,0xf3,0xa0,0xd0,0x00,0x00,0x00,0x07}; void delay(uint count){uint i,j;for(i=0;i<count;i++)for(j=0;j<10;j++);}void delayb20(uchar count){uchar i;for(i=0;i<count;i++);}uchar b20_Init(){uchar i;dq=1;delayb20(1);dq=0;delayb20(29);dq=1;delayb20(3);i=dq;delayb20(25);if(i==0)return 1;return 0;}uchar b20_Readbit(void){uchar i;dq=0;dq=1;for(i=0;i<3;i++);return(dq);}uchar b20_Readbyte(void) {uchar i,j,dat;dat=0;for(i=0;i<8;i++){j=b20_Readbit();dat=(j<<7)|(dat>>1);}return(dat);}void b20_Writebyte(uchar dat) {uchar i,j;bit testb;for(j=0;j<8;j++){testb=dat&0x01;dat=dat>>1;if(testb){dq=0;i++;i++;dq=1;for(i=0;i<8;i++);}{dq=0;for(i=0;i<8;i++);dq=1;i++;i++;}}}uint b20_Matchrom(uint num){uint j;b20_Init();if(b20_Init()==1){b20_Writebyte(0x55);for(j=0;j<8;j++)b20_Writebyte(ID[num][j]);return 1;}elsereturn 0;}void b20_temchange(){b20_Init();delay(1);b20_Writebyte(0xcc);b20_Writebyte(0x44);delay(5000);delay(5000);}uint b20_tempget(){float tt;uchar a,b;b20_Writebyte(0xbe);a=b20_Readbyte();b=b20_Readbyte();temp=b;temp<<=8;temp=temp|a;tt=temp*0.0625;temp=tt*10+0.5;return(temp);}void dataconvt(){uint t=b20_tempget();pres_temp[0] = t/ 1000;pres_temp[1] = t % 1000 / 100;pres_temp[2]=t%100/10;pres_temp[3] = t% 10;}void display(uchar p){ uint a;dataconvt();a=pres_temp[0]*1000+pres_temp[1]*100+pres_temp[2]*10+pres_temp[3]; if(p){if(a>305){P1_1=0;P1_2=0;}if(a<295){P1_1=1;P1_2=1;}}else{if(a>305){P1_5=0;P1_6=0;}if(a<295){P1_5=1;P1_6=1;}}t=4*p;if(pres_temp[0]==0)ZLG7289_Hide(0);else if(old_temp[0]!=pres_temp[0]) {x=t;dat= pres_temp[0];ZLG7289_Download(1,x,0,dat);old_temp[0]=pres_temp[0];}if(pres_temp[0]==0&&pres_temp[1]==0) ZLG7289_Hide(1);else if(old_temp[3]!=pres_temp[3] ){x=t+1;dat= pres_temp[1];ZLG7289_Download(1,x,0,dat);}if(old_temp[3]!=pres_temp[3]){x=t+2;dat= pres_temp[2];ZLG7289_Download(1,x,1,dat);x=t+3;dat= pres_temp[3];ZLG7289_Download(1,x,0,dat);old_temp[3]=pres_temp[3];}}void main(){ZLG7289_Init(5);delay(1000);ZLG7289_Reset();delay(1000);while(1){b20_temchange();b20_Matchrom(0);display(0);b20_Matchrom(1);display(1);}}#include<reg52.h>#include<math.h>#include<intrins.h>#include<ZLG7289.h>#define unchar unsigned char#define unint unsigned intunchar pres_temp[]={9,9,9,9},old_temp[]={0,0,0,0}; bit flag=0,dp;unint value;unchar low, high, mod,x,dat,m;sbit ds=P3^6;void delay(unchar i){unchar j, k;for(j = i; j > 0; j--)for(k = 125; k > 0; k--);}void dsInit(){unint i;ds = 0;i = 103;while(i>0) i--;ds = 1;i = 4;while(i>0) i--;flag=ds;}bit readBit(){unint i;bit b;ds = 0;i++;ds = 1;i++; i++;b = ds;i = 8;while(i>0) i--;return b;}unchar readByte(){unint i;unchar j, dat;dat = 0;for(i=0; i<8; i++){j = readBit();dat = (j << 7) | (dat >> 1);}return dat;}void writeByte(unchar dat){unint i;unchar j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;if(b){ds = 0;i++; i++;ds = 1;i = 8; while(i>0) i--;}else{ds = 0;i = 8; while(i>0) i--;ds = 1;i++; i++;}}}void dataconvert(){float t;flag=0;value = high;value <<= 8;value |= low;if(value&0x8000){value=~value;value+=1;flag=1;}t = value * 0.0625;value = t * 10+0.5;if(value>310)P1=0xe7;if(value<290)P1=0xff;pres_temp[0] = value/ 1000;pres_temp[1] = value % 1000 / 100;pres_temp[2]=value%100/10;pres_temp[3] = value % 10;}void display(){if(flag==1){dat=0x40;ZLG7289_Download(2,0,0,dat);}else if(pres_temp[0]==0)ZLG7289_Hide(0);else if(old_temp[0]!=pres_temp[0]) {dat= pres_temp[0];ZLG7289_Download(1,0,0,dat);old_temp[0]=pres_temp[0];}if(pres_temp[0]==0&&pres_temp[1]==0) ZLG7289_Hide(1);else if(old_temp[3]!=pres_temp[3] ) {dat= pres_temp[1];ZLG7289_Download(1,1,0,dat);}if(old_temp[3]!=pres_temp[3]){dat= pres_temp[2];ZLG7289_Download(1,2,1,dat);dat= pres_temp[3];ZLG7289_Download(1,3,0,dat);old_temp[3]=pres_temp[3];}}void main(){ZLG7289_Init(5);delay(100);ZLG7289_Reset();delay(100);while(1){dsInit();delay(1);writeByte(0xcc);delay(1);writeByte(0x44);dsInit();delay(1);writeByte(0xcc);delay(1);writeByte(0xbe);low = readByte() ;high = readByte() ;dataconvert();if(old_temp[3]!=pres_temp[3] ){dat=0x63;ZLG7289_Download(2,4,0, dat);dat=0x0c;ZLG7289_Download(1,5,0, dat);}display();}}。
DS18B20温度传感器详解带c程序
00A2H
+0.5
0000 0000 0000 000
0000H
-0.5
1111 1111 1111 1000
FFF8H
-10.125
1111 1111 0110 1110
FF5EH
-25.0625
1111 1110 0110 1111
FF6FH
-55 执行序列与介绍 3.1 执行序列
duan=1; switch(i) {
case 0: if(zf==0) P1=numfh[zf];
else if(bai!=0) P1=numd[bai]; else if(shi!=0) P1=numd[shi]; else P1=numdg[ge]; break;
case 1: if(zf==0&&shi!=0) P1=numd[shi];
表 3.2 DS18B20 温度/数字对应关系表
温度(℃)
输出的二进制码
对应的十六进制码
+125
0000 0111 1101 0000
07D0H
+85
0000 0101 0101 0000
0550H
+25.0625
0000 0001 1001 0001
0191H
+10.125
0000 0000 1010 0010
uchar x,y; for(x=z;x>0;x--)
for(y=110;y>0;y--); } /******************15us 延时函数****************/ void delay(uint z) {
while(z--); } /******************初始化 DS18B20 函数****************/ void reset_ds18b20() {
DS18B20的c语言程序
c语言程序单总线接6个DS18B20(其实程序只要多余3个即可),。
//将DQ与Vcc之间接入4.7K上拉电阻#include "reg52.h"#include "INTRINS.H"#include "1602.c"#define uchar unsigned char#define uint unsigned int//#define CLEARSCREEN LCD_en_command(0x01) 1602清屏sbit DQ="P1"^0;/*操作命令代码跳过ROM 0xCC发送温度转换0xBE写EEPROM 0x4E*//////////////低层驱动子程序///////////void Init18B20(void); //初始化void Write18B20(uchar ch);//写数据unsigned char Read18B20(void);//读数据void Delay15(uchar n);void Delay10ms(uint delay_num);void Display(void);/////////////////////////////////////code uchar decimalH[]={00,06,12,18,25,31,37,43,50,56,62,68,75,81,87,93}; code uchar decimalL[]={00,25,50,75,00,25,50,75,00,25,50,75,00,25,50,75};uint ResultTemperatureH ,ResultTemperatureLH,ResultTemperatureLL;//整数,小数高位,小数低位uint ResultSignal;//符号位main(){ uint TemH,TemL,delay,k=0;for(; ; ){Init18B20();Write18B20(0xCC);//跳过ROM_nop_();//Write18B20(0x4E);//写EEPROM// Write18B20(0x00);//Th//Write18B20(0x00);//TlWrite18B20(0x7f);//12 bits温度分辨率Init18B20();Write18B20(0xCC);//跳过ROM_nop_();Write18B20(0x44);//发送温度转换指令Delay10ms(25);Delay10ms(25);Delay10ms(25);Delay10ms(25);//等待1s转换Init18B20();Write18B20(0xCC);//跳过ROMWrite18B20(0xBE);//发送温度转换指令TemL="Read18B20"(); //读低位温度值TemH="Read18B20"(); //读高位温度值Delay10ms(2);TemH=(TemH<<4)|(TemL>>4);TemL="TemL"&0x0f; //取低4位if(TemH&0x80){ TemH=~TemH;TemL=~TemL+1;ResultSignal="1"; //负}else ResultSignal="0"; //正ResultTemperatureLH="decimalH"[TemL];ResultTemperatureLL="decimalL"[TemL];ResultTemperatureH="TemH";Display();for(delay=0;delay<60000;delay++);for(delay=0;delay<20000;delay++);}}void Display(void){ uint i,j,q;LCD_init();CLEARSCREEN;LCD_en_command(0x01);delay_nms(2);q="ResultTemperatureH/100";i=(ResultTemperatureH%100)/10;j="ResultTemperatureH-"(i*10+q*100);LCD_write_string(0,LINE1," Jaq1217 18B20 "); if(ResultSignal){ LCD_write_string(0,LINE2," T is:- . "); }else {LCD_write_string(0,LINE2," T is:+ . ");}LCD_write_char(0x07,LINE2,q|0x30);LCD_write_char(0x08,LINE2,i|0x30);LCD_write_char(0x09,LINE2,j|0x30);LCD_write_char(0x0b,LINE2,(ResultTemperatureLH/10)|0x30); LCD_write_char(0x0c,LINE2,(ResultTemperatureLH%10)|0x30); LCD_write_char(0x0d,LINE2,(ResultTemperatureLL/10)|0x30); LCD_write_char(0x0e,LINE2,(ResultTemperatureLL%10)|0x30);}unsigned char Read18B20(void){ unsigned char ch;unsigned char q ;for(q=0;q<8;q++){ch=ch>>1;DQ="0";_nop_();DQ="1";_nop_();_nop_();_nop_();_nop_();if(DQ==1){ch="ch|0x80";}else {ch="ch"&0x7f;}Delay15(3);DQ="1";}return (ch);}void Write18B20(uchar ch){ uchar i;for(i=0;i<8;i++){ DQ="0";Delay15(1);DQ="ch"&0x01;Delay15(3);DQ="1";ch="ch">>1;_nop_();}}void Init18B20(void){ DQ="0";Delay15(33);//至少延时480usDQ="1";Delay15(10);//至少延时100us/*if(DQ==1) return 0; //初始化失败else return 1;DQ=1; Delay15(18); */}void Delay15(uchar n){ do{ _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_();n--;}while(n);}void Delay10ms(uint delay_num){uchar i;while(delay_num--){for(i=0;i<125;i++){;}}}说明:如果你只需要温度部分的,那么LCD部分的,你可以不看,只参考18B20的程序段。
单片机DS18B20温度传感器C语言程序含CRC校验
单片机中使用DS18B20温度传感器C语言程序(参考1)/******************************************************************************** DS18B20 测温程序硬件:AT89S52(1)单线ds18b20接 P2.2(2)七段数码管接P0口(3)使用外部电源给ds18b20供电,没有使用寄生电源软件:Kei uVision 3**********************************************************************************/ #include "reg52.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intsbit ds=P2^2;sbit dula=P2^6;sbit wela=P2^7;uchar flag ;uint temp; //参数temp一定要声明为 int 型uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点数字编码/*延时函数*/void TempDelay (uchar us){ while(us--); }void delay(uint count) //延时子函数{ uint i;while(count){ i=200;while(i>0)i--;count--; } }/*串口初始化,波特率9600,方式1 */void init_com(){ TMOD=0x20; //设置定时器1为模式2TH1=0xfd; //装初值设定波特率TL1=0xfd;TR1=1; //启动定时器SM0=0; //串口通信模式设置SM1=1;// REN=1; //串口允许接收数据PCON=0; //波特率不倍频// SMOD=0; //波特率不倍频// EA=1; //开总中断//ES=1; //开串行中断}/*数码管的显示 */void display(uint temp){ uchar bai,shi,ge;bai=temp/100;shi=temp%100/10;ge=temp%100%10;dula=0;P0=table[bai]; //显示百位dula=1; //从0到1,有个上升沿,解除锁存,显示相应段dula=0; //从1到0再次锁存wela=0;P0=0xfe;wela=1;wela=0;delay(1); //延时约2msP0=table1[shi]; //显示十位dula=1;dula=0;P0=0xfd;wela=1;wela=0;delay(1);P0=table[ge]; //显示个位dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(1); }/*****************************************时序:初始化时序、读时序、写时序。
DS18B20 C语言程序
/**********************êy??1ü??ê?**************************************/
void delay1ms(unsigned char a)
{
unsigned char j;
while(a-- != 0)
{
i=8;
while(i>0)i--;
DQ=1;
i++;
i++;
{
wr_dat(*p);
p++;
delay1ms(1);
}
}
init_play()//初始化显示
{ lcd_init();
wr_com(0x80);
display(str1);
wr_com(0xc0);
display(str2);
}
/******************************ds1820程序***************************************/
tflag=1;
}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue);
}
/*******************************************************************/
void ds1820disp()//温度值显示
for (j = 0; j < 125; j++);
}
}
void disp(temp)
基于51单片机DS18B20温度传感器的C语言程序和电路
基于51单片机DS18B20温度传感器的C 语言程序和电路DS18B2C 在外形上和三极管很像,有三只脚。
电压范围为 3.0 V 至5.5 V 无需备用电源 测量温度 位 温度转换为 12 位数字格式最大值为 750 毫秒 用户可定义的非易失性温度报警设置 应用范围包 敏感系统。
F 面是DS18B20勺子程序,本人用过完全可行的: #include<reg51.h> #include<intrins.h>#define uchar unsigned char #define uint unsigned int sbit DQ=P2A 0;void reset(); void write_byte(uchar val); uchar read_byte(void); void read_temp(); void work_temp(); uchar data temp_data[2]={0x00,0x00};uchar datadisplay[5]={0x00,0x00,0x00,0x00,0x00}; // 对于温度显示值值 uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x0 数部分查表 main() {while(1) {自己添加 ;void delay1(uint t) {for(;t>0;t--); }/////// 温度控制子函数 void reset(){uchar presence=1; while(presence){ while(presence){DQ=1;_nop_();_nop_(); DQ=0;delay1(50); DQ=1; delay1(6);presence=DQ;}delay1(45); presence=~DQ; }//DS18B20//DS18B20 写命令函数 //DS18B20 读 1 字节函数// 温度读取函数 // 温度数据处理函数DQ=1;}void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();DQ=val&0x01;delay1(6);val=val/2;}DQ=1;_nop_();}uchar read_byte(void){uchar i;uchar value=0;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0; _nop_();_nop_();_nop_();_nop_(); DQ=1;_nop_();_nop_();_nop_();_nop_();if(DQ)value|=0x80;delay1(6);}DQ=1;return(value);void read_temp(){reset();write_byte(0xcc);write_byte(0xbe);temp_data[0]=read_byte();temp_data[1]=read_byte();reset();write_byte(0xcc);write_byte(0x44);}void work_temp(){if(temp_data[1]>127){ temp_data[1]=(256-temp_data[1]); temp_data[0]=(256-temp_data[0]); n=1; // 需要前面宏定义}display[4]=temp_data[0]&0x0f; // 低位的低4 位display[0]=ditab[display[4]]; // 小数点后的数值display[4]=((temp_data[0]&0xf0) >> 4)|((temp_data[1]&0x0f)<<4); // 小数display[3]=display[4] / 100; display[1]=display[4] % 100;display[2]=display[1] / 10;display[1]=display[1] % 10;}电路:Bi -ij-F16欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习课件等等打造全网一站式需求。
DS18B20温度传感器的C语言程序
下面是DS18B20的子程序,#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar a;sbit DQ=P2^0;void reset(); //DS18B20复位函数void write_byte(uchar val); //DS18B20写命令函数uchar read_byte(void); //DS18B20读1字节函数void read_temp(); //温度读取函数void work_temp(); //温度数据处理函数uchar data temp_data[2]={0x00,0x00};uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //对于温度显示值值uchar codeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//温度小数部分查表main(){while(1){reset();write_byte(a);read_byte();read_temp();work_temp();}}void delay1(uint t) {for(;t>0;t--);}///////温度控制子函数void reset(){uchar presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_(); DQ=0; delay1(50);DQ=1;delay1(6);presence=DQ;}delay1(45);presence=~DQ;}DQ=1;}void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); DQ=val&0x01; delay1(6);val=val/2;}DQ=1;_nop_();}uchar read_byte(void){uchar i;uchar value=0;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_(); if(DQ)value|=0x80; delay1(6);}DQ=1;return(value);}void read_temp(){reset();write_byte(0xcc);write_byte(0xbe);temp_data[0]=read_byte();temp_data[1]=read_byte();reset();write_byte(0xcc);write_byte(0x44);}void work_temp(){if(temp_data[1]>127){temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);}display[4]=temp_data[0]&0x0f; //低位的低4位display[0]=ditab[display[4]]; //小数点后的数值display[4]=((temp_data[0]&0xf0) >>4)|((temp_data[1]&0x0f)<<4); //小数点前的数值display[3]=display[4] / 100;display[1]=display[4] % 100;display[2]=display[1] / 10;display[1]=display[1] % 10;}。
51单片机与DS18B20测温的C程序——完整版
/*-----------------------------------------------名称:18B20温度传感器日期:2012.8.25修改:无内容:18B20单线温度检测的应用样例程序,请将18b20插紧,然后在数码管可以显示XX.XC,C表示摄氏度,如显示25.3C表示当前温度25.3度------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<math.h>#include<INTRINS.H>#define uchar unsigned char#define uint unsigned int/******************************************************************//* 定义端口*//******************************************************************/sbit seg1=P2^0;sbit seg2=P2^1;sbit seg3=P2^2;sbit DQ=P1^3;//ds18b20 端口sfr dataled=0x80;//显示数据端口/******************************************************************//* 全局变量*//******************************************************************/uint temp;uchar flag_get,count,num,minute,second;uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数码管段码表共阳uchar str[6];/******************************************************************//* 函数声明*//******************************************************************/void delay1(uchar MS);unsigned int ReadTemperature(void);void Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);void delay(unsigned int i);/******************************************************************//* 主函数*//******************************************************************/main(){unsigned char TempH,TempL;TMOD|=0x01;//定时器设置TH0=0xef;TL0=0xf0;IE=0x82;TR0=1;P2=0x00;count=0;while(1){str[5]=0x39; //显示C符号str[1]=tab[TempH/100]; //十位温度str[2]=tab[(TempH%100)/10]; //十位温度str[3]=tab[(TempH%100)%10]|0x80; //个位温度,带小数点str[4]=tab[TempL];if(flag_get==1) //定时读取当前温度{temp=ReadTemperature();if(temp&0x8000){str[0]=0x40;//负号标志temp=~temp; // 取反加1temp +=1;}elsestr[0]=0;TempH=temp>>4;TempL=temp&0x0F;TempL=TempL*6/10;//小数近似处理flag_get=0;}}}/******************************************************************/ /* 定时器中断*/ /******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔{TH0=0xef;//定时器重装值TL0=0xf0;num++;if (num==50){num=0;flag_get=1;//标志位有效second++;if(second>=60){second=0;minute++;}}count++;if(count==1){P2=0;dataled=str[0];}//数码管扫描if(count==2){P2=1;dataled=str[1];}if(count==3){ P2=2;dataled=str[2];}if(count==4){ P2=3;dataled=str[3];}if(count==5){ P2=4;dataled=str[4];}if(count==6){ P2=5;dataled=str[5];count=0;}}/******************************************************************/ /* 延时函数*/ /******************************************************************/ void delay(unsigned int i)//延时函数{while(i--);}/******************************************************************/ /* 初始化*/ /******************************************************************/ void Init_DS18B20(void)unsigned char x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(5);}/******************************************************************/ /* 读一个字节*/ /******************************************************************/ 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(5);}return(dat);}/******************************************************************/ /* 写一个字节*/ /******************************************************************/ void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;delay(5);}/******************************************************************//* 读取温度*//******************************************************************/ unsigned int ReadTemperature(void){unsigned char a=0;unsigned int b=0;unsigned int t=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //低位b=ReadOneChar(); //高位b<<=8;t=a+b;return(t);}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机中使用DS18B20温度传感器C语言程序(参考1)/********************************************************************************DS18B20 测温程序硬件:AT89S52(1)单线ds18b20接P2.2(2)七段数码管接P0口(3)使用外部电源给ds18b20供电,没有使用寄生电源软件:Kei uVision 3**********************************************************************************/ #include "reg52.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned intsbit ds=P2^2;sbit dula=P2^6;sbit wela=P2^7;uchar flag ;uint temp; //参数temp一定要声明为int 型uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //带小数点数字编码/*延时函数*/void TempDelay (uchar us){while(us--);}void delay(uint count) //延时子函数{uint i;while(count){i=200;while(i>0)i--;count--;}}/*串口初始化,波特率9600,方式1 */void init_com(){TMOD=0x20; //设置定时器1为模式2 TH1=0xfd; //装初值设定波特率TR1=1; //启动定时器SM0=0; //串口通信模式设置SM1=1;// REN=1; //串口允许接收数据PCON=0; //波特率不倍频// SMOD=0; //波特率不倍频// EA=1; //开总中断//ES=1; //开串行中断}/*数码管的显示*/void display(uint temp){uchar bai,shi,ge;bai=temp/100;shi=temp%100/10;ge=temp%100%10;dula=0;P0=table[bai]; //显示百位dula=1; //从0到1,有个上升沿,解除锁存,显示相应段dula=0; //从1到0再次锁存P0=0xfe;wela=1;wela=0;delay(1); //延时约2ms P0=table1[shi]; //显示十位dula=1;dula=0;P0=0xfd;wela=1;wela=0;delay(1);P0=table[ge]; //显示个位dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(1);}/*****************************************时序:初始化时序、读时序、写时序。
所有时序都是将主机(单片机)作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
初始化时序:复位脉冲存在脉冲读;1 或0时序写;1 或0时序只有存在脉冲信号是从18b20(从机)发出的,其它信号都是由主机发出的。
存在脉冲:让主机(总线)知道从机(18b20)已经做好了准备。
******************************************//*--------------------------------------------------------------------------------------------------------------------初始化:检测总线控制器发出的复位脉冲和ds18b20的任何通讯都要从初始化开始初始化序列包括一个由总线控制器发出的复位脉冲和跟在其后由从机发出的存在脉冲。
初始化:复位脉冲+存在脉冲具体操作:总线控制器发出(TX)一个复位脉冲(一个最少保持480μs 的低电平信号),然后释放总线,进入接收状态(RX)。
单线总线由5K 上拉电阻拉到高电平。
探测到I/O 引脚上的上升沿后DS1820 等待15~60μs,然后发出存在脉冲(一个60~240μs 的低电平信号)。
具体看18b20 单线复位脉冲时序和1-wire presence detect "的时序图-------------------------------------------------------------------------------------------------------------------*/void ds_reset(void){ds=1;_nop_(); //1usds=0;TempDelay(80); //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里延//时约530us总线停留在低电平超过480μs,总线上的所有器件都将被复位。
_nop_();ds=1; //产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查18b20中文资料TempDelay(5); //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,//存在检测高电平时间:15~60us,所以延时44us,进行1-wire presence detect(单线存在检测)_nop_();_nop_();_nop_();if(ds==0)flag=1; //detect 18b20 successelseflag=0; //detect 18b20 failTempDelay(20); //存在检测低电平时间:60~240us,所以延时约140us_nop_();_nop_();ds=1; //再次拉高总线,让总线处于空闲状态/**/}原理解释:控制器对18B20 操作流程:1 ,复位:首先我们必须对DS18B20 芯片进行复位,复位就是由控制器(单片机)给DS18B20 单总线至少480uS 的低电平信号。
当18B20 接到此复位信号后则会在15~60uS 后回发一个芯片的存在脉冲。
2 ,存在脉冲:在复位电平结束之后,控制器应该将数据单总线拉高,以便于在15~60uS 后接收存在脉冲,存在脉冲为一个60~240uS 的低电平信号。
至此,通信双方已经达成了基本的协议,接下来将会是控制器与18B20 间的数据通信。
/*----------------------------------------读/写时间隙:DS1820 的数据读写是通过时间隙处理位和命令字来确认信息交换。
------------------------------------------*/bit ds_read_bit(void) //读一位{bit dat;ds=0; //单片机(微处理器)将总线拉低_nop_(); //读时隙起始于微处理器将总线拉低至少1usds=1; //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据_nop_();_nop_(); //小延时一下,读取18b20上的数据,因为从ds18b20上输出的数据//在读"时间隙"下降沿出现15us内有效dat=ds; //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效TempDelay(10); //所有读"时间隙"必须60~120us,这里77usreturn(dat); //返回有效数据原理:图8读时间隙时控制时的采样时间应该更加的精确才行,读时间隙时也是必须先由主机产生至少1uS 的低电平,表示读时间的起始。
随后在总线被释放后的15uS 中DS18B20 会发送内部数据位,这时控制如果发现总线为高电平表示读出“1 ”,如果总线为低电平则表示读出数据“0 ”。
每一位的读取之前都由控制器加一个起始信号。
注意:如图8 所示,必须在读间隙开始的15uS 内读取数据位才可以保证通信的正确。
在通信时是以8 位“0 ”或“ 1 ”为一个字节,字节的读或写是从高位开始的,即A7 到A0. 字节的读写顺序也是如图2 自上而下的。
uchar ds_read_byte(void ) //读一字节{uchar value,i,j;value=0; //一定别忘了给初值for(i=0;i<8;i++){j=ds_read_bit();value=(j<<7)|(value>>1); //这一步的说明在一个word文档里面??}return(value); //返回一个字节的数据}void ds_write_byte(uchar dat) //写一个字节{uchar i;bit onebit; //一定不要忘了,onebit是一位for(i=1;i<=8;i++){onebit=dat&0x01;dat=dat>>1; //由低到高传送数据if(onebit) //写1{ds=0;_nop_();_nop_(); //看时序图,至少延时1us,才产生写"时间隙"ds=1; //写时间隙开始后的15μs内允许数据线拉到高电平TempDelay(5); //所有写时间隙必须最少持续60us}else //写0{ds=0;TempDelay(8); //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64usds=1;_nop_();_nop_();}}}/*****************************************主机(单片机)控制18B20完成温度转换要经过三个步骤:每一次读写之前都要18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18b20进行预定的操作。
复位要求主CPU将数据线下拉500us,然后释放,当ds18B20受到信号后等待16~60us,后发出60~240us的存在低脉冲,主CPU收到此信号表示复位成功******************************************//*----------------------------------------进行温度转换:先初始化然后跳过ROM:跳过64位ROM地址,直接向ds18B20发温度转换命令,适合单片工作发送温度转换命令------------------------------------------*/void tem_change(){ds_reset();delay(1); //约2msds_write_byte(0xcc);//单线情况下,跳跃ROM指令ds_write_byte(0x44);//温度转换指令}/*----------------------------------------获得温度:------------------------------------------*/uint get_temperature(){float wendu;uchar a,b;ds_reset();delay(1); //约2msds_write_byte(0xcc);ds_write_byte(0xbe);//发送读温度命令a=ds_read_byte();//读出温度低8位b=ds_read_byte();//读书温度高8位temp=b;temp<<=8;temp=temp|a;wendu=temp*0.0625; //得到真实十进制温度值,因为DS18B20//可以精确到0.0625度,所以读回数据的最低位代表的是//0.0625度temp=wendu*10+0.5; //放大十倍,这样做的目的将小数点后第一位//也转换为可显示数字,同时进行一个四舍五入操作。