你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
H_JEN 发表于 2016-5-8 16:19 还没解决。现在能读数据了,但是读出来的数据,高八位要么全为0,要么全为1;低八位总是为0 ...
LIUBEIHUA 发表于 2016-5-18 13:57 用库函数延时比较长,至少在L152上就有点长了,用开漏的目的就是为了省时间,省去端口切换的时间,时序必须 ...
dsjsjf 发表于 2016-5-13 21:08 这个读时序要严格控制的,确认一下你的时钟频率,程序中的延时函数的精度 ...
如果时序没有问题,很有可能是你延时没有正确造成的,要么就是你拿的器件有问题,可以换一个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;
}
程序里的时延可能需要再仔细推敲推敲。
升不到1可适当减小上拉电阻,我接了一个10米长的引线,上拉电阻用的是1K。必须保证15us内数据线能拉到1.
谢谢。这个问题已经解决了,其实我也不知道为什么,是端口配置问题,我直接配置寄存器就可以读到数据了,但是用库函数来设置端口的话就不行,不管哪种输入方式。这个问题等我调试好整个东西,再来研究下库函数。
嗯,谢谢!问题已经解决了,是端口配置问题,我换成直接写寄存器来配置端口就没问题了,本来是用库函数来配置的,还不知是什么原因,换成寄存器就可以了.......等调试整个东西再来研究库函数
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;}