单片机+DS18B20温度传感器测温

发布者:Heavenly999最新更新时间:2021-11-24 来源: eefocus关键字:单片机  DS18B20  温度传感器  测温 手机看文章 扫描二维码
随时随地手机看文章

项目描述:

单片机(STC89C52RCA)通过1-wire总线协议控制DS18B20测量当前环境的温度,并将采集回的温度数据实时显示在LCD1602上。测温范围:-55°C ~ 125°C。超过温度范围时会蜂鸣器响起,LED灯闪烁报警。


C语言代码如下:


/*----------------------------

FileName:TempratureMeasure.h

Function: 头文件

Author: Zhang Kaizhou

Date: 2019-6-21 16:21:00

----------------------------*/

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int


/*主模块端口定义*/

sbit start = P3^4; // 启动温度测量

sbit buzzer = P2^3;

sbit led = P1^7;


/*DS18B20测温模块端口定义*/

sbit DQ = P2^2;


/*LCD1602显示模块端口定义*/

sbit lcdrs = P1^0;

sbit lcdrw = P1^1;

sbit lcden = P2^5;


/*主模块函数声明*/

void start18B20();

void getTemprature();

void setAlarmTemprature(uchar tHigh, uchar tLow);

void tempratureAlarming();

void timer0Init();


/*1-wire总线模块函数声明*/

void initResetBus();

void writeByte18B20(uchar dat);

void writeLogic1();

void writeLogic0();

void readByte18B20(uchar * dat);

bit readBit();


/*LCD1602显示模块函数声明*/

void LCDInit();

void display(float dat);

void writeCommand(uchar command);

void writeData(uchar dat);

void delay(uint xms);


/*---------------------------------------------------------------

FileName: main.c

Function: 单片机通过1-wire总线协议控制DS18B20测量当前环境的温度,

并将采集回的温度数据实时显示在LCD1602上。

Description: 测温范围:-55°C ~ 125°C。超过温度范围时会蜂鸣器响起,

LED灯闪烁报警。

Author: Zhang Kaizhou

Date: 2019-6-21 11:26:22

----------------------------------------------------------------*/

#include "TempratureMeasure.h"


/*定义全局变量*/

float temprature = 25; // 存放从18B20温度暂存器中读取的温度数据


/*主函数*/

void main(){

LCDInit();

timer0Init();

// setAlarmTemprature(0x28, 0x14); // 温度上下限设置为20~30摄氏度

start18B20();

while(1){

getTemprature();

display(temprature);

tempratureAlarming();

}

}


///*设置18B20报警温度的上下限*/

//void setAlarmTemprature(uchar tHigh, uchar tLow){

// initResetBus();

// delay(1);

// writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测

// writeByte18B20(0x4e); // 写暂存器指令

// writeByte18B20(tHigh); // 报警温度上限30摄氏度

// writeByte18B20(tLow); // 报警温度下限20摄氏度

//}


/*温度报警函数*/

void tempratureAlarming(){

if(temprature < 20 || temprature > 30){ // 温度上下限为20~30摄氏度

buzzer = 0; // 开启蜂鸣器报警

TR0 = 1; // 启动timer0,LED闪烁报警

}else{

buzzer = 1;

TR0 = 0;

}

}


/*timer0用于LED灯闪烁计时*/

void timer0Init(){

TMOD = 0x01; // timer0 定时模式 16位定时器 非门控启动

TH0 = (65536 - 50000) / 256; // 定时50ms

TL0 = (65536 - 50000) % 256;

ET0 = 1; // 开timer0溢出中断

EA = 1; // 开全局中断

}


/*timer0溢出中断服务程序*/

void timer0Service() interrupt 1{

TH0 = (65536 - 50000) / 256; // 定时50ms

TL0 = (65536 - 50000) % 256;

led = ~led;

}


/*启动18B20开始从环境中获取温度*/

void start18B20(){

initResetBus();

delay(1);

writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测

writeByte18B20(0x44); // 启动18B20开始温度转换

}


/*MCU从18B20的温度暂存器中读取温度*/

