首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从ds18b20读取temp

无法从ds18b20读取temp
EN

Stack Overflow用户
提问于 2019-09-14 14:15:26
回答 2查看 245关注 0票数 0

我正在使用stm32读取ds18b20和HAL库。

我认为init是正确的,但读和写却不正确。

谁能告诉我为什么这样做不对?

对于编写,下面是代码

代码语言:javascript
复制
if ((data & (1 << i)) != 0)
        {
            MX_GPIO_Set(1);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
            delay_ms(1);

            MX_GPIO_Set(0);
            delay_ms(60);
        }
        else
        {
            MX_GPIO_Set(1);
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
            delay_ms(60);

            MX_GPIO_Set(0);
        }

它是写一位数据。

以及读取的代码

代码语言:javascript
复制
MX_GPIO_Set(1);

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
        delay_ms(2);

        MX_GPIO_Set(0);
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET)
        {
            value |= 1 << i;
        }
        delay_ms(60);

MX_GPIO_Set(1)意味着设置GPIO输出

哪里出问题了?

请不要告诉我使用库或代码在github.I,我想自己写代码,这样我就可以理解ds18b20。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-14 15:26:21

DS18B20使用单线协议.https://en.wikipedia.org/wiki/1-Wire

每比特大约需要60微秒才能传输。大多数传输过程中,1s值较高,大多数传输过程中s值较低。下一位的开始由一个脉冲指示。

在我看来最突出的一点是,您使用的是delay_ms (毫秒),而您可能希望使用delay_us (微秒)。

此外,您还依赖于位的时间来准确地(可能不会)。相反,根据脉搏来确定你的时间。

比这更复杂。当你阅读时,你需要不断地检查引脚的价值,解释它的含义,而不是拖延,希望时间匹配。

我还没有测试过这个代码,而且它是不完整的。这只是为了说明一种技术。

为了开始,我们将我们的输出设置为低,并等待传感器降低至少200 go。(最理想的是500米。200美元是我们的最低要求。)这是“重置”序列,它告诉我们新的数据即将开始。

代码语言:javascript
复制
const int SleepIntervalMircoseconds = 5;

// Start off by setting our output to LOW (aka GPIO_PIN_RESET).
MX_GPIO_Set(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

// Switch back to reading mode.
MX_GPIO_Set(0);

const int ResetRequiredMiroseconds = 200;

int pinState = GPIO_PIN_SET;
int resetElapsedMicroseconds = 0;
while (pinState != GPIO_PIN_RESET || resetElapsedMicroseconds < ResetRequiredMiroseconds) {
  pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
  if (pinState != GPIO_PIN_RESET) {
    resetElapsedMicroseconds = 0;
    continue;
  }

  delay_us(SleepIntervalMircoseconds);

  // Note that the elapsed microseconds is really an estimate here.
  // The actual elapsed time will be 5us + the amount of time it took to execute the code.
  resetElapsedMicroseconds += SleepIntervalMircoseconds;
}

这只会让我们开始。在您收到重置信号之后,您需要通过在一定时间内将您的值设置为较高的值来向另一方指示您已经收到了它。

票数 1
EN

Stack Overflow用户

发布于 2019-09-16 13:51:31

我无法对您的代码进行评论,因为GPIO设置和调用函数的源代码等重要部分都丢失了。但是,如果位计时给您带来麻烦,您可能会尝试这样做。

使用UART实现一线总线母版

然后,除了计算UART波特率之外,您不必处理延迟和时间问题。

所有STM32 UART都支持一根带开式漏GPIO引脚的线操作。将设备的I/O引脚连接到UART TX引脚。将引脚配置为开漏备用函数输出,并在适用的情况下为UART配置备用函数号。启用UART并将其设置为控制寄存器中的单线操作。

将UART波特率设置为7407,并发送0xF0,这是重置脉冲。等待RXNE并读取UART数据寄存器。如果不是0xF0,那么这个设备就会有一个存在的脉冲。

将UART波特率设置为133333,就可以开始通信。若要发送0位,请将0x00写入UART数据寄存器。若要发送1位,请将0xFF写入UART数据寄存器。要接收一点信息,请编写0xFF,等待RXNE,并读取数据寄存器。如果字节读取为0xFF,则为1,否则(任何其他值读取)即为0

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57936337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档