一、概述
代码参考了正点原子的例程,并经过测试,
开发环境:IAR
单片机:STM32F103C8T6
二、代码
/*******************************************************************************
* 函数名:Port_SetMode
* 功 能:GPIO设置输入或输出模式
* 参 数:*GPIOx 引脚组号
GPIO_Pin引脚号
u32Mode输入或输出模式
* 返回值:无
* 说 明:无
*******************************************************************************/
void Port_SetMode(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t u32Mode)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_Pin;
GPIO_InitStruct.Mode = u32Mode;
//GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}
相关引脚驱动宏定义
#define DS18B20_DQSet() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET)
#define DS18B20_DQReset() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET)
#define DS18B20_DQModeOutput() Port_SetMode(GPIOB, GPIO_PIN_6, GPIO_MODE_OUTPUT_PP)
#define DS18B20_DQModeInput() Port_SetMode(GPIOB, GPIO_PIN_6, GPIO_MODE_INPUT)
#define DS18B20_DIORead() HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6)
驱动程序
/*******************************************************************************
* 函数名:DS18B20_set
* 功 能:DS18B20复位
* 参 数:无
* 返回值:无
* 说 明:复位
*******************************************************************************/
void DS18B20_Reset(void)
{
DS18B20_DQModeOutput();//设置为输出
DS18B20_DQReset();//低电平
delay_us(750);//750us
DS18B20_DQSet();//高电平
delay_us(15);//15us
}
/*******************************************************************************
* 函数名:DS18B20_Check
* 功 能:检测DS18B20是否存在
* 参 数:无
* 返回值:1不存在,0存在
* 说 明:无
*******************************************************************************/
uint8_t DS18B20_Check(void)
{
uint8_t u8Retry = 0;
DS18B20_DQModeInput();//设置为输入
while ((DS18B20_DIORead() == 1)&&(u8Retry < 200))
{
u8Retry++;
delay_us(1);
}
if (u8Retry >= 200)
{
return 1;
}else
{
u8Retry = 0;
}
while ((DS18B20_DIORead() == 0) && (u8Retry < 240))
{
u8Retry++;
delay_us(1);
}
if(u8Retry >= 120)
{
return 1;
}
return 0;
}
/*******************************************************************************
* 函数名:DS18B20_WriteByte
* 功 能:向DS18B20写入一个字节
* 参 数:u8Data:要写入的数据
* 返回值:无
* 说 明:
*******************************************************************************/
void DS18B20_WriteByte(uint8_t u8Data)
{
uint8_t tempIndex,tempData;
DS18B20_DQModeOutput();//设置为输出
for (tempIndex = 1; tempIndex <= 8; tempIndex++)
{
tempData = (u8Data & 0x01);
u8Data >>= 1;
if (tempData == 1)
{
DS18B20_DQReset();//低电平
delay_us(2);
DS18B20_DQSet();//高电平
delay_us(60);//延时60us
}else
{
DS18B20_DQReset();//低电平
delay_us(60);//延时60us
DS18B20_DQSet();//高电平
delay_us(2);
}
}
}
/*******************************************************************************
* 函数名:DS18B20_ReadBit
* 功 能:从DS18B20读取一个位
* 参 数:无
* 返回值:1或0
* 说 明:无
*******************************************************************************/
uint8_t DS18B20_ReadBit(void)
{
uint8_t u8Data = 0;
DS18B20_DQModeOutput();//设置为输出
DS18B20_DQReset();//低电平
delay_us(2);
DS18B20_DQSet();//高电平
DS18B20_DQModeInput();//设置为输入
delay_us(12);
u8Data = ((DS18B20_DIORead() == 1) ? 1 : 0);
delay_us(50);
return u8Data;
}
/*******************************************************************************
* 函数名:DS18B20_ReadByte
* 功 能:从DS18B20读取一个字节
* 参 数:无
* 返回值:u8Data读出的数据
* 说 明:无
*******************************************************************************/
uint8_t DS18B20_ReadByte(void)
{
uint8_t i,j, u8Ddata = 0;
for (i = 1; i <= 8; i++)
{
j = DS18B20_ReadBit();
u8Ddata = (j << 7) | (u8Ddata >> 1);
}
return u8Ddata;
}
/*******************************************************************************
* 函数名:DS18B20_Start
* 功 能:开始温度转换
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void DS18B20_Start(void)
{
DS18B20_Reset();
DS18B20_Check();
DS18B20_WriteByte(0xCC);//跳过ROM
DS18B20_WriteByte(0x44);//温度转换
}
其中用到的微秒延时函数,可参考另一篇博客《通用定时器实现STM32单片机微秒级延时函数》。