void getTemprature(){

uchar tLow, tHigh;

uint result;

initResetBus(); // 复位总线

delay(1);

writeByte18B20(0xcc); // 总线上只有一个18B20, 跳过ROM序列检测

writeByte18B20(0xbe); // 启动18B20开始温度转换

readByte18B20(&tLow); // 读取温度暂存器中的低字节

readByte18B20(&tHigh); // 读取温度暂存器中的低字节

result = tHigh; // 高低字节合并成一个双字节数据

result <<= 8;

result |= tLow;

temprature = result * 0.0625; // 温度寄存器为12bit, 温度分辨率为0.0625

}


/*-----------------------------

FileName: 1-wireBus.c

Function: 单总线操作相关的函数

Author: Zhang Kaizhou

Date: 2019-6-21 16:23:34

-----------------------------*/

#include "TempratureMeasure.h"


/*定义全局变量*/

uint i; // 延时变量


/*1-wire总线初始化(复位)函数*/

void initResetBus(){

DQ = 0; // 主控设备将总线拉低(480us~960us), 使得总线处于初始化状态

i = 103; while(i) i--; // 将总线拉低870us

DQ = 1; // 释放总线并等待(15~60us)接收18B20的应答信号

i = 4; while(i) i--; // 延时等待45us

/*

若总线上存在18B20设备, 在检测到总线上引第8行释放总线而产生的上升沿信号后,

等待15~60us之后会将总线拉低60~240us

*/

// ack = DQ; // 读取18B20的应答信号(若ack = 0, 则总线上存在18B20, 否则无)

// return ack;

}


/*向DS18B20写一个字节数据的函数*/

void writeByte18B20(uchar dat){

bit bitFlag;

uchar i;

for(i = 0; i < 8; i++){

bitFlag = dat & 0x01;

dat >>= 1;

if(bitFlag){ // 写1

writeLogic1();

}else{ // 写0

writeLogic0();

}

}

}


/*向1-wire总线写逻辑1*/

void writeLogic1(){

DQ = 0; // 将总线拉低至少1us声明要进行写操作(产生写时隙)

_nop_(); _nop_(); // 延时2 * 1.09us = 2.18us

DQ = 1; // 从产生写时隙开始在15us之内释放总线

i = 8; while(i) i--; // 延时71us

}


/*向1-wire总线写逻辑0*/

void writeLogic0(){

DQ = 0; // 将总线拉低至少1us声明要进行写操作(产生写时隙)

i = 8; while(i) i--; // 延时71us

DQ = 1; // 从产生写时隙开始要将总线持续拉低至少60us

_nop_(); _nop_();

}


/*从1-wire总线上读取1byte数据*/

void readByte18B20(uchar * dat){

uchar i, temp;

for(i = 0; i < 8; i++){

temp = readBit();

* dat = (temp << 7) | ((* dat) >> 1);

}

}


/*从1-wire总线上读取1bit数据*/

bit readBit(){

bit dat;

DQ = 0; // 将总线拉低大于1us开始进入读总线时段

_nop_();

DQ = 1; // 释放总线

_nop_(); _nop_();

dat = DQ;

i = 8; while(i) i--; // 延时71us

return dat;

}


/*-----------------------------

FileName:display.c

Function: LCD1602显示函数

Author: Zhang Kaizhou

Date: 2019-6-21 16:21:40

------------------------------*/

#include "TempratureMeasure.h"


uchar code table0[] = {"Welcome here"};

uchar code table1[] = {"T:"};

uchar code table2[] = {"0123456789"};

uchar code table3[] = {"'C"};

uchar num = 0;


/*初始化LCD1602的设置*/

void LCDInit(){

uchar i;

lcden = 0; // 拉低使能端,准备产生使能高脉冲信号

writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)

writeCommand(0x0c); // 开显示,不显示光标

writeCommand(0x06); // 写一个字符后地址指针自动加1

writeCommand(0x01); // 显示清零,数据指针清零

/*LCD上电界面*/

writeCommand(0x80); // 将数据指针定位到第一行首

