ds18b20

ds18b20

检测不到ds18b20输入

问题困惑现场总线/以太网/modbus开 回复了问题 • 3 人关注 • 2 个回复 • 47 次浏览 • 2019-10-15 15:05 • 来自相关话题

ds18b20的输入和输出

问题困惑现场总线/以太网/modbus开 回复了问题 • 3 人关注 • 2 个回复 • 121 次浏览 • 2019-10-05 11:43 • 来自相关话题

CubeMX+freertos+2个DS18B20测温

经验分享wide(BG7RGT) 发表了文章 • 4 个评论 • 2343 次浏览 • 2017-05-24 14:32 • 来自相关话题

硬件: STM32F103开发板(MIN);独立两路 18B20软件:  CubeMX最新版本;MDK 最新版本,IAR 7.8关键: 单总线的时序要求比较严格,所以根据系统时钟计算好微秒函数, CubeMX带的 freeRTOS已经重新封装过,非常好用,所以任务都在 freeROTS.c中,自动生成的 main函数一点不用动,文档请看下面百度云链接,里面有keil与 IAR两个版本,包括CubeMX配置文件http://pan.baidu.com/s/1nv2X3dv  密码:q81t 查看全部

硬件: STM32F103开发板(MIN);独立两路 18B20

软件:  CubeMX最新版本;MDK 最新版本,IAR 7.8

关键: 单总线的时序要求比较严格,所以根据系统时钟计算好微秒函数, CubeMX带的 freeRTOS已经重新封装过,非常好用,所以任务都在 freeROTS.c中,自动生成的 main函数一点不用动,文档请看下面百度云链接,里面有keil与 IAR两个版本,包括CubeMX配置文件

http://pan.baidu.com/s/1nv2X3dv  密码:q81t

分享DS18B20单线式温度测量利用stm32cubemx的配置和完整程序代码,芯片是stm32f407

软件教程admin 发表了文章 • 9 个评论 • 3417 次浏览 • 2014-12-19 16:03 • 来自相关话题

今天去某coocox论坛,看到有人问DS18B20怎么使用,才想起来以前生成并测试过此代码
其实早就分享到了本站的资源下载里面了.
这两天也没分享和研究过什么代码,只好把它拿出来了,呵呵
代码没什么特别的,很普通的代码,关键问题是要知道单线式芯片的使用方法,知道了这个编写代码也简单
有兴趣的可以去搜搜这个片子的资料,类似这种片子还不少,使用方法大致相同
下面说说用软件stm32cubemx怎么配置和生成代码后怎么使用
本站利用管脚PA2来实现功能,只需将PA2管脚定义为[输出,无上拉,快速]模式就行了,
我这里利用usart来输出读取的温度值,故还需配置下usart1串口,串口配置暂且不提了,以前帖子里面写了很多了
生成代码后,打开工程,添加ds18b20的驱动程序,如下:
文件名: ds18b20.c


#include "ds18b20.h"
#include "delay.h"

//复位DS18B20
void DS18B20_Rst(void)
{
CLR_DS18B20(); //拉低DQ
delay_us(750); //拉低750us
SET_DS18B20();; //DQ=1
delay_us(15); //15US
}


//等待DS18B20的回应
//返回1:未检测到ds18b20的存在
//返回0:存在
uint8_t DS18B20_Check(void)
{
uint8_t retry=0;

while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}


//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) // read one bit
{
uint8_t data;

CLR_DS18B20(); //拉低DQ
delay_us(2);
SET_DS18B20();; //DQ=1
delay_us(12);
if(DS18B20_DQ_IN)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;
}

//*本程序由 www.stm32cube.com 提供
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;

for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}


//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}


//初始化DS18B20的IO口DQ同时检查DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20_Init(void)
{
//配置PA2口
GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOA_CLK_ENABLE();

/[i]Configure GPIO pin : PA2 [/i]/
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //使PA2输出高电平

DS18B20_Rst();
return DS18B20_Check();
}


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
uint8_t temp;
uint8_t TL,TH;
short tem;

DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB

if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负值
}else temp=1; //温度为正
tem=TH; //获得高8位
tem<<=8;
tem+=TL; //获得低8位
tem=(float)tem*0.625; //转换
if(temp)return tem; //返回温度值
else return -tem;
}



文件名: ds18b20.h


#ifndef __DS18B20_H
#define __DS18B20_H
#include "stm32f4xx_hal.h"


