历史上的今天
今天是:2025年10月11日(星期六)
2022年10月11日 | 51单片机基础之DS18B20温度传感器
2022-10-11 来源:csdn
外型:

代码:
main.c 文件
#include "smg.h"
#include "ds18b20.h"
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
u8 i=0;
int temp_value;
u8 temp_buf[6];
ds18b20_init();//初始化DS18B20
while(1)
{
i++;
if(i%50==0)//间隔一段时间读取温度值,间隔时间要大于温度传感器转换温度时间
temp_value=ds18b20_read_temperture()*10;//保留温度值小数后一位
if(temp_value<0)//负温度
{
temp_value=-temp_value;
temp_buf[0]=0x40;//显示负号
}
else
// temp_buf[0]=0x00;//不显示
//temp_buf[1]=gsmg_code[temp_value/1000];//百位
temp_buf[2]=gsmg_code[temp_value%1000/100];//十位
temp_buf[3]=gsmg_code[temp_value%1000%100/10]|0x80;//个位+小数点
temp_buf[4]=gsmg_code[temp_value%1000%100%10];//小数点后一位
temp_buf[5]=0x39; //显示C
smg_display(temp_buf,3);
}
}
ds18b20.c 文件
#include "ds18b20.h"
#include "intrins.h"
/*******************************************************************************
* 函 数 名 : ds18b20_reset
* 函数功能 : 复位DS18B20
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_reset(void)
{
DS18B20_PORT=0; //拉低DQ
delay_10us(75); //拉低750us
DS18B20_PORT=1; //DQ=1
delay_10us(2); //20US
}
/*******************************************************************************
* 函 数 名 : ds18b20_check
* 函数功能 : 检测DS18B20是否存在
* 输 入 : 无
* 输 出 : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
u8 ds18b20_check(void)
{
u8 time_temp=0;
while(DS18B20_PORT&&time_temp<20) //等待DQ为低电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回1
else time_temp=0;
while((!DS18B20_PORT)&&time_temp<20) //等待DQ为高电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回1
return 0;
}
/*******************************************************************************
* 函 数 名 : ds18b20_read_bit
* 函数功能 : 从DS18B20读取一个位
* 输 入 : 无
* 输 出 : 1/0
*******************************************************************************/
u8 ds18b20_read_bit(void)
{
u8 dat=0;
DS18B20_PORT=0;
_nop_();_nop_();
DS18B20_PORT=1;
_nop_();_nop_(); //该段时间不能过长,必须在15us内读取数据
if(DS18B20_PORT)dat=1; //如果总线上为1则数据dat为1,否则为0
else dat=0;
delay_10us(5);
return dat;
}
/*******************************************************************************
* 函 数 名 : ds18b20_read_byte
* 函数功能 : 从DS18B20读取一个字节
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
u8 ds18b20_read_byte(void)
{
u8 i=0;
u8 dat=0;
u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次读取一位,且先读低位再读高位
{
temp=ds18b20_read_bit();
dat=(temp<<7)|(dat>>1);
}
return dat;
}
/*******************************************************************************
* 函 数 名 : ds18b20_write_byte
* 函数功能 : 写一个字节到DS18B20
* 输 入 : dat:要写入的字节
* 输 出 : 无
*******************************************************************************/
void ds18b20_write_byte(u8 dat)
{
u8 i=0;
u8 temp=0;
for(i=0;i<8;i++)//循环8次,每次写一位,且先写低位再写高位
{
temp=dat&0x01;//选择低位准备写入
dat>>=1;//将次高位移到低位
if(temp)
{
DS18B20_PORT=0;
_nop_();_nop_();
DS18B20_PORT=1;
delay_10us(6);
}
else
{
DS18B20_PORT=0;
delay_10us(6);
DS18B20_PORT=1;
_nop_();_nop_();
}
}
}
/*******************************************************************************
* 函 数 名 : ds18b20_start
* 函数功能 : 开始温度转换
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_start(void)
{
ds18b20_reset();//复位
ds18b20_check();//检查DS18B20
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0x44);//转换命令
}
/*******************************************************************************
* 函 数 名 : ds18b20_init
* 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在
* 输 入 : 无
* 输 出 : 1:不存在,0:存在
*******************************************************************************/
u8 ds18b20_init(void)
{
ds18b20_reset();
return ds18b20_check();
}
/*******************************************************************************
* 函 数 名 : ds18b20_read_temperture
* 函数功能 : 从ds18b20得到温度值
* 输 入 : 无
* 输 出 : 温度数据
*******************************************************************************/
float ds18b20_read_temperture(void)
{
float temp;
u8 dath=0;
u8 datl=0;
u16 value=0;
ds18b20_start();//开始转换
ds18b20_reset();//复位
ds18b20_check();
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0xbe);//读存储器
datl=ds18b20_read_byte();//低字节
dath=ds18b20_read_byte();//高字节
value=(dath<<8)+datl;//合并为16位数据
if((value&0xf800)==0xf800)//判断符号位,负温度
{
value=(~value)+1; //数据取反再加1
temp=value*(-0.0625);//乘以精度
}
else //正温度
{
temp=value*0.0625;
}
return temp;
}
ds18b20.h 文件
#ifndef _ds18b20_H
#define _ds18b20_H
#include "smg.h"
//管脚定义
sbit DS18B20_PORT=P3^7; //DS18B20数据口定义
//函数声明
u8 ds18b20_init(void);
float ds18b20_read_temperture(void);
#endif
smg.c 文件
#include "smg.h"
//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*******************************************************************************
* 函 数 名 : delay_10us
* 函数功能 : 延时函数,ten_us=1时,大约延时10us
* 输 入 : ten_us
* 输 出 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
/*******************************************************************************
* 函 数 名 : smg_display
* 函数功能 : 动态数码管显示
* 输 入 : dat:要显示的数据
pos:从左开始第几个位置开始显示,范围1-8
* 输 出 : 无
*******************************************************************************/
void smg_display(u8 dat[],u8 pos)
{
u8 i=0;
u8 pos_temp=pos-1;
for(i=pos_temp;i<8;i++)
{
switch(i)//位选
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据
delay_10us(100);//延时一段时间,等待显示稳定
SMG_A_DP_PORT=0x00;//消音
}
}
smg.h 文件
#ifndef _smg_H
#define _smg_H
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
extern u8 gsmg_code[17];
void smg_display(u8 dat[],u8 pos);
void delay_10us(u16 ten_us);
#endif
运行结果:
下一篇:51单片机基础之继电器
史海拾趣
|
由于CPLD数字设计结构化的趋势,将出现针对CPLD不同层次的IP(Intellectual Property)核。各个IP核可重复利用,可大大提高设计能力和效率。国外各大公司都推出了专门的IP核,我国也迫切需要发展自己的IP核。本文针对I2C的主方式串行扩展通信的特点, ...… 查看全部问答> |
|
LED 的排列方式及LED 光源的规范决定着基本的驱动器要求。LED 驱动器的主要功能就是在一定的工作条件范围下限制流过LED 的电流, 而无论输入及输出电压如何变化。最常用的是采用变压器来进行电气隔离。文中论述了LED 照明设计需要考虑的因素 一、L ...… 查看全部问答> |
|
ARM7 44b0,用ADS1.20编译调试。 代码中定义了这样一个函数device_run,如下。 BOOL device_run(BYTE type) { BYTE setAttributeValue; MAC_ENUM status; ...… 查看全部问答> |
|
各位仁兄: 小弟有项目如下: 基于S3C2416的串口驱动程序,串口芯片16550, 现在有MDD+PDD(中间层)缺少最低层对16550的初始化代码 由于时间关系,现将项目外包 ...… 查看全部问答> |
|
VS2008如何开发WINDOWS CE .NET 4.2的应用程序 我现在手里有一个MOTOROLA MC1000的设备,装的系统是WINDOWS CE .NET 4.2 在网上看了下 说.NET 可以开发移动设备的程序,所以就下了个试了下 我打开VS2008 - 新建 智能设备项目 - 目标平台我选的是 WINDOWS CE - .NET CF 我选的是 CF2.0 写了个T ...… 查看全部问答> |




