From 275e01269539610fad16d89049694c7e6776ae02 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Tue, 31 May 2022 09:47:29 +0200 Subject: [PATCH] ds18b20 code added --- CMakeLists.txt | 10 +++++-- ds18b20.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ ds18b20.h | 23 ++++++++++++++++ ds18b20.pio | 44 ++++++++++++++++++++++++++++++ gbmanager.cpp | 1 + 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 ds18b20.cpp create mode 100644 ds18b20.h create mode 100644 ds18b20.pio diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bbbf1f..ccf24b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,9 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-volatile") # Initialise pico_sdk from installed location # (note this can come from environment, CMake cache etc) @@ -19,7 +21,7 @@ pico_sdk_init() # Add executable. Default name is the project name, version 0.1 -add_executable(gbmanager gbmanager.cpp lcd.cpp) +add_executable(gbmanager gbmanager.cpp lcd.cpp ds18b20.cpp) pico_set_program_name(gbmanager "gbmanager") pico_set_program_version(gbmanager "0.1") @@ -27,12 +29,16 @@ pico_set_program_version(gbmanager "0.1") pico_enable_stdio_uart(gbmanager 1) pico_enable_stdio_usb(gbmanager 0) +pico_generate_pio_header(gbmanager ${CMAKE_CURRENT_LIST_DIR}/ds18b20.pio) + # Add the standard library to the build target_link_libraries(gbmanager pico_stdlib) # Add any user requested libraries target_link_libraries(gbmanager hardware_i2c + hardware_gpio + hardware_pio ) pico_add_extra_outputs(gbmanager) diff --git a/ds18b20.cpp b/ds18b20.cpp new file mode 100644 index 0000000..eee186f --- /dev/null +++ b/ds18b20.cpp @@ -0,0 +1,72 @@ +#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; +} \ No newline at end of file diff --git a/ds18b20.h b/ds18b20.h new file mode 100644 index 0000000..9c2f68d --- /dev/null +++ b/ds18b20.h @@ -0,0 +1,23 @@ +#ifndef DS18B20_H +#define DS18B20_H + +#include "ds18b20.pio.h" +#include "hardware/gpio.h" +#include "pico/stdlib.h" + +class DS18B20 { + public: + DS18B20(PIO pio, uint8_t gpio); + float getTemperature(); + void convert(); + + private: + uint8_t crc8(uint8_t *data, uint8_t len); + void writeBytes(uint8_t bytes[], int len); + void readBytes(uint8_t bytes[], int len); + PIO pio; + uint8_t gpio; + uint stateMachineIndex; +}; + +#endif \ No newline at end of file diff --git a/ds18b20.pio b/ds18b20.pio new file mode 100644 index 0000000..eb23d8f --- /dev/null +++ b/ds18b20.pio @@ -0,0 +1,44 @@ + +.program ds18b20 +.wrap_target +again: + pull block + mov x, osr + jmp !x, read + +write: set pindirs, 1 + set pins, 0 +loop1: + jmp x--,loop1 +set pindirs, 0 [31] +wait 1 pin 0 [31] + + pull block + mov x, osr +bytes1: + pull block + set y, 7 + set pindirs, 1 +bit1: + set pins, 0 [1] + out pins,1 [31] + set pins, 1 [20] + jmp y--,bit1 +jmp x--,bytes1 + +set pindirs, 0 [31] +jmp again + +read: + pull block + mov x, osr +bytes2: + set y, 7 +bit2: + set pindirs, 1 + set pins, 0 [1] + set pindirs, 0 [5] + in pins,1 [10] +jmp y--,bit2 +jmp x--,bytes2 +.wrap diff --git a/gbmanager.cpp b/gbmanager.cpp index c051d98..4f4e114 100644 --- a/gbmanager.cpp +++ b/gbmanager.cpp @@ -4,6 +4,7 @@ #include "pico/stdlib.h" #include "lcd.h" +#include "ds18b20.h" constexpr uint I2C_SDA_PIN = 26; constexpr uint I2C_SCL_PIN = 27;