for(i = 0; i < strlen(table0); i++){

writeData(table0[i]);

delay(5);

}

writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首

for(i = 0; i < strlen(table1); i++){

writeData(table1[i]);

delay(5);

}

}


/*LCD显示函数*/

void display(float dat){

uchar i;

writeCommand(0x80 + 0x40 + strlen(table1));

writeData(table2[(uchar)((uchar)(dat / 100))]); // 显示温度的百位

delay(5);

writeData(table2[(uchar)dat % 100 / 10]); // 显示温度的十位

delay(5);

writeData(table2[(uchar)dat % 10]); // 显示温度的个位

delay(5);

writeData('.'); // 显示小数点

delay(5);

writeData(table2[(uchar)(dat * 10) % 10]); // 显示温度的十分位

delay(5);

writeData(table2[(uchar)(dat * 100) % 10]); // 显示温度的百分位

delay(5);

for(i = 0; i < strlen(table3); i++){

writeData(table3[i]);

delay(5);

}

}


/*写指令函数*/

void writeCommand(uchar command){

lcdrs = 0; // 命令选择

lcdrw = 0;

P0 = command;

delay(5);

lcden = 1; // 产生一个正脉冲使能信号

delay(5);

lcden = 0;

}


/*写数据函数*/

void writeData(uchar dat){

lcdrs = 1; // 数据选择

lcdrw = 0;

P0 = dat;

delay(5);

lcden = 1;

delay(5);

lcden = 0;

}


/*延时xms函数*/

void delay(uint xms){

uint i, j;

for(i = xms; i > 0; i--)

for(j = 110; j > 0; j--);

}

关键字:单片机  DS18B20  温度传感器  测温 引用地址:单片机+DS18B20温度传感器测温

上一篇:单片机PWM调光
下一篇:DA转换(IIC总线)

推荐阅读最新更新时间:2024-11-10 09:44