#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA

#define CLR_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_RESET )
#define SET_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_SET )

#define DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_BIT)


uint8_t DS18B20_Init(void); //初始化DS18B20
short DS18B20_Get_Temp(void); //获取温度
void DS18B20_Start(void); //开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void); //读出一个字节
uint8_t DS18B20_Read_Bit(void); //读出一个位
uint8_t DS18B20_Check(void); //检测是否存在DS18b20
void DS18B20_Rst(void); //复位DS18B20

#endif


文件名: delay.c


#include "delay.h"

/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value)
{
uint32_t i;
i = value * 50;
while(i--);
}

文件名:delay.h


#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f4xx_hal.h"
/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value);

#endif



以上是ds18b20所要使用的驱动程序文件,将这两个c文件添加至工程中
在main.c文件中
添加ds18b20的驱动头文件和uart的printf函数栈定义


/[i] USER CODE BEGIN 0 [/i]/
#include "ds18b20.h"
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/[i] USER CODE END 0 [/i]/


主函数mian()中是以下代码
int main(void)
{

/ USER CODE BEGIN 1 /
short temp;
/ USER CODE END 1 /

/ MCU Configuration----------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init();

/ Configure the system clock /
SystemClock_Config();

/ System interrupt init/
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/ Initialize all configured peripherals /
MX_GPIO_Init();
MX_USART1_UART_Init();

/ USER CODE BEGIN 2 /
printf ("start:\r\n");

while(DS18B20_Init()) //初始化并检测18B20
{
printf ("DS18B20 Check Failed!");
HAL_Delay (500);
printf ("Please Check!");
HAL_Delay (500);
}




/ USER CODE END 2 /

/ USER CODE BEGIN 3 /
/ Infinite loop /
while (1)
{
HAL_Delay (500);
HAL_GPIO_TogglePin (GPIOF ,GPIO_PIN_6 ); //闪烁led指示程序运行正常
temp=DS18B20_Get_Temp();//获取温度值
printf ("Temperate:%d \r\n",temp );//输出得到的温度值到终端
}
/ USER CODE END 3 /

}
编译,后运行,串口调试助手里面会显示测量的温度值........
注意啊,ds18b20.c文件里面
uint8_t DS18B20_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/ GPIO Ports Clock Enable /
__GPIOA_CLK_ENABLE();

/Configure GPIO pin : PA2 /
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //ʹGPIOAµÄPin_2Êä³ö¸ßµçƽ

DS18B20_Rst();
return DS18B20_Check();
}
这个代码,上面初始化的部分由于stm32cubemx生成的时候已经初始化了,可以删掉...额
我是直接把初始化的这个剪切到了这里
如果你要用以上的代码在其他端口,只需要修改ds18b20.h中的
#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA
这个就可以了.
最简洁的办法是,不要用stm32cubemx定义你准备使用的连接到ds18b20的管脚,
到时候用的时候直接来这个h文件里面修改!
结束! 查看全部
今天去某coocox论坛,看到有人问DS18B20怎么使用,才想起来以前生成并测试过此代码
其实早就分享到了本站的资源下载里面了.
这两天也没分享和研究过什么代码,只好把它拿出来了,呵呵
代码没什么特别的,很普通的代码,关键问题是要知道单线式芯片的使用方法,知道了这个编写代码也简单
有兴趣的可以去搜搜这个片子的资料,类似这种片子还不少,使用方法大致相同
下面说说用软件stm32cubemx怎么配置和生成代码后怎么使用
本站利用管脚PA2来实现功能,只需将PA2管脚定义为[输出,无上拉,快速]模式就行了,
我这里利用usart来输出读取的温度值,故还需配置下usart1串口,串口配置暂且不提了,以前帖子里面写了很多了
生成代码后,打开工程,添加ds18b20的驱动程序,如下:
文件名: ds18b20.c


#include "ds18b20.h"
#include "delay.h"

//复位DS18B20
void DS18B20_Rst(void)
{
CLR_DS18B20(); //拉低DQ
delay_us(750); //拉低750us
SET_DS18B20();; //DQ=1
delay_us(15); //15US
}


//等待DS18B20的回应
//返回1:未检测到ds18b20的存在
//返回0:存在
uint8_t DS18B20_Check(void)
{
uint8_t retry=0;

while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}


