嵌入式设计与开发项目-DS18B20温度传感器程序设计


知识拓展:
①DS18B20是单线接口数字温度传感器,测量范围是-55 ~ +125℃,-10℃ ~ +85℃范围内精度是+0.5℃,测量分辨率为9 ~ 12位(复位值为12位,最大转换时间为750ms)
②DS18B20包括 寄生电源电路64位ROM和单线接口电路暂存器EEPROM8位CRC生成器和温度传感器等。寄生电源电路可以实现外部电源供电和单线寄生供电,64位ROM中存放的48位序列号用于识别同一单线上连接的多个DS18B20,以实现多点测温。
③64位ROM代码的格式为: 8位CRC校验码 + 48位序列号 + 8位系列码(0x28)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、实现的功能

  • ①实时获取DS18B20温度数据并显示到LCD屏幕上面;
  • ②8个LED的流水灯控制,每隔1s点亮一个灯,按以上步骤重复进行;;
  • ③根据传感器获取数据要求编写dsp_read()的流程;

二、根据功能实现代码

1、主文件main.c

#include"key.h"
#include"led.h"
#include"lcd.h"
#include"stdio.h"
#include"ds18b20.h"

unsigned int uiDsb_Val;
unsigned char ucSec , ucSec1;
unsigned char pucStr[21];
unsigned long ulTick_ms;

void DSB_Proc(void);

int main(void)
{
	SysTick_Config(72000);	//定时1ms(HCLK = 72MHz)
	KEY_Init();
	LED_Init();
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	ds18b20_init_x();
	while(1)
	{
		LED_Disp(ucSec);
		DSB_Proc();
	}
}
void DSB_Proc(void)
	{
		if(ucSec != ucSec1)
		{
			ucSec1 = ucSec;
			uiDsb_Val = dsp_read();
			sprintf((char*)pucStr,"  Temp:%5.2fC",uiDsb_Val/16.0);
			LCD_DisplayStringLine(Line5,pucStr);
		}
	}
	
//SysTick 中断处理程序
	void SysTick_Handler(void)
	{
		ulTick_ms++;
		if(ulTick_ms % 1000 ==0)
		ucSec++;
	}
	

	

主函数分析:❤️ ❤️ ❤️

  1. DS18B20返回的16位二进制数uiDsb_Val 代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值
  2. 左移n位等于乘于2n,右移n位等于除于2n 例如:除于16等同于右移4位;

2、DS18B20的头文件“ds18b20.h”

#ifndef __DS18B20_H
#define __DS18B20_H

#include "stm32f10x.h"

#define OW_DIR_OUT() 	mode_output1()
#define OW_DIR_IN() 	mode_input1()
#define OW_OUT_LOW() 	(GPIO_ResetBits(GPIOA,GPIO_Pin_6))
#define OW_GET_IN()  	(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))

#define OW_SKIP_ROM 		0xCC
#define DS18B20_CONVERT 	0x44
#define DS18B20_READ 		0xBE


void ds18b20_init_x(void);
unsigned int dsp_read(void);

#endif


简要分析:❤️ ❤️

  1. 通过宏定义 #define 把函数封装起来,可直接使用;
  2. 包含对于引脚初始化和获取温室数据的函数;

3、DS18B20的源文件“ds18b20.c”



#include "stm32f10x.h"
#include "ds18b20.h"

#define delay_us(X)  delay((X)*72/5)

void delay(unsigned int n)
{
	while(n--);
}

void ds18b20_init_x(void)
{
  	GPIO_InitTypeDef GPIO_InitStructure;
  	/* Enable  clock */
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  , ENABLE);
  
  	/* Configure Ports */
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//
void mode_input1(void )
{
  	GPIO_InitTypeDef GPIO_InitStructure;

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void mode_output1(void )
{
  	GPIO_InitTypeDef GPIO_InitStructure;

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//
uint8_t ow_reset(void)
{ 
	uint8_t err;

   	OW_DIR_OUT(); // pull OW-Pin low for 480us
   	OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite)

   	delay_us(400);	  //about 480us
   
   	// set Pin as input - wait for clients to pull low
   	OW_DIR_IN(); // input

   	delay_us(66);
   	err = OW_GET_IN();		// no presence detect
   	// nobody pulled to low, still high


   	// after a delay the clients should release the line
  	// and input-pin gets back to high due to pull-up-resistor
   	delay_us(480-66);
   	if( OW_GET_IN() == 0 )		// short circuit
      err = 1;

   	return err;
 }

uint8_t ow_bit_io( uint8_t b )
{ 
 	OW_DIR_OUT(); // drive bus low
 	OW_OUT_LOW();	
 	delay_us(1); // Recovery-Time wuffwuff was 1

 	if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up)
	
#define  OW_CONF_DELAYOFFSET  5
 	delay_us(15-1-OW_CONF_DELAYOFFSET);
      
 	if( OW_GET_IN() == 0 ) b = 0;  // sample at end of read-timeslot
	
 	delay_us(60-15);
 	OW_DIR_IN();

 	return b;
}

uint8_t ow_byte_wr( uint8_t b )
{ 	
	uint8_t i = 8, j;
   	do 
    { 
		j = ow_bit_io( b & 1 );
      	b >>= 1;
      	if( j ) b |= 0x80;
    } 
   	while( --i );
   	return b;
}

//
uint8_t ow_byte_rd( void )
{
   	return ow_byte_wr( 0xFF ); 
}

//获取DS18B20温度传感器
unsigned int dsp_read(void)
{
	unsigned char th,tl;
	
	ow_reset();							//复位
	ow_byte_wr(0xCC);					//跳过Rom
	ow_byte_wr(0x44);					//转换温度
	
	ow_reset();
	ow_byte_wr(0xCC);
	ow_byte_wr(0xBE);					//读暂存器
	tl = ow_byte_wr(0xFF);				//读温度值低8位
	th = ow_byte_wr(0xFF);				//读温度值高8位
	return (th<<8) + tl;
}



简要分析:❤️ ❤️

  1. 延时函数us的函数的 *#define delay_us(X) delay((X)72/5) 参数需要添加括号();
  2. 初始化端口可参考蓝桥杯-嵌入式设计与开发项目-LED指示灯程序设计
  3. DS18B20内部电路和时序详细介绍可参考:DS18B20温度传感器原理详解及例程代码
  4. 操作步骤包括:复位ROM命令功能命令

三、实现功能过程的注意与学习点

1、注意点

1.获取到的温度值需要乘于0.625,才能转换为正确地温度值;

2、学习的知识点

  1. 获取到DS18B20温度的传感器的实时数据;
  2. 根据ROM命令表、功能命令表进行获取寄存器的温度数据;
  3. 熟悉DS18B20温度传感器在实战中的应用;

❤️ ❤️ ❤️ ❤️ ❤️ ❤️

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小鹿

博主不差钱,点个赞就行哈哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值