DS18B20温度传感器程序设计

本程序对应的开发板为蓝桥杯嵌入式开发板stm32f103rbt6,为中型mcu。DS18B20是单线接口数字温度传感器,具体特征如下图。

 

 

 

DS18B20包括寄生电源电路、64位ROM和单线接口电路、暂存器、EEPROM、8位CRC生成器和温度传感器等。寄生电源电路可以实现外部电源供电和单线寄生供电,64位ROM中存放的48位序列号用于是吧同一单线 上连接的多个DS18b20,以实现多点测温。

64位ROM代码的格式为:

8位CRC校验码+48位序列号+8位系列码(0x28)

其中8位CRC校验码是48位序列号和8位系列码的CRC校验码。

连接:

P4.6(PA6)-P3.6(TDQ)

程序:

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 ); 
}



unsigned char dsb_read(void)
{
  	unsigned char th,t1;

  	ow_reset();
  	ow_byte_wr(0xcc);
  	ow_byte_wr(0x44);
  	

  	ow_reset();
  	ow_byte_wr( 0xcc );
  	ow_byte_wr ( 0xbe );

  	t1=ow_byte_wr(0xff);
	th=ow_byte_wr(0xff);

  	

	return (th<<8)+t1;
}

主程序

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

u32 TimingDelay = 0;

void Delay_Ms(u32 nTime);
unsigned long Tick_Ms;
unsigned char string[20];
unsigned char Sec,Sec1;
unsigned char DSB_Val;
void DSB_Proc(void);


int main(void)
{
  
    STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);
	ds18b20_init_x();

	
	LCD_DisplayStringLine(Line0,"                    ");	
	LCD_DisplayStringLine(Line1,"                    ");	
	LCD_DisplayStringLine(Line2,"                    ");
	LCD_DisplayStringLine(Line3,"                    ");
	LCD_DisplayStringLine(Line4,"                    ");
	LCD_DisplayStringLine(Line5,"                    ");
	LCD_DisplayStringLine(Line6,"                    ");
	LCD_DisplayStringLine(Line7,"                    ");	
	LCD_DisplayStringLine(Line8,"                    ");
	LCD_DisplayStringLine(Line9,"                    ");	
	

  while (1)
  {
	DSB_Proc();

  }
}

void DSB_Proc(void)
{
	if(Sec!=Sec1)
	{
	Sec1=Sec;
	DSB_Val=dsb_read();
	sprintf((char*)string,"Temp :%5.2fC",DSB_Val/16.0);
	LCD_DisplayStringLine(Line6,string);
								  
	
	
	}
}


void SysTick_Handler(void)
{
		TimingDelay--;
		Tick_Ms++;
		if(Tick_Ms%1000==0)Sec++;
}



void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}
																										  

 

<think>好的,用户正在寻找关于DS18B20温度传感器程序设计方法和示例代码。我需要根据提供的引用内容来组织回答。 首先,引用[1]提到了DS18B20的工作流程:初始化、发送温度转换命令、等待转换完成、读取温度数据。这些步骤可以作为程序设计的框架。然后,引用[2]补充了硬件连接、通信协议、初始化配置等关键步骤,说明需要涵盖这些方面。引用[3]中的代码片段展示了如何读取温度和处理负数的情况,这可能是一个具体的示例,可以引用作为代码示例的一部分。 接下来,我需要将程序设计步骤分解清楚,包括初始化、发送指令、读取数据、数据解析等部分。每个步骤需要说明具体操作,比如初始化时需要发送复位脉冲和检测应答脉冲。发送温度转换命令和读取温度命令需要正确的ROM命令,比如0x44和0xBE。数据解析部分需要注意12位数据的处理和符号位的判断,如引用[3]中的代码所示。 然后,示例代码部分需要结合C语言的实现,展示初始化的函数、发送指令的过程、读取温度的函数,以及主循环中的调用逻辑。要注意代码中的注释,解释每一步的作用,比如初始化、发送跳过ROM命令、启动温度转换、延时等待、读取暂存器等。同时,处理负温度的部分需要参考引用[3]中的方法,取反加1,并显示负号。 最后,相关问题的生成需要围绕用户可能感兴趣的方面,比如单线协议的具体实现、提高精度的方法、多传感器并联的处理、常见错误及解决方案,以及温度转换时间的优化。这些问题可以帮助用户进一步深入学习。 需要确保所有数学表达式使用正确的LaTeX格式,比如温度转换公式中的乘以0.0625。代码块使用正确的语法高亮,并解释关键部分。引用标识要正确对应,比如初始化步骤引用[1],数据处理引用[3]。</think>以下是与DS18B20温度传感器程序设计相关的核心步骤和示例代码: ### 一、DS18B20程序设计核心步骤 1. **初始化时序** 发送复位脉冲(480μs低电平),检测传感器的应答脉冲(60-240μs低电平)[^1] ```c void DS18B20_Init() { DQ = 1; Delay(8); DQ = 0; Delay(80); // 复位脉冲 DQ = 1; Delay(14); if(DQ == 0) { // 检测应答 Delay(20); DQ = 1; } } ``` 2. **温度转换指令** 发送跳过ROM命令$0xCC$后,发送温度转换命令$0x44$[^2] ```c void StartConvert() { DS18B20_Init(); WriteByte(0xCC); // 跳过ROM WriteByte(0x44); // 启动温度转换 } ``` 3. **读取温度数据** 发送读取暂存器命令$0xBE$后读取9字节数据[^3] ```c float ReadTemperature() { unsigned char LSB, MSB; DS18B20_Init(); WriteByte(0xCC); // 跳过ROM WriteByte(0xBE); // 读暂存器 LSB = ReadByte(); MSB = ReadByte(); return TempConvert(MSB, LSB); } ``` 4. **数据解析处理** 温度值计算公式: $$Temp = (MSB \ll 8 | LSB) \times 0.0625$$ 注意处理负温度(符号位为1时取反加1)[^3] ```c float TempConvert(unsigned char H, unsigned char L) { int temp = (H << 8) | L; if(temp & 0x8000) { // 负温度处理 temp = ~temp + 1; return -(temp * 0.0625); } return temp * 0.0625; } ``` ### 二、完整示例代码框架 ```c #include <reg52.h> sbit DQ = P1^0; // 单线数据引脚 void main() { while(1) { StartConvert(); // 启动温度转换 Delay(750); // 等待转换完成(12位精度) float temp = ReadTemperature(); Display(temp); // 显示温度值 Delay(2000); } } // 单字节写入函数 void WriteByte(unsigned char dat) { for(int i=0; i<8; i++) { DQ = 0; _nop_(); DQ = dat & 0x01; Delay(5); DQ = 1; dat >>= 1; } } // 单字节读取函数 unsigned char ReadByte() { unsigned char byte = 0; for(int i=0; i<8; i++) { DQ = 0; _nop_(); DQ = 1; _nop_(); if(DQ) byte |= 0x01 << i; Delay(4); } return byte; } ``` ### 三、关键注意事项 1. 时序精度要求严格,建议使用示波器验证延时函数 2. 12位分辨率需要至少750ms转换时间[^2] 3. 多设备并联时需增加ROM匹配流程 4. 建议增加CRC校验保证数据可靠性
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

身在江湖的郭大侠

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值