From 9c28d33e41a59ef9312a54c2ff556d61b54893a9 Mon Sep 17 00:00:00 2001 From: Arti Zirk Date: Sun, 22 Aug 2021 22:31:36 +0300 Subject: [PATCH] Add 7 segment display --- .editorconfig | 1 + main.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index 280cd99..c2536c5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,3 +6,4 @@ end_of_line = lf insert_final_newline = true indent_style = tab indent_size = 4 + diff --git a/main.c b/main.c index 232f96a..c8db0c4 100644 --- a/main.c +++ b/main.c @@ -31,6 +31,51 @@ #define DHT_PORT GPIOB #define DHT_PIN GPIO0 +#define SEGMENT_PORT GPIOA +#define SEGMENT_A GPIO7 +#define SEGMENT_B GPIO5 +#define SEGMENT_C GPIO2 +#define SEGMENT_D GPIO0 +#define SEGMENT_E GPIO1 +#define SEGMENT_F GPIO3 +#define SEGMENT_G GPIO6 +#define SEGMENT_DOT GPIO4 +#define SEGMENT_ALL GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO6 | GPIO7 | GPIO4 +#define COMMON_PORT GPIOB +#define COMMON_ALL GPIO15 | GPIO14 | GPIO13 | GPIO12 | GPIO11 +#define COMMON_1 GPIO15 +#define COMMON_2 GPIO14 +#define COMMON_3 GPIO13 +#define COMMON_4 GPIO12 +#define COMMON_L GPIO11 + +const uint16_t segment_numbers[] = { + SEGMENT_A | SEGMENT_B | SEGMENT_C | SEGMENT_D | SEGMENT_E | SEGMENT_F, // 0 + SEGMENT_B | SEGMENT_C, // 1 + SEGMENT_A | SEGMENT_B | SEGMENT_D | SEGMENT_E | SEGMENT_G, // 2 + SEGMENT_A | SEGMENT_B | SEGMENT_C | SEGMENT_D | SEGMENT_G, // 3 + SEGMENT_B | SEGMENT_C | SEGMENT_F | SEGMENT_G, // 4 + SEGMENT_A | SEGMENT_C | SEGMENT_D | SEGMENT_F | SEGMENT_G, // 5 + SEGMENT_A | SEGMENT_C | SEGMENT_D | SEGMENT_E | SEGMENT_F | SEGMENT_G, // 6 + SEGMENT_A | SEGMENT_B | SEGMENT_C, // 7 + SEGMENT_A | SEGMENT_B | SEGMENT_C | SEGMENT_D | SEGMENT_E | SEGMENT_F | SEGMENT_G, // 8 + SEGMENT_A | SEGMENT_B | SEGMENT_C | SEGMENT_D | SEGMENT_F | SEGMENT_G, // 9 + SEGMENT_A | SEGMENT_B | SEGMENT_C | SEGMENT_E | SEGMENT_F | SEGMENT_G, // A 10 + SEGMENT_C | SEGMENT_D | SEGMENT_E | SEGMENT_F | SEGMENT_G, // B 11 + SEGMENT_A | SEGMENT_D | SEGMENT_E | SEGMENT_F, // C 12 + SEGMENT_B | SEGMENT_C | SEGMENT_D | SEGMENT_E | SEGMENT_G, // D 13 + SEGMENT_A | SEGMENT_D | SEGMENT_E | SEGMENT_F | SEGMENT_G, // E 14 + SEGMENT_A | SEGMENT_E | SEGMENT_F | SEGMENT_G, // F 15 + SEGMENT_B | SEGMENT_C | SEGMENT_E | SEGMENT_F | SEGMENT_G, // H 16 + SEGMENT_G // - 17 +}; + +const uint16_t common_numbers[] = { COMMON_1, COMMON_2, COMMON_3, COMMON_4 }; + +volatile int segment_values[] = {17, 17, 17, 17}; +volatile int common_counter = 0; + + enum DHT11_STATE { DHT11_STOP, // Stop statemachine DHT11_START, // We drive DATA Low for minimum 18ms and then drive it HIGH and start waiting for response @@ -62,6 +107,7 @@ static void gpio_setup(void) /* Manually: */ // RCC_APB2ENR |= RCC_APB2ENR_IOPCEN; /* Using API functions: */ + rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOB); /* Set GPIO5 (in GPIO port A) to 'output push-pull'. */ @@ -75,14 +121,35 @@ static void gpio_setup(void) gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); // A random DEBUG pin we can toggle and measure with logic gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); + + + // 7segments + gpio_set_mode(SEGMENT_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, SEGMENT_ALL); + // commons + gpio_set_mode(COMMON_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, COMMON_ALL); } // Onetime config of timer things that stay the same static void tim_setup(void) { - nvic_enable_irq(NVIC_TIM3_IRQ); - nvic_set_priority(NVIC_TIM3_IRQ, 1); // interrupts will not work without it??? + // 7 segment driver timer + nvic_enable_irq(NVIC_TIM2_IRQ); + nvic_set_priority(NVIC_TIM2_IRQ, 2); + rcc_periph_clock_enable(RCC_TIM2); + rcc_periph_reset_pulse(RST_TIM2); + timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + timer_set_prescaler(TIM2, (rcc_apb1_frequency*2) / 1000000 - 1); // set timer tickrate to 1mhz + timer_set_period(TIM2, 3000); // 1 ms + timer_enable_irq(TIM2, TIM_DIER_UIE); + + // start displaying 7 segment numbers + timer_enable_counter(TIM2); + + + // DHT11 Reading timer + nvic_enable_irq(NVIC_TIM3_IRQ); + nvic_set_priority(NVIC_TIM3_IRQ, 1); rcc_periph_clock_enable(RCC_TIM3); rcc_periph_reset_pulse(RST_TIM3); @@ -93,6 +160,26 @@ static void tim_setup(void) timer_enable_irq(TIM3, TIM_DIER_UIE); // overflow timer_enable_irq(TIM3, TIM_DIER_CC3IE); // triggered when DHT drives DATA pin + // timer is enabled in dht_start() +} + +static void show_segment_value(int common, int value, bool decimal) { + gpio_clear(COMMON_PORT, COMMON_ALL); + gpio_set(SEGMENT_PORT, SEGMENT_ALL); + gpio_clear(SEGMENT_PORT, segment_numbers[value] | (decimal ? SEGMENT_DOT : 0)); + gpio_set(COMMON_PORT, common_numbers[common]); +} + +void tim2_isr(void) { + if (timer_get_flag(TIM2, TIM_SR_UIF)) { + timer_clear_flag(TIM2, TIM_SR_UIF); + show_segment_value(common_counter, segment_values[common_counter], + common_counter == 1 ? true : false); + common_counter++; + if (common_counter > 3){ + common_counter = 0; + } + } } void tim3_isr(void) @@ -227,6 +314,17 @@ static void dht_parse_data(void) { if (checksum == data[4]) { SEGGER_RTT_printf(0, "Humidity: %d.%d%%; Temperature: %d.%dC\n", data[0], data[1], data[2], data[3]); + if (segment_values[3] == 0xC) { + segment_values[3] = 16; // now showing humidity + segment_values[0] = (data[0] / 10) % 10; + segment_values[1] = data[0] % 10; + segment_values[2] = data[1] % 10; + } else { + segment_values[3] = 0xC; // now showing temperature + segment_values[0] = (data[2] / 10) % 10; + segment_values[1] = data[2] % 10; + segment_values[2] = data[3] % 10; + } } else { SEGGER_RTT_printf(0, "Checksum did not match, %x != %x\n", checksum, data[4]); } @@ -256,10 +354,12 @@ int main(void) /* Blink the LED (PA5) on the board. */ while (1) { /* Using API function gpio_toggle(): */ - gpio_toggle(GPIOB, GPIO1); /* LED on/off */ + //gpio_toggle(GPIOB, GPIO1); /* LED on/off */ + SEGGER_RTT_printf(0, "Poll: %d, seg: %d\n", i, i & 0xf); + //show_segment_value(i & 3, 16, false); i++; - SEGGER_RTT_printf(0, "Poll: %d\n", i); delay(10000000); + //delay(1000000); dht_start(); wait = true; while (wait) {