单片机DS18B20数字温度计设计 - 图文 下载本文

void delay_DS(uchar z) {

for(;z>0;z--); }

void init_DS() //DS18B20初始化函数 { reset_DS(); }

uchar reset_DS() //DS18B20复位函数 { uchar reset; dq=1; delay_DS(1); //高电平稍作延时 dq=0; delay_DS(50); //下拉数据线500us左右 dq=1; delay_DS(3); //释放数据线30us左右 reset=dq; delay_DS(25); return(reset); }

void write_byte(uchar dat) //向单总线上写入一个字节 { uchar i; for(i=0;i<8;i++) { dq=0; dq=dat&0x01; //提取出最低位(每次只能发一位) delay_DS(5); //延时50us左右 dq=1; //数据线拉高 dat=dat>>1; //右移一位,准备发送下一位 } delay_DS(5); }

uchar read_byte() //从单总线上读取一个字节 { uchar i, value=0; for(i=0;i<8;i++) { value=value>>1;

30

dq=0; dq=1; delay_DS(1); if(dq==1) value=value|0x80; delay_DS(6); //延时60us左右,等待DS18B20完成一个读时序 } return(value); }

void read_temp() //读DS18B20温度函数 {

reset_DS(); write_byte(0xcc); //跳过ROM write_byte(0x44); //启动温度转换 reset_DS(); write_byte(0xcc); //跳过ROM write_byte(0xbe); //读内部RAM中内容 low_temp=read_byte(); //读温度低字节 high_temp=read_byte(); //读温度高字节 }

void convert_temp() //温度转换函数 { temp=high_temp*256+low_temp; if(high_temp>0xf8) //判断温度是否为负数 { flag=1; temp=(~temp)+1; } temp=temp*0.0625; //计算温度数值 bai=temp/100; //计算温度百位数 shi=temp/10; //计算温度十位数 ge=temp; //计算温度个位数 xs=(low_temp&0x0f)*10*0.0625;//温度低字节的低四位代表的是小数值(0.0625*16=1) }

/*************************温度检测*******************************/ void test_temp() {

uchar tem,a,b; if(flag==1) a=-1; else a=1;

31

tem=a*(bai*100+shi*10+ge); if(temp>=high_test_temp||temp

/*************************按键检测*******************************/ void delay() { uchar u,d; for(u=0;u<200;u++) for(d=0;d<200;d++) {} }

void test_aj() { if(high_test_temp_up==0) { delay(); high_test_temp++; } else if(high_test_temp_down==0) { delay(); high_test_temp--; } else if(low_test_temp_up==0) { delay(); low_test_temp++; } else if(low_test_temp_down==0) { delay(); low_test_temp--; } }

/*************************主函数*******************************/ void main()

32

{ init_1602(); init_DS(); display1(); for(j=0;j<30;j++)for(i=0;i<30000;i++); wc51r(0x01); //清屏 delay5ms(); display2(); for(j=0;j<30;j++)for(i=0;i<30000;i++); wc51r(0x01); //清屏 delay5ms(); while(1) { bj=1; //在新的一次测温开始,蜂鸣器无效 flag=0; //在新的一次测温开始,flag清零 test_aj(); //检测有没有按键按下想要修改温度报警限 read_temp(); //读DS18B20温度 convert_temp(); //转换温度 display0(); //显示温度 test_temp(); //检测温度 } //为了实时检测温度,因此每次测温结束不用延时 }

33