Add ds18b20.c
This commit is contained in:
parent
879f5d639a
commit
4e65640929
|
@ -0,0 +1,167 @@
|
|||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
#include <libopencm3/cm3/systick.h>
|
||||
#include <stdint.h>
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue