diff --git a/Core/Inc/DHT11.h b/Core/Inc/DHT11.h new file mode 100644 index 0000000..e9a62be --- /dev/null +++ b/Core/Inc/DHT11.h @@ -0,0 +1,18 @@ +#ifndef __DHT11 +#define __DHT11 + +#define SKIP_LOW while (!(GPIOD->IDR & 0x0800)) {} +#define SKIP_HIGH while (GPIOD->IDR & 0x0800) {} + +__attribute__((packed)) +struct DHT11_Data { + uint8_t humid_integral; + uint8_t humid_decimal; + uint8_t temp_integral; + uint8_t temp_decimal; + uint8_t crc; +}; + +int DHT11_run_test(void); + +#endif diff --git a/Core/Src/DHT11.c b/Core/Src/DHT11.c new file mode 100644 index 0000000..16392b5 --- /dev/null +++ b/Core/Src/DHT11.c @@ -0,0 +1,113 @@ +#include "main.h" +#include "generic_macros.h" +#include "lcd.h" +#include "DHT11.h" + +extern TIM_HandleTypeDef htim2; + +static inline void wait(uint32_t wait_us) +{ + uint32_t target_time = TIM2->CNT; + target_time += wait_us << 4; + + while (TIM2->CNT < target_time) {} +} + +static inline size_t dht11_measure_high_duration(void) +{ + SKIP_LOW; + uint32_t start_time = TIM2->CNT; + SKIP_HIGH; + uint32_t end_time = TIM2->CNT; + + // elapsed_time > 49us ? 1 : 0 + return (end_time - start_time) > (49 << 4); +} + +static size_t dht11_read_value(struct DHT11_Data *data) +{ + // treat data as a normal array to simplify read loop + uint8_t *buffer = (uint8_t *) data; + + register uint32_t read_register = 0; + + TIM2->CNT = 0; + HAL_TIM_Base_Start(&htim2); + + GPIOD->MODER |= 0x00400000; // enable output mode on GPIOD 11 + + GPIOD->BSRR = GPIO_PIN_11; // enable DHT11 + wait(50000); // hold HIGH for 50 ms + GPIOD->BSRR = GPIO_PIN_11 << 16; // start signal + wait(30000); // hold it for 30 ms + GPIOD->BSRR = GPIO_PIN_11; // pull up, DHT will now take control over the connection + + wait(100); + GPIOD->MODER &= 0xFF3FFFFF; // switch GPIOD 11 to input mode + + // reading pull down from DHT11 + SKIP_LOW; + + // waiting for 500ms max + for (size_t i = TIM2->CNT + (500000 << 4); TIM2->CNT <= i; ) + if (!(GPIOD->IDR & 0x0800)) + goto reading_data; + + // if didn't exit through goto, then DHT11 awaiting has timed out + return 1; + +reading_data: + // read 5 bytes of data + for (size_t i = 0; i < 5; i++) { + for (register size_t j = 0; j < 8; j++) { + read_register <<= 1; + read_register |= dht11_measure_high_duration(); + } + + buffer[i] = (uint8_t) read_register; + } + + HAL_TIM_Base_Stop(&htim2); + + return 0; +} + +int DHT11_run_test(void) +{ + DISPLAY_CLEAR; + display_write_data_seq("DHT11 Temp+Humid"); + + struct DHT11_Data data; + size_t result = dht11_read_value(&data); + + size_t checksum_mismatch = (( + data.humid_decimal + + data.humid_integral + + data.temp_decimal + + data.temp_integral + ) & 0xFF) != data.crc; + + if (result) { + DISPLAY_SET_CURSOR(1, 4); + display_write_data_seq("StartTimeout"); + } else if (checksum_mismatch) { + DISPLAY_SET_CURSOR(1, 4); + display_write_data_seq("CRC Fault"); + } else { + DISPLAY_SET_CURSOR(1, 4); + display_write_data_seq("OK"); + + DISPLAY_SET_CURSOR(1, 7); + display_write_data_byte('0' + (data.humid_integral/10)%10); + display_write_data_byte('0' + (data.humid_integral)%10); + display_write_data_seq("% "); + + display_write_data_byte('0' + (data.temp_integral/10)%10); + display_write_data_byte('0' + (data.temp_integral)%10); + display_write_data_byte('.'); + display_write_data_byte('0' + data.temp_decimal); + display_write_data_seq("C"); + } + + return (result || checksum_mismatch); +} diff --git a/Core/Src/main.c b/Core/Src/main.c index d6c4f4c..0a62fed 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -32,6 +32,7 @@ #include "LIS302DL.h" #include "MP45DT02.h" #include "LSM9DS1.h" +#include "DHT11.h" /* USER CODE END Includes */ @@ -75,10 +76,10 @@ SPI_HandleTypeDef hspi1; TIM_HandleTypeDef htim2; -extern size_t display_current_frame; - /* USER CODE BEGIN PV */ +extern size_t display_current_frame; + static const int ((*executors[])(void)) = { DNI_show_celsius, PCA9685_run_test, @@ -88,7 +89,8 @@ static const int ((*executors[])(void)) = { LIS302DL_run_test, MP45DT02_run_test, LSM9DS1_test_accel, - LSM9DS1_test_magnet + LSM9DS1_test_magnet, + DHT11_run_test }; static const void ((*cleanup_functions[])(void)) = { @@ -100,6 +102,7 @@ static const void ((*cleanup_functions[])(void)) = { NULL, NULL, LSM9DS1_cleanup_accel, + NULL, NULL }; @@ -568,10 +571,17 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); - /*Configure GPIO pins : PD11 PD12 PD13 PD14 - PD15 PD4 PD7 */ - GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 - |GPIO_PIN_15|GPIO_PIN_4|GPIO_PIN_7; + /*Configure GPIO pin : PD11 */ + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /*Configure GPIO pins : PD12 PD13 PD14 PD15 + PD4 PD7 */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 + |GPIO_PIN_4|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; diff --git a/test1.ioc b/test1.ioc index 6d4604d..571959d 100644 --- a/test1.ioc +++ b/test1.ioc @@ -121,6 +121,8 @@ PC8.Locked=true PC8.Signal=GPIO_Input PC9.Locked=true PC9.Signal=GPIO_Input +PD11.GPIOParameters=GPIO_Speed +PD11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PD11.Locked=true PD11.Signal=GPIO_Output PD12.Locked=true