//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) // read one bit
{
uint8_t data;

CLR_DS18B20(); //拉低DQ
delay_us(2);
SET_DS18B20();; //DQ=1
delay_us(12);
if(DS18B20_DQ_IN)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;
}

//*本程序由 www.stm32cube.com 提供
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;

for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}


//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}


//初始化DS18B20的IO口DQ同时检查DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20_Init(void)
{
//配置PA2口
GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOA_CLK_ENABLE();

/[i]Configure GPIO pin : PA2 [/i]/
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //使PA2输出高电平

DS18B20_Rst();
return DS18B20_Check();
}


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
uint8_t temp;
uint8_t TL,TH;
short tem;

DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB

if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负值
}else temp=1; //温度为正
tem=TH; //获得高8位
tem<<=8;
tem+=TL; //获得低8位
tem=(float)tem*0.625; //转换
if(temp)return tem; //返回温度值
else return -tem;
}



文件名: ds18b20.h


#ifndef __DS18B20_H
#define __DS18B20_H
#include "stm32f4xx_hal.h"


#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA

#define CLR_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_RESET )
#define SET_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_SET )

#define DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_BIT)


uint8_t DS18B20_Init(void); //初始化DS18B20
short DS18B20_Get_Temp(void); //获取温度
void DS18B20_Start(void); //开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void); //读出一个字节
uint8_t DS18B20_Read_Bit(void); //读出一个位
uint8_t DS18B20_Check(void); //检测是否存在DS18b20
void DS18B20_Rst(void); //复位DS18B20

#endif


文件名: delay.c


#include "delay.h"

/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value)
{
uint32_t i;
i = value * 50;
while(i--);
}

文件名:delay.h


#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f4xx_hal.h"
/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value);

#endif



以上是ds18b20所要使用的驱动程序文件,将这两个c文件添加至工程中
在main.c文件中
添加ds18b20的驱动头文件和uart的printf函数栈定义


/[i] USER CODE BEGIN 0 [/i]/
#include "ds18b20.h"
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/[i] USER CODE END 0 [/i]/


主函数mian()中是以下代码
int main(void)
{

/ USER CODE BEGIN 1 /
short temp;
/ USER CODE END 1 /

/ MCU Configuration----------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init();

/ Configure the system clock /
SystemClock_Config();

/ System interrupt init/
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/ Initialize all configured peripherals /
MX_GPIO_Init();
MX_USART1_UART_Init();

/ USER CODE BEGIN 2 /
printf ("start:\r\n");

while(DS18B20_Init()) //初始化并检测18B20
{
printf ("DS18B20 Check Failed!");
HAL_Delay (500);
printf ("Please Check!");
HAL_Delay (500);
}




/ USER CODE END 2 /

/ USER CODE BEGIN 3 /
/ Infinite loop /
while (1)
{
HAL_Delay (500);
HAL_GPIO_TogglePin (GPIOF ,GPIO_PIN_6 ); //闪烁led指示程序运行正常
temp=DS18B20_Get_Temp();//获取温度值
printf ("Temperate:%d \r\n",temp );//输出得到的温度值到终端
}
/ USER CODE END 3 /

}
编译,后运行,串口调试助手里面会显示测量的温度值........
注意啊,ds18b20.c文件里面
uint8_t DS18B20_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/ GPIO Ports Clock Enable /
__GPIOA_CLK_ENABLE();

/Configure GPIO pin : PA2 /
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //ʹGPIOAµÄPin_2Êä³ö¸ßµçƽ

DS18B20_Rst();
return DS18B20_Check();
}
这个代码,上面初始化的部分由于stm32cubemx生成的时候已经初始化了,可以删掉...额
我是直接把初始化的这个剪切到了这里
如果你要用以上的代码在其他端口,只需要修改ds18b20.h中的
#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA
这个就可以了.
最简洁的办法是,不要用stm32cubemx定义你准备使用的连接到ds18b20的管脚,
到时候用的时候直接来这个h文件里面修改!
结束!

检测不到ds18b20输入

回复

问题困惑现场总线/以太网/modbus开 回复了问题 • 3 人关注 • 2 个回复 • 47 次浏览 • 2019-10-15 15:05 • 来自相关话题

ds18b20的输入和输出

回复

问题困惑现场总线/以太网/modbus开 回复了问题 • 3 人关注 • 2 个回复 • 121 次浏览 • 2019-10-05 11:43 • 来自相关话题

CubeMX+freertos+2个DS18B20测温

