找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1869|回复: 8
打印 上一主题 下一主题
收起左侧

自己写的ds18b20程序,找不到器件,请指导

[复制链接]
跳转到指定楼层
楼主
ID:929517 发表于 2024-12-18 11:38 来自触屏版 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
100黑币
结合网上其他程序,自己又写的,但是存在检测返回1,不知道怎么回事,自己又检查不出来,请帮忙看一下

最佳答案

查看完整内容

这是我当时在VET6上写的(标准库),里面贴了源程序,再附上工程文件
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1140385 发表于 2024-12-18 11:38 | 只看该作者
这是我当时在VET6上写的(标准库),里面贴了源程序,再附上工程文件

DS18B20指令流程.docx

17.11 MB, 下载次数: 0

STM32[STD]-DS18B20.7z

185.28 KB, 下载次数: 0

回复

使用道具 举报

板凳
ID:929517 发表于 2024-12-18 14:50 | 只看该作者
这是文件包

STM32_DS18B20.zip

323.11 KB, 下载次数: 0

回复

使用道具 举报

地板
ID:929517 发表于 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);
}
回复

使用道具 举报

5#
ID:1133081 发表于 2024-12-18 16:50 | 只看该作者
ds18b20对时序非常敏感,随便找个程序要结合所使用的MCU特性和参数修改代码,否则难以成功。
回复

使用道具 举报

6#
ID:688692 发表于 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之间,传感器一定会拉一下棍子。

接下来你就自己对着干吧。
回复

使用道具 举报

7#
ID:161164 发表于 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. }
复制代码


回复

使用道具 举报

8#
ID:583948 发表于 2024-12-19 15:50 | 只看该作者
1.检查一下你的硬件是否好坏。用标准程序去验证
2.检查硬件接口,数据引脚和程序是否对应,如果不对应还是会报错
3.检查软件时序是否正确,拉低拉高时长是否满足手册要求
4.实在找不出问题,使用标准程序修改管脚即可
回复

使用道具 举报

9#
ID:1136761 发表于 2024-12-20 16:28 | 只看该作者
可以自己编写一个块,让后整合一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表