/src/hardware/sht11/sht11.c
C | 360 lines | 286 code | 46 blank | 28 comment | 26 complexity | bc1169bab3c0ae072872c134df4e576d MD5 | raw file
- #include "main.h"
- #include "sht11_config.h"
- #include "sht11.h"
- #define SHT11_CMD_TEMP 0x03
- #define SHT11_CMD_HUMID 0x05
- #define SHT11_CMD_WSTAT 0x06
- #define SHT11_CMD_RSTAT 0x07
- #define SHT11_CMD_RESET 0x1E
- /////////////////////////////////////////////////////////////////////////////
- // This version needs external pullups on SDA!
- /////////////////////////////////////////////////////////////////////////////
- static void delay(void) { uint8_t i; for(i = 0; i<25;i++); }
- #define scl_hi GPIO_SetBits(SHT11_SCK_GPIO_PORT, SHT11_SCK_PIN)
- #define scl_lo GPIO_ResetBits(SHT11_SCK_GPIO_PORT, SHT11_SCK_PIN)
- static void sda_hi(void) {
- GPIO_InitTypeDef GPIO_InitStructure;
- //SHT11_SDA_GPIO_PORT->MODER &= ~(GPIO_MODER_MODER6_0);
- //SHT11_SDA_GPIO_PORT->PUPDR &= ~(GPIO_PUPDR_PUPDR6);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
- GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
- }
- static void sda_lo(void) {
- GPIO_InitTypeDef GPIO_InitStructure;
- //SHT11_SDA_GPIO_PORT->MODER |= GPIO_MODER_MODER6_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
- GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
- }
- static void scl_pulse(void) { scl_hi; delay(); scl_lo; }
- static uint8_t sda_val(void) { return GPIO_ReadInputDataBit(SHT11_SDA_GPIO_PORT,SHT11_SDA_PIN) != Bit_RESET; }
- /////////////////////////////////////////////////////////////////////////////
- static uint8_t crc_value;
- static uint8_t sht11_state;
- static uint16_t sht11_hum_raw=0,
- sht11_tmp_raw=0;
- static int16_t sht11_hum=0,
- sht11_tmp=0;
-
- static void
- crc8(uint8_t b)
- {
- uint8_t i;
- for (i = 0; i < 8; ++i) {
- if ((crc_value ^ b) & 0x80) {
- crc_value <<= 1;
- crc_value ^= 0x31;
- } else
- crc_value <<= 1;
- b <<= 1;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- static uint8_t
- send(uint16_t b)
- {
- crc8(b);
-
- // data
- uint8_t i;
- for (i = 0; i < 8; ++i) {
- if (b & 0x80)
- sda_hi();
- else
- sda_lo();
- b <<= 1;
- delay();
- scl_pulse();
- }
- // acknowledge
- sda_hi();
- delay();
- uint8_t ack = sda_val();
- scl_pulse();
- return ack;
- }
- static uint8_t
- recv_data(void)
- {
- // data
- uint8_t b = 0;
- uint8_t i;
- for (i = 0; i < 8; ++i) {
- // data is transmitted MSB first
- b <<= 1;
- if (sda_val())
- b |= 1;
- scl_pulse();
- delay();
- }
- // lo acknowledge
- sda_lo();
- delay();
- scl_pulse();
- sda_hi();
- delay();
- crc8(b);
- return b;
- }
- static uint8_t
- recv_crc(void)
- {
- // data
- uint8_t b = 0;
- uint8_t i;
- for (i = 0; i < 8; ++i) {
- // CRC is transmitted LSB first
- b >>= 1;
- if (sda_val())
- b |= 0x80;
- scl_pulse();
- delay();
- }
- // hi acknowledge
- sda_hi();
- delay();
- scl_pulse();
- delay();
- return b;
- }
- static void
- start(void) {
- // reset communication
- uint8_t i;
- for (i = 0; i < 10; ++i) {
- scl_pulse();
- delay();
- }
- // "start" sequence
- scl_hi; delay();
- sda_lo(); delay();
- scl_lo; delay();
- scl_hi; delay();
- sda_hi(); delay();
- scl_lo; delay();
- }
- /////////////////////////////////////////////////////////////////////////////
- // Measurement sequence.
- uint8_t
- sht11_start_temp(void)
- {
- crc_value = SHT11_RESOLUTION << 7; // bit-reversed
- start();
- return send(SHT11_CMD_TEMP) == 0;
- }
- uint8_t
- sht11_start_humid(void)
- {
- crc_value = SHT11_RESOLUTION << 7; // bit-reversed
- start();
- return send(SHT11_CMD_HUMID) == 0;
- }
- uint8_t
- sht11_ready(void)
- {
- return sda_val() == 0;
- }
- int16_t
- result(void)
- {
- if (!sht11_ready())
- return SHT11_UNAVAIL;
- int16_t v = recv_data() << 8; v |= recv_data();
- uint8_t crc = recv_crc();
- if (crc != crc_value)
- return SHT11_CRC_FAIL;
- return v;
- }
- int16_t
- sht11_result_temp(void)
- {
- int16_t v = result();
- if (sht11_valid(v))
- {
- sht11_tmp_raw=(uint16_t)v;
- #if SHT11_RESOLUTION
- v = v * 4 - SHT11_TEMP_V_COMP;
- #else
- v -= SHT11_TEMP_V_COMP;
- #endif
- }
- return v;
- }
- int16_t
- sht11_result_humid(void)
- {
- int16_t v = result();
- if (sht11_valid(v))
- {
- sht11_hum_raw=(uint16_t)v;
- #if SHT11_RESOLUTION
- // inspired by Werner Hoch, modified for low resolution mode
- const int32_t C1 = (int32_t)(-4.0 * 100);
- const int32_t C2 = (int32_t)(0.648 * 100 * (1L<<24));
- const int32_t C3 = (int32_t)(-7.2e-4 * 100 * (1L<<24));
- v = (int16_t)((((C3 * v + C2) >> 7) * v + (1L<<16)) >> 17) + C1;
- const int32_t T1 = (uint32_t)(0.01 * (1L<<30));
- const int32_t T2 = (uint32_t)(0.00128 * (1L<<30));
- #else
- // inspired by Werner Hoch
- const int32_t C1 = (int32_t)(-4.0 * 100);
- const int32_t C2 = (int32_t)(0.0405 * 100 * (1L<<28));
- const int32_t C3 = (int32_t)(-2.8e-6 * 100 * (1L<<30));
- v = (int16_t)((((((C3 * v) >> 2) + C2) >> 11) * v + (1L<<16)) >> 17) + C1;
- const int32_t T1 = (uint32_t)(0.01 * (1L<<30));
- const int32_t T2 = (uint32_t)(0.00008 * (1L<<30));
- #endif
- // implemented by whitejack (temp compensation)
- v = (int16_t)( (((((int32_t)sht11_tmp-2500) * (int32_t)( (T1+T2*((int32_t)sht11_hum_raw)) >>13))>>17) + ((int32_t)v)) );
- }
- if(v>9999)v=9999;
- if(v<0001)v=0001;
- return v;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Initialize.
- void
- sht11_init(void) {
- GPIO_InitTypeDef GPIO_InitStructure;
- /*!< Enable GPIO clocks */
- RCC_AHB1PeriphClockCmd(SHT11_SDA_GPIO_CLK | SHT11_SCK_GPIO_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_InitStructure.GPIO_Pin = SHT11_SCK_PIN;
- GPIO_Init(SHT11_SCK_GPIO_PORT, &GPIO_InitStructure);
- scl_lo;
- GPIO_InitStructure.GPIO_Pin = SHT11_SDA_PIN;
- GPIO_Init(SHT11_SDA_GPIO_PORT, &GPIO_InitStructure);
- GPIO_ResetBits(SHT11_SDA_GPIO_PORT, SHT11_SDA_PIN);
- delay();
- start();
- send(SHT11_CMD_RESET);
- uint32_t i;
- for(i = 0; i<154000;i++); //_delay_ms(11);
- start();
- send(SHT11_CMD_WSTAT);
- send(SHT11_RESOLUTION); //set resolution
- sht11_state=SHT11_STATE_MEASURE_TMP;
- }
- /////////////////////////////////////////////////////////////////////////////
- // User.
- void sht11_start_measure(void)
- {
- if(sht11_state==SHT11_STATE_READY)
- {
- sht11_state=SHT11_STATE_MEASURE_TMP;
- }
- }
- uint8_t sht11_measure(void)
- {
- switch(sht11_state)
- {
- case SHT11_STATE_MEASURE_TMP:
- {
- sht11_start_temp();
- sht11_state = SHT11_STATE_CALC_TMP;
- }break;
- case SHT11_STATE_CALC_TMP:
- {
- if(sht11_ready())
- {
- sht11_tmp=sht11_result_temp();
- sht11_state = SHT11_STATE_MEASURE_HUM;
- }
- }break;
- case SHT11_STATE_MEASURE_HUM:
- {
- sht11_start_humid();
- sht11_state = SHT11_STATE_CALC_HUM;
- }break;
- case SHT11_STATE_CALC_HUM:
- {
- if(sht11_ready())
- {
- sht11_hum=sht11_result_humid();
- sht11_state = SHT11_STATE_READY;
- }
- }break;
- }
- return sht11_state;
- }
- uint8_t sht11_measure_finish(void)
- {
- if(sht11_measure()==SHT11_STATE_READY)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- uint16_t sht11_get_tmp_raw(void)
- {
- return sht11_tmp_raw;
- }
- uint16_t sht11_get_hum_raw(void)
- {
- return sht11_hum_raw;
- }
- int16_t sht11_get_tmp(void)
- {
- return sht11_tmp;
- }
- int16_t sht11_get_hum(void)
- {
- return sht11_hum;
- }