STM32微控制器及ST33安全微控制器出货量分别突破10亿和5亿
意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)宣布其基于ARM Cortex 内核的STM32通用微控制器的出货量突破十亿颗大关。同时,搭载ARM SecurCore SC300处理器的ST33安全微控制器出货量亦突破五亿颗。 意法半导体早期决定使用ARM内核研发STM32系列微控制器的决策已取得了巨大成功,创造出一系列无与伦比的32位微控制器,包括可促进创新的高性能自适应实时加速器及丰富的片上外设。片上外设包括低功耗、高性能的模拟功能及DSP扩展功能等。这些出货量逾十亿的微控制器产品被用于各种不同的应用中,例如工业自动化、消费电子、物联网、移动产品、医疗、健身和穿戴装置。从
[单片机]
单片机ROM,RAM和FLASH的作用
常规上ROM是用来存储固化程序的,RAM是用来存放数据的。由于FLASH ROM比普通的ROM读写速度快,擦写方便,一般用来存储用户程序和需要永久保存的数据。譬如说,现在家用的电子式电度表,它的内核是一款单片机,该单片机的程序就是存放在ROM里的。电度表在工作过程中,是要运算数据的,要采集电压和电流,并根据电压和电流计算出电度来。电压和电流时一个适时的数据,用户不关心,它只是用来计算电度用,计算完后该次采集的数据就用完了,然后再采集下一次,因此这些值就没必要永久存储,就把它放在RAM里边。然而计算完的电度,是需要永久保存的,单片机会定时或者在停电的瞬间将电度数存入到FLASH里。 --ROM存放指令代码和一些固定数值,程序运行后
[单片机]
C51单片机是怎么存储程序和数据的
初学51总是会有这样的疑问,从电脑下载程序到开发板后,程序去哪了? C51中,用户或应用程序,系统程序和数据都是存放在哪的? 51单片机从物理结构上,可分为片内,片外程序存储器,片内片外数据存储器。 51单片机从功能上,有程序存储器,片内数据存储器,特殊功能寄存器,位地址空间,片外数据存储器。 程序存储器 51单片机的程序存储器用于存储代码和一些固定表格常数。 可寻址的程序存储器空间为64KB。 51单片机的从物理角度上可分为:片内,片外程序存储器,作为编址空间,编址规律是:先片内,后片外,片内片外连续,不重叠。 如图:为51单片机程序存储器编址图。 单片机如何执行指令? 如图: 无论片内程序存储器,还是片外程序存储器,他
[单片机]
穿戴产品持续增温 引爆微型MCU应用热潮
穿戴式装置市场持续发烧,根据Cisco研究指出,2015年全球穿戴式应用产品将有250亿美元市场,预料2020年穿戴式市场将呈现倍翻扩展,面对使厂需求骤增,也吸引越来越多晶片业者积极投入适用于穿戴式设备需求设计的微控制器解决方案… 随着穿戴式产品不断翻新,各式新颖造型的穿戴产品推陈出新,目前已有Samsung、Sony、Google、Apple、Qualcomm、Intel、Freescale等国际大厂竞相推出穿戴设备、或是适用于穿戴式装置使用的解决方案,尤其在2014年的CES(Consumer Electronics Show)展中以Wrist Revolution及Fashion Ware两大展区大规模呈现穿戴科技
[物联网]
穿戴产品持续增温 引爆微型<font color='red'>MCU</font>应用热潮
贸泽开售Microchip WBZ350射频就绪多协议MCU模块 简化无线应用开发并加快上市速度
2024年10月18日 – 提供超丰富半导体和电子元器件™的业界知名新品引入 (NPI) 代理商贸泽电子 (Mouser Electronics) 即日起开售Microchip Technology的WBZ350射频就绪多协议MCU模块。 WBZ350模块是PIC32CX-BZ系列的一款安全型32位MCU,内置了蓝牙和Zigbee®无线功能。此射频就绪模块专为需要可靠无线连接的应用而设计,包括用于智能工厂和过程自动化的物联网(IoT)设备、家庭自动化和智能照明系统、具有无线数据控制功能的健康和健身可穿戴设备以及楼宇自动化系统。 Microchip Technology WBZ350射频就绪多协议MCU模块配备64MHz Arm
[半导体设计/制造]
贸泽开售Microchip WBZ350射频就绪多协议<font color='red'>MCU</font>模块   简化无线应用开发并加快上市速度
适用于控制永磁无刷直流电机的嵌入式微控制器
一、 概述 无刷直流电机由电动机主体和驱动器组成,是一种典型的机电一体化产品。电动机的定子绕组多做成三相对称星形接法,同三相异步电动机十分相似。电动机的转子上粘有已充磁的永磁体,为了检测电动机转子的极性,在电动机内装有位置传感器。驱动器由功率电子器件和集成电路等构成,其功能是:接受电动机的启动、停止、制动信号,以控制电动机的启动、停止和制动;接受位置传感器信号和正反转信号,用来控制逆变桥各功率管的通断,产生连续转矩;接受速度指令和速度反馈信号,用来控制和调整转速;提供保护和显示等等。 永磁无刷直流电机(Permanent Magnet Brushless DC Motor以下简称PMBLDC)由于其固有的特点,在家用消费类产品
[单片机]
适用于控制永磁无刷直流电机的嵌入式<font color='red'>微控制器</font>
单片机开发中为什么要用到仿真和仿真机
仿真 是单片机开发过程中非常重要的一个环节,除了一些极简单的任务,一般产品开发过程中都要进行 仿真 ,仿真的主要目的是进行软件调试,当然借助仿真机,也能进行一些硬件排错。一块单片机应用电路板包括单片机部份及为达到使用目的而设计的应用电路,仿真就是利用仿真机来代替应用电路板(称目标机)的单片机部份,对应用电路部份进行测试、调试。仿真有CPU仿真和ROM仿真两种,所谓CPU仿真是指用仿真机代替目标机的CPU,由仿真机向目标机的应用电路部份供给各种信号、数据,进行调试的办法。这种仿真能通过单步运行、连续运行等多种办法来运行程序,并能观察到单片机内部的变化,便于改正程序中的错误。所谓ROM仿真,就是用仿真机代替目标机的ROM,目标机的CP
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved