From 4e65640929c8c76bb1248ec0a08bdf0411ab6cfc Mon Sep 17 00:00:00 2001 From: smallsolar Date: Sat, 5 Apr 2025 22:40:49 +0000 Subject: [PATCH] Add ds18b20.c --- ds18b20.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 ds18b20.c diff --git a/ds18b20.c b/ds18b20.c new file mode 100644 index 0000000..c2de5bc --- /dev/null +++ b/ds18b20.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include "ds18b20.h" +//#include "delay.h" +#include "misc.h" + +// Define GPIO port and pin for the DS18B20 +#define DS18B20_PORT GPIOB +#define DS18B20_PIN GPIO1 + +// Delay function +void ds18b20_delay_us(uint32_t us) { +for (uint32_t i = 0; i < (us * 3); i++) { +__asm__("nop"); +} +} + +void ds18b20_delay_us_nop() { + __asm__("nop"); + +} + +// OneWire low-level functions +static void ds18b20_pin_mode_output(void) { + gpio_mode_setup(DS18B20_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DS18B20_PIN); +} + +static void ds18b20_pin_mode_input(void) { + gpio_mode_setup(DS18B20_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, DS18B20_PIN); +} + +static void ds18b20_write_bit(uint8_t bit) { + ds18b20_pin_mode_output(); + gpio_clear(DS18B20_PORT, DS18B20_PIN); + + if (bit) { + delay_us(1); // Short low pulse for '1' + gpio_set(DS18B20_PORT, DS18B20_PIN); + ds18b20_pin_mode_input(); + } + + delay_us(60); + ds18b20_pin_mode_input(); + delay_us(10); +} + +static uint8_t ds18b20_read_bit(void) { + uint8_t bit; + ds18b20_pin_mode_output(); + gpio_clear(DS18B20_PORT, DS18B20_PIN); +// ds18b20_delay_us(1); +// gpio_set(DS18B20_PORT, DS18B20_PIN); + + ds18b20_pin_mode_input(); + ds18b20_delay_us(10); + bit = gpio_get(DS18B20_PORT, DS18B20_PIN); + ds18b20_delay_us(50); + return bit; +} + +uint8_t ds18b20_reset(void) { + uint8_t presence; + ds18b20_pin_mode_output(); + gpio_clear(DS18B20_PORT, DS18B20_PIN); + + ds18b20_delay_us(960); + + ds18b20_pin_mode_input(); + ds18b20_delay_us(120); + + presence = gpio_get(DS18B20_PORT, DS18B20_PIN); + + ds18b20_delay_us(840); + + return presence == 0; // If presence is detected, return 1 +} + +void ds18b20_write_byte(uint8_t byte) { + for (uint8_t i = 0; i < 8; i++) { + ds18b20_write_bit(byte & 0x01); + byte >>= 1; + } + ds18b20_pin_mode_input(); +} + +/* +uint8_t ds18b20_read_byte(void) { + uint8_t byte = 0; + for (uint8_t i = 0; i < 8; i++) { + byte |= (ds18b20_read_bit() << i); + } + return byte; +} +*/ +/* +uint8_t ds18b20_read_byte(void) { + uint8_t i=8, n=0; + while(i--){ + n>>=1; + n |= (ds18b20_read_bit()<<7); + } + return n; +} +*/ + +uint8_t ds18b20_read_byte(void) +{ + uint8_t byte = 0; //Value to be returned + for (uint8_t i = 0; i< 8; i++)//Loop to read the whole byte + { + byte >>= 1; //Shift the byte at one bit to the right + if (ds18b20_read_bit()) //If 1 has been read + byte |= 0x80; //Then add it to the byte + } + return (byte); +} + + +// DS18B20 high-level functions +void ds18b20_start_conversion(void) { + ds18b20_reset(); + delay_ms(1); + ds18b20_write_byte(0xCC); // Skip ROM + delay_ms(1); + ds18b20_write_byte(0x44); // Start conversion + delay_ms(1); +} + +int16_t ds18b20_read_temperature(void) { + uint8_t temp_lsb, temp_msb; + uint8_t temperature[2]; + int8_t digit; + uint16_t decimal; + + int16_t temp; + ds18b20_reset(); + ds18b20_write_byte(0xCC); // Skip ROM + ds18b20_write_byte(0xBE); // Read scratchpad + temp = ds18b20_read_byte(); + temp |= (uint16_t)(ds18b20_read_byte() << 8); + +// temperature[0] = ds18b20_read_byte(); +// temperature[1] = ds18b20_read_byte(); + + ds18b20_reset(); +// temp = (temp_msb << 8) | temp_lsb; + +// digit=temperature[0]>>4; +// digit|=(temperature[1]&0x7)<<4; + //Store decimal digits +// decimal=temperature[0]&0xf; +// decimal*=625; + +// temp = (digit * 1000) + decimal; + + //return temp * 0.0625; // Convert to Celsius +// return temp; // Convert to Celsius +// return digit; + + if (temp & 0x8000) { // Check if the sign bit (MSB) is set + temp = -(int16_t)((~temp + 1) & 0xFFFF); // Two's complement unary conversion + } + + return (temp * 625) / 10; +} \ No newline at end of file