From aa65f9556f277c5aeca9e57efd09c0a30aa02f39 Mon Sep 17 00:00:00 2001 From: IOsetting Date: Sat, 4 Jun 2022 14:57:34 +0800 Subject: [PATCH] feat: add ds18b20 demo --- demo/gpio/ds18b20/ds18b20.c | 168 ++++++++++++++++++++++++++++ demo/gpio/ds18b20/ds18b20.h | 120 ++++++++++++++++++++ demo/gpio/ds18b20/ds18b20_stc8h3k.c | 52 +++++++++ 3 files changed, 340 insertions(+) create mode 100644 demo/gpio/ds18b20/ds18b20.c create mode 100644 demo/gpio/ds18b20/ds18b20.h create mode 100644 demo/gpio/ds18b20/ds18b20_stc8h3k.c diff --git a/demo/gpio/ds18b20/ds18b20.c b/demo/gpio/ds18b20/ds18b20.c new file mode 100644 index 0000000..81809e0 --- /dev/null +++ b/demo/gpio/ds18b20/ds18b20.c @@ -0,0 +1,168 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ds18b20.h" + +void DS18B20_Init(void) +{ + DS18B20_DQ_PULLUP(); + DS18B20_DQ_OUTPUT(); + DS18B20_DQ = SET; + SYS_DelayUs(1000); + DS18B20_DQ = RESET; + SYS_DelayUs(1000); + DS18B20_DQ = SET; + SYS_DelayUs(2000); +} + +__BIT DS18B20_Reset(void) +{ + __BIT b; + + /* Line low, and wait 480us */ + DS18B20_DQ = RESET; + DS18B20_DQ_OUTPUT(); + SYS_DelayUs(500); + /* Release line and wait for 70us */ + DS18B20_DQ_INPUT(); + SYS_DelayUs(70); + /* Check bit value, success if low */ + b = DS18B20_DQ; + /* Delay for 410 us */ + SYS_DelayUs(410); + /* Return value of presence pulse, 0 = OK, 1 = ERROR */ + return b; +} + +__BIT DS18B20_ReadBit(void) +{ + __BIT b = RESET; + + /* Line low */ + DS18B20_DQ = RESET; + DS18B20_DQ_OUTPUT(); + SYS_DelayUs(2); + + /* Release line */ + DS18B20_DQ_INPUT(); + SYS_DelayUs(10); + + /* Read line value */ + if (DS18B20_DQ) { + /* Bit is HIGH */ + b = SET; + } + + /* Wait 50us to complete 60us period */ + SYS_DelayUs(50); + + /* Return bit value */ + return b; +} + +uint8_t DS18B20_ReadByte(void) +{ + uint8_t i = 8, byte = 0; + while (i--) + { + byte >>= 1; + byte |= (DS18B20_ReadBit() << 7); + } + return byte; +} + +void DS18B20_WriteBit(__BIT b) +{ + if (b) + { + /* Set line low */ + DS18B20_DQ = RESET; + DS18B20_DQ_OUTPUT(); + SYS_DelayUs(10); + + /* Bit high */ + DS18B20_DQ_INPUT(); + + /* Wait for 55 us and release the line */ + SYS_DelayUs(55); + DS18B20_DQ_INPUT(); + } + else + { + /* Set line low */ + DS18B20_DQ = RESET; + DS18B20_DQ_OUTPUT(); + SYS_DelayUs(65); + + /* Bit high */ + DS18B20_DQ_INPUT(); + + /* Wait for 5 us and release the line */ + SYS_DelayUs(5); + DS18B20_DQ_INPUT(); + } + +} + +void DS18B20_WriteByte(uint8_t byte) +{ + uint8_t i = 8; + /* Write 8 bits */ + while (i--) + { + /* LSB bit is first */ + DS18B20_WriteBit(byte & 0x01); + byte >>= 1; + } +} + +void DS18B20_StartAll(void) +{ + /* Reset pulse */ + DS18B20_Reset(); + /* Skip rom */ + DS18B20_WriteByte(ONEWIRE_CMD_SKIPROM); + /* Start conversion on all connected devices */ + DS18B20_WriteByte(DS18B20_CMD_CONVERTTEMP); +} + +__BIT DS18B20_AllDone(void) +{ + /* If read bit is low, then device is not finished yet with calculation temperature */ + return DS18B20_ReadBit(); +} + +uint16_t DS18B20_ReadTemperature(void) +{ + uint16_t temperature; + uint8_t i = 0; + uint8_t data[9]; + + /* Reset line */ + DS18B20_Reset(); + /* Skip ROM */ + DS18B20_WriteByte(ONEWIRE_CMD_SKIPROM); + /* Read scratchpad command by onewire protocol */ + DS18B20_WriteByte(ONEWIRE_CMD_RSCRATCHPAD); + + /* Get data */ + for (i = 0; i < 9; i++) + { + /* Read byte by byte */ + data[i] = DS18B20_ReadByte(); + } + temperature = data[1]; + temperature = temperature << 8 | data[0]; + return temperature; +} diff --git a/demo/gpio/ds18b20/ds18b20.h b/demo/gpio/ds18b20/ds18b20.h new file mode 100644 index 0000000..94c74ca --- /dev/null +++ b/demo/gpio/ds18b20/ds18b20.h @@ -0,0 +1,120 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __FW_DS18B20__ +#define __FW_DS18B20__ + +#include "fw_hal.h" + +/** + * DS18B20 - Programmable Resolution 1-Wire Digital Thermometer + * + * To-92 Pins: + * With the flat side facing you and with the leads pointing down, they are GND, DQ and Vdd + * +*/ + +#define DS18B20_DQ P35 +#define DS18B20_DQ_PULLUP() GPIO_SetPullUp(GPIO_Port_3, GPIO_Pin_5, HAL_State_ON) +#define DS18B20_DQ_INPUT() GPIO_P3_SetMode(GPIO_Pin_5, GPIO_Mode_Input_HIP) +#define DS18B20_DQ_OUTPUT() GPIO_P3_SetMode(GPIO_Pin_5, GPIO_Mode_InOut_OD) +#define DS18B20_DQ_LOW() DS18B20_DQ=RESET +#define DS18B20_DQ_HIGH() DS18B20_DQ=SET + +/* OneWire commands */ +#define ONEWIRE_CMD_RSCRATCHPAD 0xBE +#define ONEWIRE_CMD_WSCRATCHPAD 0x4E +#define ONEWIRE_CMD_CPYSCRATCHPAD 0x48 +#define ONEWIRE_CMD_RECEEPROM 0xB8 +#define ONEWIRE_CMD_RPWRSUPPLY 0xB4 +#define ONEWIRE_CMD_SEARCHROM 0xF0 +#define ONEWIRE_CMD_READROM 0x33 +#define ONEWIRE_CMD_MATCHROM 0x55 +#define ONEWIRE_CMD_SKIPROM 0xCC + +#define DS18B20_FAMILY_CODE 0x28 +#define DS18B20_CMD_ALARMSEARCH 0xEC + +/* DS18B20 read temperature command */ +#define DS18B20_CMD_CONVERTTEMP 0x44 /* Convert temperature */ +#define DS18B20_DECIMAL_STEPS_12BIT 0.0625 +#define DS18B20_DECIMAL_STEPS_11BIT 0.125 +#define DS18B20_DECIMAL_STEPS_10BIT 0.25 +#define DS18B20_DECIMAL_STEPS_9BIT 0.5 + +/* Bits locations for resolution */ +#define DS18B20_RESOLUTION_R1 6 +#define DS18B20_RESOLUTION_R0 5 + +typedef enum { + DS18B20_Resolution_9bits = 9, /*!< DS18B20 9 bits resolution */ + DS18B20_Resolution_10bits = 10, /*!< DS18B20 10 bits resolution */ + DS18B20_Resolution_11bits = 11, /*!< DS18B20 11 bits resolution */ + DS18B20_Resolution_12bits = 12 /*!< DS18B20 12 bits resolution */ +} DS18B20_Resolution_t; + +/** + * @brief Initialize DS18B20 + */ +void DS18B20_Init(void); + +/** + * @brief Reset DS18B20 + * @return bit value + */ +__BIT DS18B20_Reset(void); + +/** + * @brief Read one bit from DS18B20 + * @return bit value + */ +__BIT DS18B20_ReadBit(void); + +/** + * @brief Read one byte from DS18B20 + * @return byte value + */ +uint8_t DS18B20_ReadByte(void); + +/** + * @brief Write one bit to DS18B20 + * @param b bit value + */ +void DS18B20_WriteBit(__BIT b); + +/** + * @brief Write one byte to DS18B20 + * @param byte byte value + */ +void DS18B20_WriteByte(uint8_t byte); + +/** + * @brief Start all DS18B20 + */ +void DS18B20_StartAll(void); + +/** + * @brief If read bit is low, then device is not finished yet with calculation temperature + * @return bit value + */ +__BIT DS18B20_AllDone(void); + +/** + * @brief Read 16 bits temperature + * @return temperature value + */ +uint16_t DS18B20_ReadTemperature(void); + + +#endif // __DS18B20_H_ diff --git a/demo/gpio/ds18b20/ds18b20_stc8h3k.c b/demo/gpio/ds18b20/ds18b20_stc8h3k.c new file mode 100644 index 0000000..da77ad2 --- /dev/null +++ b/demo/gpio/ds18b20/ds18b20_stc8h3k.c @@ -0,0 +1,52 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*** + * Demo: DS18B20 + * Board: STC8H3K32 + * + * P35 -> DQ + * GND -> GND + * 3.3V -> VCC + */ + +#include "fw_hal.h" +#include "ds18b20.h" + +uint16_t temp; + +int main(void) +{ + uint16_t temperature; + + SYS_SetClock(); + // UART1, baud 115200, baud source Timer1, 1T mode, no interrupt + UART1_Config8bitUart(UART1_BaudSource_Timer1, HAL_State_ON, 115200); + DS18B20_Init(); + + while(1) + { + DS18B20_StartAll(); + while (!DS18B20_AllDone()) + { + UART1_TxChar('.'); + SYS_Delay(1); + } + temperature = DS18B20_ReadTemperature(); + UART1_TxHex(temperature >> 8); + UART1_TxHex(temperature & 0xFF); + UART1_TxString("\r\n"); + SYS_Delay(1000); + } +}