#include "main.h" #include "generic_macros.h" #include "dht11.h" static struct SysTickConfig stc; static uint32_t *systick_base = (uint32_t *) SysTick_BASE; static void wait(uint32_t wait_us) { int target_time = *(systick_base+8); target_time -= wait_us << 4; while (*(systick_base+8) > target_time) {} } static void dht11_save_systick_state(void) { stc.ctrl = *(systick_base + 0); stc.load = *(systick_base + 4); stc.val = *(systick_base + 8); } static void dht11_load_systick_state(void) { *(systick_base + 4) = stc.load; *(systick_base + 8) = stc.val; *(systick_base + 0) = stc.ctrl; } static void dht11_init_systick(void) { dht11_save_systick_state(); *(systick_base + 0) = 0x5; // disable /8 prescaler, no interrupts, enable counting *(systick_base + 4) = 0xFFFFFF; // load largest possible value // verify value load if (*(systick_base + 8) == 0) PANIC(0x4000); } static size_t dht11_measure_high_duration(void) { int current_time = *(systick_base+8); SKIP_HIGH; // elapsed_time > 49us ? 1 : 0 return (current_time - *(systick_base+8)) > (49 << 4); } static void dht11_read_value(struct DHT11_Data *data) { dht11_init_systick(); register uint8_t read_register = 0; 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 // switch GPIOD 11 to input mode GPIOD->MODER &= 0xFF3FFFFF; // read transmission start sequence from DHT11 SKIP_HIGH; SKIP_LOW; SKIP_HIGH; // read humidity integral FILL_REGISTER; data->humid_integral = read_register; // read humidity decimal FILL_REGISTER; data->humid_decimal = read_register; // read temperature integral FILL_REGISTER; data->temp_integral = read_register; // read temperature decimal FILL_REGISTER; data->temp_decimal = read_register; // read crc FILL_REGISTER; data->crc = read_register; dht11_load_systick_state(); } void dht11_show_both(void) { struct DHT11_Data data; dht11_read_value(&data); }