本人现在在做基于STM32的DS18B20的测温,但是一直不成功。就拿初始化来说,按照时序图是先给低电平480us或以上,再给15us的高电平,然后就放开总线,18B20就开始复位。我的初始化程序时要看18B20有没有复位完成。但是我用示波器来看的时候前面给的开始信号是正确的,但是后面读18B20的复位输出的时候,18B20一直处于高电平.......为什么呢?
- char ds18b20_Reset(void)
- {
- uint8_t count = 0,i = 0;
- GPIO_Out_Config();
- DQ_L;
- Delay_us(480);
- DQ_H;
- Delay_us(15);
- GPIO_In_Config();//IPU模式能读数,但是一直为1,18b20可能坏了
- Delay_us(10);
- while(count < 100)
- {
- i = DQ_Read;
- if(i == 1)
- {
- NOP();
- count++;
- }
- else
- break;
- }
- if(count >= 100)
- return 0;
- else
- count = 0;
- while(count <240)
- {
- i = DQ_Read;
- if(i ==0)
- {
- NOP();
- count++;
- }
- break;
- }
- if(count >= 240)
- return 0;
- else
- return 1;
- }
复制代码 以上是初始化的,GPIO的输出模式是PP推挽,GPIO的输入模式是IPU上拉输入;
求大神指点一二啊
单片机是STM32F103ZET的,现在经过修改后,能读出数据,但是高八位要么全0,要么全1;低八位总是全0。而且18b20复位完成后,不发送任何指令,直接读数据口,读出来的有时是1,有时是0。根据时序图,复位完成后,数据口应该是一直高电平才对。
完整的程序如下:
- #include "stm32_18b20.h"
- void ds18b20_Config(void)
- {
- unsigned char Init_Flag;
- Init_Flag = ds18b20_Reset();
- if(Init_Flag)
- printf("\r\n 1 \r\n");//复位成功
- else
- {
- printf("\r\n -1 \r\n");//复位失败
- while(1);
- }
- }
- void ds18b20_WriteCmd(uint8_t cmd)
- {
- uint8_t i, ch;
- GPIO_Out_Config();
- for(i = 0; i < 8; i++)
- {
- ch = cmd;
- ch = ch & 0x01;
- cmd = cmd >> 1;
-
- DQ_L;
- Delay_us(15);//起始15us低电平
- if(ch)//写入1
- {
- DQ_H;
- NOP();NOP();NOP();NOP();NOP();
- DQ_L;
- Delay_us(65);
- }
- else//写入0
- {
- DQ_L;
- Delay_us(65);
- DQ_H;
- NOP();NOP();NOP();NOP();NOP();
- }
- }
- }
- uint8_t ds18b20_ReadData(void)
- {
- uint8_t i,s = 0, dat = 0, data = 0;
- ds18b20_Config();
- for(i = 0; i < 8; i++)
- {
- data = data >> 1;
- DQ_L;
- NOP();
- DQ_H;
- Delay_us(12);//放开总线
- s = DQ_Read;
- if(s)
- dat = 1;
- else
- dat = 0;
- Delay_us(45);
- s = 0;
- data = data | (dat << 7);
- }
- return data;
- }
- char ds18b20_Reset(void)
- {
- uint8_t count = 0,i = 0;
- GPIO_Out_Config();
- DQ_L;
- Delay_us(480);//复位信号
- DQ_H;
- Delay_us(15);//释放总线
- while(count < 100)
- {
- i = DQ_Read;
- if(i == 1)
- {
- Delay_us(1);
- count++;
- }
- else
- break;
- }
- if(count >= 100)
- return 0;
- else
- count = 0;
- while(count <240)
- {
- i = DQ_Read;
- if(i ==0)
- {
- Delay_us(1);
- count++;
- }
- break;
- }
-
- if(count >= 240)
- return 0;
- else
- {
- Delay_us(750);
- i = DQ_Read;
- printf("\r\n i = %d\r\n ",i);
- return 1;
- }
- }
- void ds18b20_TransCmd(void)
- {
- ds18b20_Config();
- ds18b20_WriteCmd(0xcc);//1100 1100
- ds18b20_WriteCmd(0x44);//0100 0100
- }
- void ds18b20_ReadCmd(void)
- {
- ds18b20_Config();
- ds18b20_WriteCmd(0xcc);//1100 1100
- ds18b20_WriteCmd(0xbe);//1011 1110
- }
- float ds18b20_GetTemp(void)
- {
- uint8_t tempH = 0, tempL = 0, temp = 0;
- float tem = 0;
- ds18b20_TransCmd();
- Delay_ms(1000);
-
- ds18b20_ReadCmd();
- tempL = ds18b20_ReadData();
- tempH = ds18b20_ReadData();
- // printf("\r\n 0x%d \r\n", tempH);
- // printf("\r\n 0x%d \r\n", tempL);
-
- temp = (tempH << 8) + tempL;
- tem =temp * 0.0625;
- printf("\r\n tem %f \r\n", tem);
- return tem;
- }
- void NOP(void)
- {
- uint8_t i = 1;
- i--;
- }
复制代码 用示波器看过延时程序的实现是正确的。复位函数里的复位信号给的也是正确的。
电路图里左边是电源线,中间是数据线,右边是地线
|
《DS18B20.c》
#include "stm32f0xx_hal.h"
#include "tim.h"
#include "DS18B20.h"
/*
微秒级延时用函数
*/
void Delay_us(uint16_t nus)
{
__HAL_TIM_SetCounter(&htim17, 0);
__HAL_TIM_ENABLE(&htim17);
while(__HAL_TIM_GetCounter(&htim17) < (48 * nus));
/* Disable the Peripheral */
__HAL_TIM_DISABLE(&htim17);
}
/*
复位DS18B20
*/
void DS18B20_Rst()
{
DS18B20_IO_OUT_SET(); //
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); //拉低DQ
Delay_us(500);
//拉低500us
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); //DQ = 1
Delay_us(30);
}
/*
等待DS18B20的响应
返回1:未检测到DS18B20的存在
返回0:存在
*/
uint8_t DS18B20_Check(void)
{
uint8_t retry = 0;
DS18B20_IO_IN_SET();
while(HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin) && (retry < 200))
{
retry++;
Delay_us(1);
}
if(retry >= 200)
return 1;
else
retry = 0;
while(!HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin) && (retry < 240))
{
retry++;
Delay_us(1);
}
if(retry >= 240)
return 1;
return 0;
}
/*
从DS18B20读取一个位
返回值:1/0
*/
uint8_t DS18B20_Read_Bit(void)
{
uint8_t data = 0;
DS18B20_IO_OUT_SET();//推挽输出设置
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); //DQ = 0
Delay_us(2);
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); //DQ
= 1
DS18B20_IO_IN_SET(); //输入上拉
Delay_us(12);
if(HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin))
data = 1;
else
data = 0;
Delay_us(50);
return data;
}
/*
从DS18B20读取一个字节
返回值:读取到的数据
*/
uint8_t DS18B20_Read_Byte(void) //read one byte
{
uint8_t i,j,dat;
dat = 0;
for(i = 1;i <= 8;i++)
{
j = DS18B20_Read_Bit();
dat = (j << 7) | (dat >> 1);
}
return dat;
}
/*
写一个字节到DS18B20
dat:要写入的字节
*/
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;
DS18B20_IO_OUT_SET();//推挽输出设置
for(j = 1;j <= 8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if(testb)
{
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET);
//DQ = 0 write 1
Delay_us(2);
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET);
//DQ = 1
Delay_us(60);
}
else
{
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET);
//DQ = 0 write 0
Delay_us(60);
HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET);
//DQ = 1
Delay_us(2);
}
}
}
/*
开始温度转换
*/
void DS18B20_Start(void) //ds18b20 start convert
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);//skip rom
DS18B20_Write_Byte(0x44);//convert
}
/*
设置为9位精度
*/
void DS18B20_Comfig2(void) //
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);//skip rom
DS18B20_Write_Byte(0x4e);//write
}
/*
初始化DS18B20的IO口DQ同时检测DS的存在
返回1:不存在
返回0:存在
*/
//uint8_t DS18B20_init(void)
//{
// ;
//}
/*
从DS18B20得到温度值
精度:0.5摄氏度
返回值:温度值
*/
uint16_t DS18B20_Get_Temp(void)
{
uint8_t temp;
uint8_t i = 0;
uint8_t TL,TH;
uint16_t tem;
#ifdef CONFIG_DS18B20
uint8_t FD,FH,RG;
#endif
#ifdef CONFIG_DS18B20
DS18B20_Comfig2();
DS18B20_Write_Byte(100);
DS18B20_Write_Byte(0);
DS18B20_Write_Byte(0x1f);
// DS18B20_Start();
#endif
DS18B20_Rst();
i = DS18B20_Check();
if(i == 1)
return 0xffee;
DS18B20_Write_Byte(0xcc);//skip rom
DS18B20_Write_Byte(0xbe);//read data
TL = DS18B20_Read_Byte();//LSB
TH = DS18B20_Read_Byte();//MSB
#ifdef CONFIG_DS18B20
FD = DS18B20_Read_Byte();
FH = DS18B20_Read_Byte();
RG = DS18B20_Read_Byte();
printf("RG = %X\r\n",RG);
#endif
if(TH > 7)
{
TH = ~TH;
TL = ~TL;
temp = 0; //温度为负
}
else
temp = 1; //温度为正
tem = TH; //获得高8位
tem <<= 8;
tem += TL;//获得低8位
tem = (float)(tem >> 3) * 0.5 *100;//转换
if(temp)
return tem; //返回温度值
else
return -tem;
}
《DS18B20.h》
#ifndef __DS18B20_H
#define __DS18B20_H
#define DS18B20_IO_OUT_SET() //{DS18B20_GPIO_Port->MODER &= 0xFFFFFFF3;GPIOF->MODER |= 1 << 2;GPIOF->PUPDR &= 0xFFFFFFF3;} //输出推挽 其余设置 默认
#define DS18B20_IO_IN_SET() //{DS18B20_GPIO_Port->MODER &= 0xFFFFFFF3;GPIOF->PUPDR &= 0xFFFFFFF3;GPIOF->PUPDR |= 1 << 2;} //设置输入上拉
//#define CONFIG_DS18B20 //设置DS18B20的 分辨率
/*
开始温度转换
*/
void DS18B20_Start(void); //ds18b20 start convert
/*
从DS18B20得到温度值
精度:0.5摄氏度
返回值:温度值
*/
uint16_t DS18B20_Get_Temp(void);
/*
微秒级延时用函数
*/
void Delay_us(uint16_t nus);
#endif
《gpio.c》
/**
******************************************************************************
* File Name : gpio.c
* Description : This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
*
* COPYRIGHT(c) 2016 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOF_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
/*Configure GPIO pins : PAPin PAPin PAPin PAPin
PAPin */
GPIO_InitStruct.Pin = CD4053_Pin|C_S1_Pin|C_S2_Pin|C_S3_Pin
|C_S4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PA7 */
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = DS18B20_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(DS18B20_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
《tim.c》
/**
******************************************************************************
* File Name : TIM.c
* Description : This file provides code for the configuration
* of the TIM instances.
******************************************************************************
*
* COPYRIGHT(c) 2016 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim14;
TIM_HandleTypeDef htim16;
TIM_HandleTypeDef htim17;
/* TIM14 init function */
void MX_TIM14_Init(void)
{
htim14.Instance = TIM14;
htim14.Init.Prescaler = 0;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 65535;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
HAL_TIM_Base_Init(&htim14);
}
/* TIM16 init function */
void MX_TIM16_Init(void)
{
htim16.Instance = TIM16;
htim16.Init.Prescaler = TIM16_PSC;
htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
htim16.Init.Period = 65535;
htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
htim16.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim16);
}
/* TIM17 init function */
void MX_TIM17_Init(void)
{
htim17.Instance = TIM17;
htim17.Init.Prescaler = 0;
htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
htim17.Init.Period = 65535;
htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
htim17.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim17);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM14)
{
/* USER CODE BEGIN TIM14_MspInit 0 */
/* USER CODE END TIM14_MspInit 0 */
/* Peripheral clock enable */
__TIM14_CLK_ENABLE();
/* USER CODE BEGIN TIM14_MspInit 1 */
/* USER CODE END TIM14_MspInit 1 */
}
else if(htim_base->Instance==TIM16)
{
/* USER CODE BEGIN TIM16_MspInit 0 */
/* USER CODE END TIM16_MspInit 0 */
/* Peripheral clock enable */
__TIM16_CLK_ENABLE();
/* USER CODE BEGIN TIM16_MspInit 1 */
/* USER CODE END TIM16_MspInit 1 */
}
else if(htim_base->Instance==TIM17)
{
/* USER CODE BEGIN TIM17_MspInit 0 */
/* USER CODE END TIM17_MspInit 0 */
/* Peripheral clock enable */
__TIM17_CLK_ENABLE();
/* USER CODE BEGIN TIM17_MspInit 1 */
/* USER CODE END TIM17_MspInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM14)
{
/* USER CODE BEGIN TIM14_MspDeInit 0 */
/* USER CODE END TIM14_MspDeInit 0 */
/* Peripheral clock disable */
__TIM14_CLK_DISABLE();
/* USER CODE BEGIN TIM14_MspDeInit 1 */
/* USER CODE END TIM14_MspDeInit 1 */
}
else if(htim_base->Instance==TIM16)
{
/* USER CODE BEGIN TIM16_MspDeInit 0 */
/* USER CODE END TIM16_MspDeInit 0 */
/* Peripheral clock disable */
__TIM16_CLK_DISABLE();
/* USER CODE BEGIN TIM16_MspDeInit 1 */
/* USER CODE END TIM16_MspDeInit 1 */
}
else if(htim_base->Instance==TIM17)
{
/* USER CODE BEGIN TIM17_MspDeInit 0 */
/* USER CODE END TIM17_MspDeInit 0 */
/* Peripheral clock disable */
__TIM17_CLK_DISABLE();
/* USER CODE BEGIN TIM17_MspDeInit 1 */
/* USER CODE END TIM17_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
评分
查看全部评分
如果时序没有问题,很有可能是你延时没有正确造成的,要么就是你拿的器件有问题,可以换一个18B20看看,我上传部分我的代码,你参考一下;
/****************************************************************************************
Include file
****************************************************************************************/
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "DS18B20.h"
#include "DS18B20_hal.h"
/****************************************************************************************
全局变量定义
****************************************************************************************/
/****************************************************************************************
函 数 名:static void DS18B20RccInit(void)
参数描述:
返回值描述:无
特殊算法:无
注意事项:
****************************************************************************************/
static void DS18B20RccInit(void)
{
RCC->BitAPB2ENR.IOPCEN = 1;
RCC->BitAPB2ENR.AFIOEN = 1;
}
/****************************************************************************************
函数名:static void SetDQPortOutput(void)
函数功能:设DQ为输出模式
参数描述:
返回值描述:无
特殊算法:无
注意事项:
****************************************************************************************/
static void SetDQPortOutput(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//配置LED的管脚为开漏输出
GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_PIN; //DQ试制电路板PC0,(原PA1)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO_Mode_Out_PP;GPIO_Mode_AF_PP
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
}
/****************************************************************************************
函数名:static void SetDQPortInput(void)
函数功能:设DQ为输入模式
参数描述:
返回值描述:无
特殊算法:无
注意事项:
****************************************************************************************/
static void SetDQPortInput(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin =DS18B20_DQ_PIN; //DQ(PA1)
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING; // GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS18B20_DQ_PORT, &GPIO_InitStructure);
}
/****************************************************************************************
函 数 名:static void DS12B20TimInit()
函数功能:定时器初始化配置
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static void DS18B20TimInit()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//计数频率 72000000/72 = 1MHz
TIM_TimeBaseStructure.TIM_Prescaler = 72-1; //时钟预分频数
TIM_TimeBaseStructure.TIM_Period = 1; //arr 设置自动重装载寄存器 arr 1MHz 1us溢出时间
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //采样不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(DS18B20_TIM, &TIM_TimeBaseStructure);
TIM_ClearFlag(DS18B20_TIM, TIM_FLAG_Update); //清除溢出标志
}
/****************************************************************************************
函 数 名:static void DS18B20_5us(void)
函数功能:定时器延时5*byDelay个us
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static void DS18B20_5us(uint8_t byDelay)
{
TIM_SetCounter(DS18B20_TIM, 0); //清计数器
TIM_SetAutoreload(DS18B20_TIM, 5*byDelay); //设置自动重载,定时器计时==5ms*byDelay;
TIM_Cmd(DS18B20_TIM, ENABLE);
while(TIM_GetFlagStatus(DS18B20_TIM, TIM_FLAG_Update) == RESET)
{
;
}
TIM_ClearFlag(DS18B20_TIM,TIM_FLAG_Update); //清除溢出标志
TIM_Cmd(DS18B20_TIM, DISABLE);
}
/****************************************************************************************
函 数 名:static void Init_DS18B20(void)
函数功能:
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static uint8_t Init_DS18B20(void)
{
uint8_t byCount = 0;
SetDQPortOutput();
DS18B20_DQ_H; //DQ= 1复位
DS18B20_5us(12);
DS18B20_DQ_L; //DQ= 0
DS18B20_5us(120); //延时600微秒(该时间的时间范围可以从480到960微秒)
DS18B20_DQ_H;
DS18B20_5us(1);
SetDQPortInput();
while((GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN)) && (byCount < 200))
{
byCount ++;
DS18B20_5us(1);
}
DS18B20_5us(80);
SetDQPortOutput();
DS18B20_DQ_H;
DS18B20_5us(1);
return byCount;
}
/****************************************************************************************
函数名:void Ap3156Open(void)
函数功能:初始化Ap3156管脚电平
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
void DS18B20_Open(void)
{
DS18B20RccInit();
RCC->BitAPB1ENR.TIM2EN = 1;
DS18B20TimInit();
TIM_ClearITPendingBit(DS18B20_TIM, TIM_IT_Update);
TIM_ClearFlag(DS18B20_TIM, TIM_FLAG_Update);
TIM_Cmd(DS18B20_TIM, DISABLE);
Init_DS18B20();
}
/****************************************************************************************
函数名:void WriteOneChar(void)
函数功能:写一个字节
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static void WriteOneChar(unsigned char dat)
{
SetDQPortOutput();
for(uint8_t i=8; i>0; i--)
{
if(dat&0x01) //写1
{
DS18B20_DQ_L;
DS18B20_5us(1);
DS18B20_DQ_H;
DS18B20_5us(16);
}
else //写0
{
DS18B20_DQ_L;
DS18B20_5us(18);
DS18B20_DQ_H;
DS18B20_5us(1);
}
dat>>=1;
}
}
/****************************************************************************************
函数名:void ReadOneChar(void)
函数功能:读一个字节
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static unsigned char ReadOneChar(void)
{
unsigned char dat = 0;
for(uint8_t ii=8; ii > 0; ii--)
{
SetDQPortOutput();
DS18B20_DQ_L;
for(uint8_t i = 0;i < 100; ++i);
DS18B20_DQ_H;
dat>>=1;
SetDQPortInput();
for(uint8_t i = 0;i < 20; ++i); //75,50
if(GPIO_ReadInputDataBit(DS18B20_DQ_PORT, DS18B20_DQ_PIN))
{
dat |= 0x80;
}
SetDQPortOutput();
DS18B20_DQ_H;
DS18B20_5us(15);
}
return(dat);
}
/****************************************************************************************
函数名:short Read18B20(void)
函数功能:读18B20温度
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
static short Read18B20(void)
{
uint8_t byDataL=0;
uint8_t byDataH=0;
short Temperature = 0;
if(!(Init_DS18B20() < 200)) //初始化失败
if(!(Init_DS18B20() < 200))
return 4000;
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
if(!(Init_DS18B20() < 200)) //初始化失败
if(!(Init_DS18B20() < 200))
return 4000;
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
byDataL = ReadOneChar(); //读低8位
byDataH = ReadOneChar(); //读高8位
DS18B20_5us(10);
Temperature = (short)((byDataH << 8) | byDataL);
return (Temperature * 5 / 8 - 10); //*0.625,1摄氏度校准
}
/****************************************************************************************
函数名:void ReadTemperature(void)
函数功能:读18B20温度
参数描述:
返回值描述:
特殊算法:
注意事项:
****************************************************************************************/
short ReadTemperature(void)
{
short Temperature1 = 0;
short Temperature2 = 0;
Temperature1 = Read18B20();
DS18B20_5us(200);
Temperature2 = Read18B20();
if((Temperature1 < Temperature2 - 10)||(Temperature1 > Temperature2 + 10))
{
Temperature1 = Read18B20();
DS18B20_5us(200);
Temperature2 = Read18B20();
if((Temperature1 < Temperature2 - 10) || (Temperature1 > Temperature2 + 10))
{
Temperature1 = Read18B20();
DS18B20_5us(200);
Temperature2 = Read18B20();
if((Temperature1 < Temperature2 - 10) || (Temperature1 > Temperature2 + 10))
return 4000;
}
}
return (Temperature1 + Temperature2)/2;
}
STM32F103 DQ不用改变输入输出,只要初始化设置为推挽输出,外接上拉电阻,本人用PB8跟PB10作为DQ是可以的,正点原子例程改为下面两句。
#define DS18B20_IO_IN() {;}//{GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=8<<8;}
#define DS18B20_IO_OUT() {;}//{GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=3<<8;}
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
2.管脚是否有上拉电阻
评分
查看全部评分
设置成开漏输出,外接上拉电阻,
没有说明芯片类型,如是F103直接设成开漏输出。
如是L152直接设成开漏输出。最好用寄操作存器保证时序。
评分
查看全部评分
评分
查看全部评分