HAL库DS18B20读取温度值程序代码
我是用的是STM32F103RB,时钟主频72M。18b20端口使用PA0,配置该端口为推挽输出即可。 注意:驱动单总线器件时序上是很简单的,如果是使用HAL库,关键点在于微秒的延时的准确性。
扫描以下二维码,关注公众号雍正不秃头获取更多STM32资源及干货!
DS18B20.H
#ifndef __DS18B20_H
#define __DS18B20_H
#include "main.h"
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+12)
#define GPIOB_ODR_Addr (GPIOB_BASE+12)
#define GPIOC_ODR_Addr (GPIOC_BASE+12)
#define GPIOD_ODR_Addr (GPIOD_BASE+12)
#define GPIOE_ODR_Addr (GPIOE_BASE+12)
#define GPIOF_ODR_Addr (GPIOF_BASE+12)
#define GPIOG_ODR_Addr (GPIOG_BASE+12)
#define GPIOA_IDR_Addr (GPIOA_BASE+8)
#define GPIOB_IDR_Addr (GPIOB_BASE+8)
#define GPIOC_IDR_Addr (GPIOC_BASE+8)
#define GPIOD_IDR_Addr (GPIOD_BASE+8)
#define GPIOE_IDR_Addr (GPIOE_BASE+8)
#define GPIOF_IDR_Addr (GPIOF_BASE+8)
#define GPIOG_IDR_Addr (GPIOG_BASE+8)
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n)
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n)
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
#define DS18B20_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;}
#define DS18B20_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;}
#define DS18B20_DQ_OUT PAout(0)
#define DS18B20_DQ_IN PAin(0)
uint8_t
DS18B20_Init(void);
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);
void DS18B20_Rst(void);
#endif
DS18B20.C
#include "ds18b20.h"
static inline void delay_ms(uint32_t delay
)
{
HAL_Delay(delay
);
}
#define CPU_FREQUENCY_MHZ 72
static void delay_us(uint32_t delay
)
{
int last
, curr
, val
;
int temp
;
while (delay
!= 0)
{
temp
= delay
> 900 ? 900 : delay
;
last
= SysTick
->VAL
;
curr
= last
- CPU_FREQUENCY_MHZ
* temp
;
if (curr
>= 0)
{
do
{
val
= SysTick
->VAL
;
}
while ((val
< last
) && (val
>= curr
));
}
else
{
curr
+= CPU_FREQUENCY_MHZ
* 1000;
do
{
val
= SysTick
->VAL
;
}
while ((val
<= last
) || (val
> curr
));
}
delay
-= temp
;
}
}
void DS18B20_Rst(void)
{
DS18B20_IO_OUT();
DS18B20_DQ_OUT
=0;
delay_us(750);
DS18B20_DQ_OUT
=1;
delay_us(15);
}
uint8_t
DS18B20_Check(void)
{
uint8_t retry
=0;
DS18B20_IO_IN();
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;
}
uint8_t
DS18B20_Read_Bit(void)
{
uint8_t data
;
DS18B20_IO_OUT();
DS18B20_DQ_OUT
=0;
delay_us(2);
DS18B20_DQ_OUT
=1;
DS18B20_IO_IN();
delay_us(12);
if(DS18B20_DQ_IN
)data
=1;
else data
=0;
delay_us(50);
return data
;
}
uint8_t
DS18B20_Read_Byte(void)
{
uint8_t i
,j
,dat
;
dat
=0;
for (i
=1;i
<=8;i
++)
{
j
=DS18B20_Read_Bit();
dat
=(j
<<7)|(dat
>>1);
}
return dat
;
}
void DS18B20_Write_Byte(uint8_t dat
)
{
uint8_t j
;
uint8_t testb
;
DS18B20_IO_OUT();
for (j
=1;j
<=8;j
++)
{
testb
=dat
&0x01;
dat
=dat
>>1;
if (testb
)
{
DS18B20_DQ_OUT
=0;
delay_us(2);
DS18B20_DQ_OUT
=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT
=0;
delay_us(60);
DS18B20_DQ_OUT
=1;
delay_us(2);
}
}
}
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0x44);
}
uint8_t
DS18B20_Init(void)
{
DS18B20_Rst();
return DS18B20_Check();
}
short DS18B20_Get_Temp(void)
{
uint8_t temp
;
uint8_t TL
,TH
;
short tem
;
DS18B20_Start
();
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0xbe);
TL
=DS18B20_Read_Byte();
TH
=DS18B20_Read_Byte();
if(TH
>7)
{
TH
=~TH
;
TL
=~TL
;
temp
=0;
}else temp
=1;
tem
=TH
;
tem
<<=8;
tem
+=TL
;
tem
=(float)tem
*0.625;
if(temp
)return tem
;
else return -tem
;
}
ends…