From 3673e4059b389b83daf948d88271129853ce5453 Mon Sep 17 00:00:00 2001 From: Chuck McManis Date: Fri, 12 Jul 2013 19:24:39 -0700 Subject: [PATCH] This is a demo that uses the System Tick counter in the STM32F4 as a way of creating accurately timed delays. A simple 'msleep' is implemented by watching the system clock to wait a certain number of milleseconds before it returns. Its a bit more accurate than a for loop, although it really shines when your running multiple threads. --- .../f4/stm32f4-discovery/tick_blink/Makefile | 25 +++++ .../f4/stm32f4-discovery/tick_blink/README | 8 ++ .../stm32f4-discovery/tick_blink/tick_blink.c | 91 +++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 examples/stm32/f4/stm32f4-discovery/tick_blink/Makefile create mode 100644 examples/stm32/f4/stm32f4-discovery/tick_blink/README create mode 100644 examples/stm32/f4/stm32f4-discovery/tick_blink/tick_blink.c diff --git a/examples/stm32/f4/stm32f4-discovery/tick_blink/Makefile b/examples/stm32/f4/stm32f4-discovery/tick_blink/Makefile new file mode 100644 index 0000000..4d24e12 --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/tick_blink/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = tick_blink + +LDSCRIPT = ../stm32f4-discovery.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f4/stm32f4-discovery/tick_blink/README b/examples/stm32/f4/stm32f4-discovery/tick_blink/README new file mode 100644 index 0000000..a407c54 --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/tick_blink/README @@ -0,0 +1,8 @@ +README +------ + +This example is the same as fancy_blink except that it uses the +systick timer to generate time accurate delays. Shows how to set +up the systick timer to create an interrupt every millisecond and +how to write a delay routine (msleep) that can then delay for a +specific number of milliseconds. diff --git a/examples/stm32/f4/stm32f4-discovery/tick_blink/tick_blink.c b/examples/stm32/f4/stm32f4-discovery/tick_blink/tick_blink.c new file mode 100644 index 0000000..1d92f4e --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/tick_blink/tick_blink.c @@ -0,0 +1,91 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Damjan Marion + * Copyright (C) 2011 Mark Panajotovic + * Copyright (C) 2013 Chuck McManis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* This version derived from fancy blink */ + +#include +#include +#include +#include + +void msleep(uint32_t); + +/* monotonically increasing number of milliseconds from reset + * overflows every 49 days if you're wondering + */ +volatile uint32_t system_millis; + +/* Called when systick fires */ +void sys_tick_handler(void) { + system_millis++; +} + +/* sleep for delay milliseconds */ +void msleep(uint32_t delay) { + uint32_t wake = system_millis + delay; + while (wake > system_millis) ; +} + +/* Set up a timer to create 1mS ticks. */ +static void systick_setup(void) +{ + /* clock rate / 1000 to get 1mS interrupt rate */ + systick_set_reload(168000); + systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB); + systick_counter_enable(); + /* this done last */ + systick_interrupt_enable(); +} + +/* Set STM32 to 168 MHz. */ +static void clock_setup(void) +{ + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]); + + /* Enable GPIOD clock. */ + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); +} + +static void gpio_setup(void) +{ + /* Set GPIO11-15 (in GPIO port D) to 'output push-pull'. */ + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15); +} + +int main(void) +{ + clock_setup(); + gpio_setup(); + systick_setup(); + + /* Set two LEDs for wigwag effect when toggling. */ + gpio_set(GPIOD, GPIO12 | GPIO14); + + /* Blink the LEDs (PD12, PD13, PD14 and PD15) on the board. */ + while (1) { + gpio_toggle(GPIOD, GPIO12 | GPIO13 | GPIO14 | GPIO15); + msleep(100); + } + + return 0; +}