标题: 自己写的ds18b20程序,找不到器件,请指导 [打印本页]

作者: reking8    时间: 2024-12-18 11:38
标题: 自己写的ds18b20程序,找不到器件,请指导
结合网上其他程序,自己又写的,但是存在检测返回1,不知道怎么回事,自己又检查不出来,请帮忙看一下
作者: TandiHQ    时间: 2024-12-18 11:38
这是我当时在VET6上写的(标准库),里面贴了源程序,再附上工程文件

DS18B20指令流程.docx

17.11 MB, 下载次数: 0

STM32[STD]-DS18B20.7z

185.28 KB, 下载次数: 0


作者: reking8    时间: 2024-12-18 14:50
这是文件包

STM32_DS18B20.zip

323.11 KB, 下载次数: 0


作者: reking8    时间: 2024-12-18 15:58
reking8 发表于 2024-12-18 14:50
这是文件包

#include "stm32f10x.h"                  // Device header
#include "DS18B20.h"
#include "delay.h"

uint8_t DS18B20_Init(void)
{
  DS18B20_OUT_Mode();
  GPIO_SetBits(GPIOA,GPIO_Pin_0);
  DS18B20_Rst();
  return DS18B20_Check();
}

void DS18B20_Rst(void)
{
  DS18B20_OUT_Mode();
  GPIO_ResetBits(DS18B20_PORT,DS18B20_PIN);//复位脉冲,即拉低480-750us
  Delay_us(750);
  GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);//释放总线,即拉高
  Delay_us(30);    //拉高后,DS8B20等待15-60us,再发送存在脉冲
}
uint8_t DS18B20_Check(void)
{
  uint16_t retry = 0;
  
  DS18B20_IN_Mode();//切换到输入模式
  //主机释放总线后,ds18b20会等等待15-60us
  while(GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)&&retry<100)
  {
    retry ++;
    Delay_us(1);
  }
  if(retry>=100)   return 1;
  else retry = 0;
  
//发出存在脉冲60-240us后,拉高释放总线,这里是等待释放
  while(!GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)&&retry<240)
  {
    retry ++;
    Delay_us(1);
  }  
  if(retry >= 240)   return 1;
  else return 0;   
}

void DS18B20_Write_Bit(uint8_t dat)
{
  DS18B20_OUT_Mode();//切换到输出模式
  if(dat)
  {
    GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_RESET);   //写1
    Delay_us(2);
    GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_SET);
    Delay_us(60);
  }
  else
  {
    GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_RESET); //写0
    Delay_us(60);
    GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_SET);//拉高释放总线
    Delay_us(2);
  }
}
void DS18B20_Write_Byte(uint8_t dat)
{
  uint8_t i=0,k=0;
  
  for(i=0;i<8;i++)
  {
    k= dat&0x01;
    dat>>=1;
    Delay_us(2); //位之间有>1us时间间隙
    DS18B20_Write_Bit(k);
  }
}
uint8_t DS18B20_Read_Bit(void)
{
  uint8_t dat;
  
  DS18B20_OUT_Mode();//切换到输出模式
  GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_RESET); //主机拉低总线,产生读取命令
  Delay_us(2);
  GPIO_WriteBit(DS18B20_PORT,DS18B20_PIN,Bit_SET);//主机拉高释放总线,等待从机发送
  
  DS18B20_IN_Mode();//切换到输入模式
  Delay_us(10); //延时,主机必须在15us内采样总线状态
  if(GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)) //采样
  {
    dat =1;
  }
  else dat =0;
  Delay_us(50);//每次读时序至少需要60us
  return dat;
}
uint8_t DS18B20_Read_Byte(void)
{
  uint8_t i,dat=0,k=0;
  
  for(i=0;i<8;i++)
  {
    k =  DS18B20_Read_Bit();
    dat= (k<<7)|(dat>>1);
  }
  return dat;  
}

void DS18B20_Start(void)
{
   DS18B20_Rst();
   DS18B20_Check();
   DS18B20_Write_Byte(0xcc);//跳过ROM检测
   DS18B20_Write_Byte(0x44);//开始转换
}

float DS18B20_Get_Temp(void)
{
  uint16_t value,TL,TH;
  float temp;
  
  DS18B20_Start();
  DS18B20_Rst();
  DS18B20_Check();
  DS18B20_Write_Byte(0xcc);//跳过ROM检测
  DS18B20_Write_Byte(0xbe);//开始转换

  TL = DS18B20_Read_Byte();//LSB
  TH = DS18B20_Read_Byte();//MSB
  value = (TH<<8)+ TL;
  
  if((value&0xf800) == 0xf800)
  {
    value = (~value)+1;
    temp=value*(-0.0625);//乘以精度       
  }  
  else
  {
    temp=value*(0.0625);//乘以精度       
  }

  return temp;  
}

void DS18B20_OUT_Mode(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  DS18B20_RCC_CMD;
  GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);

}  

void DS18B20_IN_Mode(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  DS18B20_RCC_CMD;
  GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}
作者: WL0123    时间: 2024-12-18 16:50
ds18b20对时序非常敏感,随便找个程序要结合所使用的MCU特性和参数修改代码,否则难以成功。
作者: cnos    时间: 2024-12-18 16:51
存在检测的逻辑就是:
你和传感器隔着一堵墙,有一根棍子。你想要知道传感器在不在,就先拉一下棍子,至少拉15μS,最长60μS你就得放手了。

传感器发现你拉了棍子,会在15-60μS之后,也拉一下棍子,拉60-240μS。

也就是在放手15-75μS或者15-255μS或者60-120或者60-300μS会看到传感器也拉了一下棍子。

那么,如果传感器在线,也就是在60-75μS之间,传感器一定会拉一下棍子。

接下来你就自己对着干吧。
作者: lkc8210    时间: 2024-12-19 11:44
  1. void DS18B20_Rst(void)
  2. {
  3.   DS18B20_OUT_Mode();
  4.   GPIO_ResetBits(DS18B20_PORT,DS18B20_PIN);//复位脉冲,即拉低480-750us
  5.   Delay_us(750);
  6.   GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);//释放总线,即拉高
  7.   Delay_us(15);    //拉高后,DS8B20等待15-60us,再发送存在脉冲//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  8. }
复制代码



作者: zpwgf    时间: 2024-12-19 15:50
1.检查一下你的硬件是否好坏。用标准程序去验证
2.检查硬件接口,数据引脚和程序是否对应,如果不对应还是会报错
3.检查软件时序是否正确,拉低拉高时长是否满足手册要求
4.实在找不出问题,使用标准程序修改管脚即可
作者: capation    时间: 2024-12-20 16:28
可以自己编写一个块,让后整合一下




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1