gbmanager/ds18b20.cpp

72 lines
No EOL
2 KiB
C++

#include "ds18b20.h"
DS18B20::DS18B20(PIO pio, uint8_t gpio) : pio{pio}, gpio{gpio} {
uint offset = pio_add_program(pio, &ds18b20_program);
stateMachineIndex = pio_claim_unused_sm(pio, true);
pio_gpio_init(pio, gpio);
pio_sm_config c = ds18b20_program_get_default_config(offset);
sm_config_set_clkdiv_int_frac(&c, 255, 0);
sm_config_set_set_pins(&c, gpio, 1);
sm_config_set_out_pins(&c, gpio, 1);
sm_config_set_in_pins(&c, gpio);
sm_config_set_in_shift(&c, true, true, 8);
pio_sm_init(pio0, stateMachineIndex, offset, &c);
pio_sm_set_enabled(pio0, stateMachineIndex, true);
}
void DS18B20::writeBytes(uint8_t bytes[], int len) {
pio_sm_put_blocking(pio, stateMachineIndex, 250);
pio_sm_put_blocking(pio, stateMachineIndex, len - 1);
for (int i = 0; i < len; i++) {
pio_sm_put_blocking(pio, stateMachineIndex, bytes[i]);
}
}
void DS18B20::readBytes(uint8_t bytes[], int len) {
pio_sm_put_blocking(pio, stateMachineIndex, 0);
pio_sm_put_blocking(pio, stateMachineIndex, len - 1);
for (int i = 0; i < len; i++) {
bytes[i] = pio_sm_get_blocking(pio, stateMachineIndex) >> 24;
}
}
void DS18B20::convert() {
uint8_t d[2] = {0xCC, 0x44};
writeBytes(d, 2);
}
uint8_t DS18B20::crc8(uint8_t *data, uint8_t len) {
uint8_t i;
uint8_t j;
uint8_t temp;
uint8_t databyte;
uint8_t crc = 0;
for (i = 0; i < len; i++) {
databyte = data[i];
for (j = 0; j < 8; j++) {
temp = (crc ^ databyte) & 0x01;
crc >>= 1;
if (temp)
crc ^= 0x8C;
databyte >>= 1;
}
}
return crc;
}
float DS18B20::getTemperature() {
uint8_t d[2] = {0xCC, 0xBE};
writeBytes(d, 2);
uint8_t data[9];
readBytes(data, 9);
uint8_t crc = crc8(data, 9);
if (crc != 0)
return -2000;
int t1 = data[0];
int t2 = data[1];
int16_t temp1 = (t2 << 8 | t1);
volatile float temp = (float)temp1 / 16;
return temp;
}