STM32 DS18B20 程序

本文介绍了一种基于STM32微控制器的DS18B20温度传感器驱动程序的设计与实现,详细讲解了初始化配置、读取数据及写入数据的具体过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include"stm32f10x.h"
#include"PinInit.h"
#include"G_OS.h"
#include"Timer.h"

/*--------------------------------------------------------------------------
* 函数名称 : gUINT8 Ds18Init(void)
* 功能描述 : 18B20初始化函数
* 入口参数 : 无
* 出口参数 : 0	初始化成功
			 1	初始化失败
-----------------------------------------------------------*/
gUINT8 Ds18Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;		/*开漏输出,外加上拉双向IO*/
  	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_SetBits(DS18_PORT,DS18_IO); 						/*使初始状态是高电平20us*/
	TimeDelayUs(20);       			
	GPIO_ResetBits(DS18_PORT,DS18_IO);						/*480us<拉低<960us  这里500us*/
	TimeDelayUs(500);				
	GPIO_SetBits(DS18_PORT,DS18_IO);						/*拉高等待ds18应答低电平,时序要求等待15-60us 这里60us 比较保险*/
	TimeDelayUs(60);					

	if(GPIO_ReadInputDataBit(DS18_PORT,DS18_IO) == 0) 		/*读*/
	{			
		TimeDelayUs(240);									/*延时240us把ds18发出的低电平(时序指出:低电平时间60~240us)耽搁过去*/
		if(GPIO_ReadInputDataBit(DS18_PORT,DS18_IO) == 1)
		{
			return 0; 										/*初始化成功*/
		}
	}														/*初始化失败*/
	return 1;
}

/*--------------------------------------------------------------------------
* 函数名称 : gUINT8 Ds18Read(void)
* 功能描述 : 18B20读函数
* 入口参数 : 无
* 出口参数 : 无
-----------------------------------------------------------*/
gUINT8 Ds18Read(void)
{
	gUINT32 CPUStatus;
	gUINT8 i,Temp;
		
	for(i=0;i<8;i++)
	{	
		G_ENTER_CRITICAL();									/*不想让G/OS心跳打断,不可以放到循环外,关中断时间太长,有闪烁感*/
		Temp = Temp>>1;

		GPIO_ResetBits(DS18_PORT,DS18_IO);
		TimeDelayUs(4);										/*时序要求至少1us这里拉低3-4us再拉高产生读时隙*/

		GPIO_SetBits(DS18_PORT,DS18_IO);					/*拉高,等数据*/
		TimeDelayUs(8);									   	/*时序要求从上次拉低算起15us后出数据,这里疑问。。。。。?过大导致读出错误*/

		if(GPIO_ReadInputDataBit(DS18_PORT,DS18_IO))
		{
			Temp |= 0x80;	
		}
		TimeDelayUs(60);  									/*读一位的时间是60us,还要至少1us的恢复时间,这里延时60us*/
		G_EXIT_CRITICAL();									/*注意:这里开中断,有可能切换到其他任务,或者执行Tick中断*/
	}
	return Temp;
}

/*--------------------------------------------------------------------------
* 函数名称 : void Ds18Write(gUINT8 Data)
* 功能描述 : 18B20写函数
* 入口参数 : 无
* 出口参数 : 无
-----------------------------------------------------------*/
void Ds18Write(gUINT8 Data)
{
	gUINT32 CPUStatus;
	gUINT8 i;

	for(i=0;i<8;i++)
	{
		G_ENTER_CRITICAL();	 								/*不想让G/OS心跳打断,不可以放到循环外,关中断时间太长,有闪烁感*/
		if(Data & 0x01)
		{	
			GPIO_ResetBits(DS18_PORT,DS18_IO);			   	/*写1,时序要求拉低至少1us,这里4us*/
			TimeDelayUs(4);
			GPIO_SetBits(DS18_PORT,DS18_IO);
			TimeDelayUs(60);							 	/*写时间是60us + 至少1us恢复时间*/	
		}
		else
		{
			GPIO_ResetBits(DS18_PORT,DS18_IO);			 	/*写0,拉低60us*/
			TimeDelayUs(60);
		}
		Data = Data>>1;
		GPIO_SetBits(DS18_PORT,DS18_IO);					/*最后拉高*/
		TimeDelayUs(5);								  		/*恢复时间至少1us,这里5us*/
		G_EXIT_CRITICAL();									/*注意:这里开中断,有可能切换到其他任务,或者执行Tick中断*/
	}
}



### STM32 DS18B20 示例代码与教程 #### 使用DS18B20温度传感器的初始化过程 为了使STM32能够读取来自DS18B20的数据,需要先完成一系列配置工作。这包括设置GPIO引脚模式以及初始化I²C或单总线通信协议来连接到DS18B20设备[^1]。 ```c // 初始化 GPIO 和 单总线接口 void DS18B20_Init(void){ // 配置 GPIO 引脚作为开漏输出/输入浮空 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` #### 温度数据获取函数实现 当硬件部分准备就绪之后,则可以编写用于启动转换并读回测量结果的功能模块。下面展示了一个简单的例子,它展示了如何发送命令给DS18B20开始一次新的温度采样,并等待直到获得有效数值为止。 ```c float DS18B20_GetTemperature(void){ uint8_t data[9]; float temperature; OneWire_Reset(); /* 复位 */ OneWire_WriteByte(0xCC); /* 跳过 ROM 命令 */ OneWire_WriteByte(0x44); /* 启动转换 */ while(!OneWire_ReadBit()); /* 等待转换结束 */ OneWire_Reset(); OneWire_WriteByte(0xCC); OneWire_WriteByte(0xBE); /* 读寄存器命令 */ for(int i=0;i<9;i++) /* 获取全部九字节数据 */ data[i]=OneWire_ReadByte(); int16_t raw_temp=(data[1]<<8)|data[0]; if(raw_temp&0x8000) /* 如果最高位为1表示负数 */ temperature=((~raw_temp+1)&0xFFFF)*(-0.0625); else /* 正常情况下的计算方式 */ temperature=raw_temp*0.0625; return temperature; } ``` 上述代码片段实现了基本的操作流程,即向传感器发出指令让其执行内部ADC变换操作并将最终得到的结果解析成实际意义上的摄氏度值返回给调用者。 对于调试过程中遇到的具体问题,在`if ((time >= 30) && (time <= 240)) { return TRUE; }`这一行加入断点可以帮助开发者更好地理解程序运行状态和时间参数的影响范围[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值