经验分享wide(BG7RGT) 发表了文章 • 4 个评论 • 2343 次浏览 • 2017-05-24 14:32 • 来自相关话题

硬件: STM32F103开发板(MIN);独立两路 18B20软件:  CubeMX最新版本;MDK 最新版本,IAR 7.8关键: 单总线的时序要求比较严格,所以根据系统时钟计算好微秒函数, CubeMX带的 freeRTOS已经重新封装过,非常好用,所以任务都在 freeROTS.c中,自动生成的 main函数一点不用动,文档请看下面百度云链接,里面有keil与 IAR两个版本,包括CubeMX配置文件http://pan.baidu.com/s/1nv2X3dv  密码:q81t 查看全部

硬件: STM32F103开发板(MIN);独立两路 18B20

软件:  CubeMX最新版本;MDK 最新版本,IAR 7.8

关键: 单总线的时序要求比较严格,所以根据系统时钟计算好微秒函数, CubeMX带的 freeRTOS已经重新封装过,非常好用,所以任务都在 freeROTS.c中,自动生成的 main函数一点不用动,文档请看下面百度云链接,里面有keil与 IAR两个版本,包括CubeMX配置文件

http://pan.baidu.com/s/1nv2X3dv  密码:q81t

分享DS18B20单线式温度测量利用stm32cubemx的配置和完整程序代码,芯片是stm32f407

软件教程admin 发表了文章 • 9 个评论 • 3417 次浏览 • 2014-12-19 16:03 • 来自相关话题

今天去某coocox论坛,看到有人问DS18B20怎么使用,才想起来以前生成并测试过此代码
其实早就分享到了本站的资源下载里面了.
这两天也没分享和研究过什么代码,只好把它拿出来了,呵呵
代码没什么特别的,很普通的代码,关键问题是要知道单线式芯片的使用方法,知道了这个编写代码也简单
有兴趣的可以去搜搜这个片子的资料,类似这种片子还不少,使用方法大致相同
下面说说用软件stm32cubemx怎么配置和生成代码后怎么使用
本站利用管脚PA2来实现功能,只需将PA2管脚定义为[输出,无上拉,快速]模式就行了,
我这里利用usart来输出读取的温度值,故还需配置下usart1串口,串口配置暂且不提了,以前帖子里面写了很多了
生成代码后,打开工程,添加ds18b20的驱动程序,如下:
文件名: ds18b20.c


#include "ds18b20.h"
#include "delay.h"

//复位DS18B20
void DS18B20_Rst(void)
{
CLR_DS18B20(); //拉低DQ
delay_us(750); //拉低750us
SET_DS18B20();; //DQ=1
delay_us(15); //15US
}


//等待DS18B20的回应
//返回1:未检测到ds18b20的存在
//返回0:存在
uint8_t DS18B20_Check(void)
{
uint8_t retry=0;

while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}


//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) // read one bit
{
uint8_t data;

CLR_DS18B20(); //拉低DQ
delay_us(2);
SET_DS18B20();; //DQ=1
delay_us(12);
if(DS18B20_DQ_IN)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;
}

//*本程序由 www.stm32cube.com 提供
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;

for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}


//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}


//初始化DS18B20的IO口DQ同时检查DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20_Init(void)
{
//配置PA2口
GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOA_CLK_ENABLE();

/[i]Configure GPIO pin : PA2 [/i]/
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //使PA2输出高电平

DS18B20_Rst();
return DS18B20_Check();
}


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
uint8_t temp;
uint8_t TL,TH;
short tem;

DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB

if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负值
}else temp=1; //温度为正
tem=TH; //获得高8位
tem<<=8;
tem+=TL; //获得低8位
tem=(float)tem*0.625; //转换
if(temp)return tem; //返回温度值
else return -tem;
}



文件名: ds18b20.h


#ifndef __DS18B20_H
#define __DS18B20_H
#include "stm32f4xx_hal.h"


#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA

#define CLR_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_RESET )
#define SET_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_SET )

#define DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_BIT)


uint8_t DS18B20_Init(void); //初始化DS18B20
short DS18B20_Get_Temp(void); //获取温度
void DS18B20_Start(void); //开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void); //读出一个字节
uint8_t DS18B20_Read_Bit(void); //读出一个位
uint8_t DS18B20_Check(void); //检测是否存在DS18b20
void DS18B20_Rst(void); //复位DS18B20

#endif


文件名: delay.c


