72 lines
No EOL
2 KiB
C++
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;
|
|
} |