我正在使用stm32读取具有HAL库的ds18b20
我认为init正确,但是读写不正确
任何人都可以告诉我为什么它不对吗?
写,这是代码
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);
}
是写一位数据。
,并读取代码
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中使用库或代码。我想自己编写代码,这样我才能理解ds18b20。
答案 0 :(得分:0)
DS18B20使用单线协议。 https://en.wikipedia.org/wiki/1-Wire
每个位大约需要60微秒来传输。 在大多数传输过程中,1为高电平,而在大多数传输过程中,0为低电平。下一位的开始用脉冲表示。
对我来说突出的一件事是,当您可能想使用delay_us(微秒)时,您正在使用delay_ms(毫秒)。
此外,您还需要精确地确定钻头的时间(可能不会)。相反,您的计时要基于脉冲。
这要复杂得多。 读取时,您需要不断检查引脚的值并解释其含义,而不是设置延迟并希望时序匹配。
我尚未测试此代码,但代码不完整。 这只是为了说明一种技术。
首先,我们将输出设置为LOW并等待 传感器至少要保持低电平200us。 (理想情况下,我们的最低要求是500us。200us。) 这是“ RESET”序列,告诉我们新数据即将开始。
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;
}
这只会让我们开始。 收到重置信号后,您需要通过在一段时间内将值设置为HIGH来指示另一边已收到重置信号。
答案 1 :(得分:0)
我无法对您的代码发表评论,因为缺少GPIO设置等重要部分以及所调用功能的源代码。但是,如果位时序给您带来麻烦,则可以尝试这样做。
Using a UART to Implement a 1-Wire Bus Master
那么,除了计算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
。