程序采用数字温度采集芯片 ds18b20 获取温度 分辨率为12位 可以由此程序获的更低分辨率温度
ds18b20 只有三个i/o接口 其中两个为电源引脚 一个为数据总线
只需要一条口线通信 简化了分布式温度传感应用 无需外部元件 可用数据总线供电
电压范围为3.0 V至5.5 V 无需备用电源 测量温度范围为-55 ° C至+125 ℃
ds18b20 相关介绍:ds18b20 百度百科
Proteus 仿真:
Code:
#include#include #define uchar unsigned char // 宏定义uchar 为无符号字符 #define uint unsigned int sbit DQ=P2^3; sbit alarm =P3^4; //温度告警标志位 sbit test = P1^0; unsigned long temp; //温度值 uchar tempH,tempL,tempSign; //ds18b20 读取的温度高位 和低8位 ,最高上限温度和最低下限温度,温度符号 signed long setMax=10; signed long setMin=-10; float precision=0.0625; //温度精度(默认12位) uchar seg[8]={0}; // eg. -100.0625 // 延时函数 void delay(uint t) //最大65ms 2^16 { /*TMOD = 0x01; //启用T0 计时器 工作方式1 TH0 = (65536 - t )/256; TL0 = (65536 - t )%256; EA = 0; //禁止中断 TR0 = 1; //开始T0计数 while( TF0 == 0); TF0 = 0; // 清除T0 溢出标志位 TR0 = 0; //关闭T0计数*/ while(t--); } // ds18b20 初始化函数 uchar init(void) { uchar feedback; DQ = 0 ; delay(100); DQ = 1; /*while(DQ); //用于获取反馈信号,返回0为成功,返回1为初始化失败 feedback = DQ;*/ delay(25); //return feedback; //返回0复位成功,返回1复位失败 } // 写函数 void write(uchar var) //先输出低位,再输出高位 { uchar i; for(i=8;i>0;i--) { DQ = 0; DQ = var&0x01; // 获取最后一位数据写入数据线 delay(5); //(DQ == 1)? delay(10):delay(70); //延时保证ds18b20 采样。写入为 1 15us 内需释放数据线;写入为 0 至少延时 60us; DQ = 1; var >>= 1; //右移一位 } //delay(5); } // 读函数 uchar read( void ) { //先读取低位,再读取高位 uchar feedback = 0; uchar i; for(i=8;i>0;i--) { DQ = 0; feedback >>= 1; // 右移 DQ = 1; // 数据线拉低15us内 释放数据线 //delay(1); if(DQ){ feedback |= 0x80;} //在feedback 在高位写入1 等待右移处理 delay(5); } return feedback; } // 配置ds18b20 参数说明:(最高温度,最低温度) //暂不可用 void setConfig(char th,char tl) { uchar precision; init(); write(0xcc); write(0x4e); write(th); //默认最高温度为+125 write(tl);//默认最低温度为-55 } // 温度超限报警处理 void warning() { uchar maxSign=0,minSign=0; //最高温度和最低温度符号 if(setMax > 0) { maxSign = 1; } if(setMin > 0) { minSign = 1; } if( temp < labs(setMin)*10000 && tempSign <= minSign ) //小于下限温度 { alarm=0; delay(100); alarm=1; delay(100); }else{ alarm =0; } if( temp > setMax*10000 && tempSign >=maxSign ) //大于上限温度 { alarm=0; delay(100); alarm=1; delay(100); }else{ alarm =0; } } // 温度显示处理,转换 tampH 和 tempL ,写入数组 seg[8], 得出十进制 温度 temp void convert() { uint tempC; //补码温度 uchar seg7; //温度符号位 tempC = tempH*256.0 + tempL; //tempC=tempH<<8; //tempC|=tempL; if(tempC > 0x0800) { seg7 = 0x40; //温度为负温度 tempSign = 0; temp = (~tempC + 1); // 补码求原码,取反加一 temp=temp*precision; }else{ tempSign = 1; seg7 = 0x00; // 温度为正 temp = tempC ; temp=temp*precision*10000; //放大10000倍,用于取余获取各位数值 } //temp = 1234567; seg[7] = seg7; seg[6] = temp/1000000; seg[5] = temp%1000000/100000; seg[4] = temp%1000000%100000/10000; seg[3] = temp%1000000%100000%10000/1000; seg[2] = temp%1000000%100000%10000%1000/100; seg[1] = temp%1000000%100000%10000%1000%100/10; seg[0] = temp%1000000%100000%10000%1000%100%10; } //数码管动态显示 ,读取数组seg[8] void ledShow() { uchar i=0,m,led; uchar tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管 0-9 uchar tabPoint[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //共阴数码管 0-9 带小数点 do{ m=seg[i]; if( i == 4 ) //数码管第四位包含小数点 单片机开发板 数码管和proteus 仿真不同 { led = tabPoint[m]; }else if( i==7 ){ //符号位跳过译码 led = seg[7]; }else{ led = tab[m]; } P2 = i ; //送位码 单片机开发板 数码管和proteus 仿真不同 P0 = led; //送段码 delay(100); i++; warning(); }while(i<8); } //从ds18b20 获取温度,获取 tempH 和 tempL void getTemp() { init(); write(0xCC); //跳过rom搜索 write(0x44); //启动温度转换 delay(100); //温度转换最多750ms init(); write(0xCC); write(0xBE); //读出ds18b20 内部RAM 9直接内容 delay(100); tempL = read(); //读出温度低字节 tempH = read(); //读出温度高字节 //tempMax = read(); //读取高温触发器 //tempMin = read(); //读取低温触发器 } void main() { while(1){ getTemp(); convert(); ledShow(); } }
上一篇:单片机红外接收软件解码
下一篇:单片机课设:六路智能抢答器
推荐阅读最新更新时间:2024-03-16 15:32
设计资源 培训 开发板 精华推荐
- 施耐德电气出席IC China 2019,助力新一代高科技电子厂房建设
- 西门子新Simcenter Madymo模拟汽车碰撞对人体的影响 促进自动驾驶研发
- EnOcean节能无线收发器模块产品可在儒卓力电子商务平台购买
- 康普:Wi-Fi卖的不只是产品,更是品牌
- TI技术文章:低功耗Bluetooth®技术助力实现汽车门禁系统变革
- 特斯拉自研AI芯片性能提升 成本下降20%
- 下一代汽车上将出现的技术:15大技术盘点 (上篇)
- 日本大学制成新型复合薄膜电极 有望实现容量更高的锂离子电池
- 现代摩比斯合作俄罗斯自动驾驶公司 为自动驾驶汽车研发软件模块
- 奥迪将展示数字OLED照明技术 允许定制照明设计并使用外部照明进行通信