
DS18B20是一种很常用的数字温度传感器,温度检测范围是-55~+125度,手册 说明在-10~+85度范围内检测误差为±0.5度,作者在自己的产品中随机抽样验证 了几只传感器,在-25度误差0.1度,+25度与+50度误差小于0.1度,可见这种传感 器实际精度是很高的,传感器引脚如图19-1所示,工作电压范围是3.0~5.5V,通 常使用+5V,电源接反或接错一般是不会损坏传感器的,对于单只DS18B20的使用,我们按图19-2连接即可。


电路和介绍详见:http://www.51hei.com/bbs/dpj-47286-1.html(在这贴附件中可下载完整的源码压缩包)
主程序如下(部分预览):- /****************《51单片机轻松入门-基于STC15W4K系列》配套例程 *************
- ★★★★★★★★★★★★★★★★★★★★★★★★
- 《51单片机轻松入门-基于STC15W4K系列》 一书已经由北航出版社正式出版发行。
- 作者亲手创作的与教材配套的51双核实验板(2个MCU)对程序下载、调试、仿真方便,不需要外部
- 仿真器与编程器,这种设计方式彻底解决了系统中多个最高优先级谁也不能让谁的中断竞争问题。
- QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
- 验证信息:STC15单片机
- 邮箱:xgliyouquan@126.com
- ★★★★★★★★★★★★★★★★★★★★★★★★*/
- //单只DS18B20的温度检测,测温范围-55 —— +125度,1602液晶显示。
- #include "STC15W4K.H"
- #include "DS18b20.h"
- #include "myfun.h"
- #include "LCD1602.h"
- bit flag; // flag=0表示正温,flag=1表示负温。
- unsigned char str[10]; // 最长字符10字节,比如:-123.4567/0
- unsigned char Long_Str(long dat,unsigned char *str) // 长整型数转换为字符串,返回值为转换后的字符串长度
- {
- signed char i=0;
- unsigned char len = 0;
- unsigned char buf[11]; // 长整数最大值4294967295,转ASCII码后占用10+1=11字节
- if (dat < 0) // 如果为负数,首先取绝对值,并添加负号
- {
- dat = -dat;
- *str++ = '-';
- len++;
- }
- do
- { // 低位在前高位在后顺序排列
- buf[i++] = dat % 10+0x30; // C语言中数组下标固定从0开始
- dat /= 10;
- } while (dat > 0);
- len += i; // i最后的值就是有效字符的个数
- while (i-- > 0) // 高位在前低位在后顺序排列
- {
- *str++ = buf[i] ;
- }
- *str = 0; // 添加字符串结束符方便使用KEIL自带的字符串处理函数处理
- return len; // 返回字符串长度
- }
-
- //****************温度数据处理函数************************/
- void gettemp() //读取温度值
- {
- unsigned int temp0,temp1,temp; // 存放小数、整数、符号,10000倍小数值
- unsigned char temH,temL; // 存放原始高字节与低字节
- unsigned char len; // 温度整数部分字符串长度
- temp=DS18B20_ReadTemperature(); // 从18B20中读取2字节原始温度值
- flag=0;
- if ((temp&0xf800)!=0) // 如果是负温,将补码取反加1变为原码
- {
- temp=~temp +1;
- flag=1;
- }
- temH=temp/256; // 高字节(5位符号+3位数据)
- temL=temp%256; // 低字节(4位整数+4位小数)
-
- temp0=temL&0x0F; // 4 位小数
- temp1=(temH<<4)|(temL>>4); // 8 位整数(最高一位符号0不用管)
-
- len=Long_Str(temp1,str);
- str[len++]='.'; // 添加小数点,覆盖原有字符串结束符0
- temp=temp0*625; // 将结果中的小数乘以分辨温度0.0625
- // 扩大10000倍进行输出,不用浮点,同样可以保留4位小数精度
- str[len++]= temp/1000+48; // 小数点后1位ASCII码
- str[len++]=(temp%1000)/100+48; // 小数点后2位ASCII码
- str[len++]=(temp%100)/10+48; // 小数点后3位ASCII码
- str[len++]= temp%10+48; // 小数点后4位ASCII码
- str[len]= 0; // 添加字符串结束符
- }
- void port_mode() // 端口模式
- {
- P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00;
- P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00;
- }
- void main()
- {
- unsigned char xPos,yPos;
- unsigned char *s="Now temp is:";
- port_mode(); // 所有IO口设为准双向弱上拉方式。
- xPos=0; // xPos表示水平右移字符数(0-15)
- yPos=0; // yPos表示垂直下移字符数(0-1)
- delay100ms(); // 等待LCD1602上电时内部复位
- LCD1602_Init();
- WriteString(xPos,yPos,s); // X坐标、Y坐标、字符串,屏幕左上角为坐标原点
- DS18B20_SetResolution(3); // 设置DS18B20的分辨率为12位(默认值,新器件可以不作任何设置)
- while(1)
- {
- gettemp();
- WriteString(0,1,str);
- SetCur(NoCur); // 有显示无光标
- }
- }
复制代码
lcd1602.h文件
|