#include "delay.h"

/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value)
{
uint32_t i;
i = value * 50;
while(i--);
}

文件名:delay.h


#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f4xx_hal.h"
/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value);

#endif



以上是ds18b20所要使用的驱动程序文件,将这两个c文件添加至工程中
在main.c文件中
添加ds18b20的驱动头文件和uart的printf函数栈定义


/[i] USER CODE BEGIN 0 [/i]/
#include "ds18b20.h"
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/[i] USER CODE END 0 [/i]/


主函数mian()中是以下代码
int main(void)
{

/ USER CODE BEGIN 1 /
short temp;
/ USER CODE END 1 /

/ MCU Configuration----------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init();

/ Configure the system clock /
SystemClock_Config();

/ System interrupt init/
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/ Initialize all configured peripherals /
MX_GPIO_Init();
MX_USART1_UART_Init();

/ USER CODE BEGIN 2 /
printf ("start:\r\n");

while(DS18B20_Init()) //初始化并检测18B20
{
printf ("DS18B20 Check Failed!");
HAL_Delay (500);
printf ("Please Check!");
HAL_Delay (500);
}




/ USER CODE END 2 /

/ USER CODE BEGIN 3 /
/ Infinite loop /
while (1)
{
HAL_Delay (500);
HAL_GPIO_TogglePin (GPIOF ,GPIO_PIN_6 ); //闪烁led指示程序运行正常
temp=DS18B20_Get_Temp();//获取温度值
printf ("Temperate:%d \r\n",temp );//输出得到的温度值到终端
}
/ USER CODE END 3 /

}
编译,后运行,串口调试助手里面会显示测量的温度值........
注意啊,ds18b20.c文件里面
uint8_t DS18B20_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/ GPIO Ports Clock Enable /
__GPIOA_CLK_ENABLE();

/Configure GPIO pin : PA2 /
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //ʹGPIOAµÄPin_2Êä³ö¸ßµçƽ

DS18B20_Rst();
return DS18B20_Check();
}
这个代码,上面初始化的部分由于stm32cubemx生成的时候已经初始化了,可以删掉...额
我是直接把初始化的这个剪切到了这里
如果你要用以上的代码在其他端口,只需要修改ds18b20.h中的
#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA
这个就可以了.
最简洁的办法是,不要用stm32cubemx定义你准备使用的连接到ds18b20的管脚,
到时候用的时候直接来这个h文件里面修改!
结束! 查看全部
今天去某coocox论坛,看到有人问DS18B20怎么使用,才想起来以前生成并测试过此代码
其实早就分享到了本站的资源下载里面了.
这两天也没分享和研究过什么代码,只好把它拿出来了,呵呵
代码没什么特别的,很普通的代码,关键问题是要知道单线式芯片的使用方法,知道了这个编写代码也简单
有兴趣的可以去搜搜这个片子的资料,类似这种片子还不少,使用方法大致相同
下面说说用软件stm32cubemx怎么配置和生成代码后怎么使用
本站利用管脚PA2来实现功能,只需将PA2管脚定义为[输出,无上拉,快速]模式就行了,
我这里利用usart来输出读取的温度值,故还需配置下usart1串口,串口配置暂且不提了,以前帖子里面写了很多了
生成代码后,打开工程,添加ds18b20的驱动程序,如下:
文件名: ds18b20.c


#include "ds18b20.h"
#include "delay.h"

//复位DS18B20
void DS18B20_Rst(void)
{
CLR_DS18B20(); //拉低DQ
delay_us(750); //拉低750us
SET_DS18B20();; //DQ=1
delay_us(15); //15US
}


//等待DS18B20的回应
//返回1:未检测到ds18b20的存在
//返回0:存在
uint8_t DS18B20_Check(void)
{
uint8_t retry=0;

while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}


//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) // read one bit
{
uint8_t data;

CLR_DS18B20(); //拉低DQ
delay_us(2);
SET_DS18B20();; //DQ=1
delay_us(12);
if(DS18B20_DQ_IN)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;
}

//*本程序由 www.stm32cube.com 提供
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;

for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
SET_DS18B20(); //DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}


//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}


//初始化DS18B20的IO口DQ同时检查DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20_Init(void)
{
//配置PA2口
GPIO_InitTypeDef GPIO_InitStruct;

/[i] GPIO Ports Clock Enable [/i]/
__GPIOA_CLK_ENABLE();

/[i]Configure GPIO pin : PA2 [/i]/
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //使PA2输出高电平

DS18B20_Rst();
return DS18B20_Check();
}


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
uint8_t temp;
uint8_t TL,TH;
short tem;

DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB

if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负值
}else temp=1; //温度为正
tem=TH; //获得高8位
tem<<=8;
tem+=TL; //获得低8位
tem=(float)tem*0.625; //转换
if(temp)return tem; //返回温度值
else return -tem;
}



文件名: ds18b20.h


#ifndef __DS18B20_H
#define __DS18B20_H
#include "stm32f4xx_hal.h"


#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA

#define CLR_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_RESET )
#define SET_DS18B20() HAL_GPIO_WritePin (DS18B20_PORT,DS18B20_BIT,GPIO_PIN_SET )

#define DS18B20_DQ_IN HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_BIT)


uint8_t DS18B20_Init(void); //初始化DS18B20
short DS18B20_Get_Temp(void); //获取温度
void DS18B20_Start(void); //开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void); //读出一个字节
uint8_t DS18B20_Read_Bit(void); //读出一个位
uint8_t DS18B20_Check(void); //检测是否存在DS18b20
void DS18B20_Rst(void); //复位DS18B20

#endif


文件名: delay.c


#include "delay.h"

/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value)
{
uint32_t i;
i = value * 50;
while(i--);
}

文件名:delay.h


#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f4xx_hal.h"
/***************************************************************************
*函数名:delay_nus()
*参数u32 n 时钟延时的微妙数
*返回值:void
*功能:使用系统节拍时钟精准延时n个微妙函数
*本程序由 www.stm32cube.com 提供
*****************************************************************************/
void delay_us(uint32_t value);

#endif



以上是ds18b20所要使用的驱动程序文件,将这两个c文件添加至工程中
在main.c文件中
添加ds18b20的驱动头文件和uart的printf函数栈定义


/[i] USER CODE BEGIN 0 [/i]/
#include "ds18b20.h"
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /[i] __GNUC__ [/i]/

/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/[i] Place your implementation of fputc here [/i]/
/[i] e.g. write a character to the EVAL_COM1 and Loop until the end of transmission [/i]/
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/[i] USER CODE END 0 [/i]/


主函数mian()中是以下代码
int main(void)
{

/ USER CODE BEGIN 1 /
short temp;
/ USER CODE END 1 /

/ MCU Configuration----------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init();

/ Configure the system clock /
SystemClock_Config();

/ System interrupt init/
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

/ Initialize all configured peripherals /
MX_GPIO_Init();
MX_USART1_UART_Init();

/ USER CODE BEGIN 2 /
printf ("start:\r\n");

while(DS18B20_Init()) //初始化并检测18B20
{
printf ("DS18B20 Check Failed!");
HAL_Delay (500);
printf ("Please Check!");
HAL_Delay (500);
}




/ USER CODE END 2 /

/ USER CODE BEGIN 3 /
/ Infinite loop /
while (1)
{
HAL_Delay (500);
HAL_GPIO_TogglePin (GPIOF ,GPIO_PIN_6 ); //闪烁led指示程序运行正常
temp=DS18B20_Get_Temp();//获取温度值
printf ("Temperate:%d \r\n",temp );//输出得到的温度值到终端
}
/ USER CODE END 3 /

}
编译,后运行,串口调试助手里面会显示测量的温度值........
注意啊,ds18b20.c文件里面
uint8_t DS18B20_Init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;

/ GPIO Ports Clock Enable /
__GPIOA_CLK_ENABLE();

/Configure GPIO pin : PA2 /
GPIO_InitStruct.Pin = DS18B20_BIT;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(DS18B20_PORT, &GPIO_InitStruct);

SET_DS18B20(); //ʹGPIOAµÄPin_2Êä³ö¸ßµçƽ

DS18B20_Rst();
return DS18B20_Check();
}
这个代码,上面初始化的部分由于stm32cubemx生成的时候已经初始化了,可以删掉...额
我是直接把初始化的这个剪切到了这里
如果你要用以上的代码在其他端口,只需要修改ds18b20.h中的
#define DS18B20_BIT GPIO_PIN_2
#define DS18B20_PORT GPIOA
这个就可以了.
最简洁的办法是,不要用stm32cubemx定义你准备使用的连接到ds18b20的管脚,
到时候用的时候直接来这个h文件里面修改!
结束!