en.radzio.dxp.pl

Finally, let's blink the LED!
After informations from previous pages we can write our blinking LED application.

How to make a delay?
Simplest way to make a delay (let's call 'monkey delay') is loop counting some many times. Time of this delay it's hard to define. Especially on ARM devices counting how CPU cycles loop will be executed is difficult. Let's define variable named dly :

volatile uint32_t dly;

Short explain about two keywords before variable name. An 'volatile' keyword says to compiler "Don't optimize access to this variable. Its value can change in any time of execution of program". Second keyword define size of variable - 32-bit unsigned integer. Now, let's do a simple loop using this variable :

for(dly = 0; dly < 500000; dly++);

This code give us 500.000 loop cycles, that in effect give us some time of CPU spending in the loop. Without keyword 'volatile' this code probably give us no cycles and no time delay.

Complete code of blink LED application :

//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 1. Blinking the LED.
// Copyright : Radoslaw Kwiecien
// http://en.radzio.dxp.pl
// e-mail : radek(at)dxp.pl
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// main function
//=============================================================================
int main(void)
{
volatile uint32_t dly;

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

GPIOC->CRH = (GPIOC->CRH & CONFMASKH(8)) | GPIOPINCONFH(8, GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));

while (1) {
for(dly = 0; dly < 500000; dly++);
GPIOC->BSRR = (1 << 8);
for(dly = 0; dly < 500000; dly++);
GPIOC->BRR = (1 << 8);
}
}
//=============================================================================
// End of file
//=============================================================================

How to make this code more universal? When LED diode will be connected to other pin, we need modify in code all references to them. So let's use the preprocessor to define some macros describing connected LED diode :

#define LED_BLUE_GPIO  GPIOC
#define LED_BLUE_PIN   8

Now we can use defined macros in place to direct GPIO and pin number, but in case of configure GPIO there is need to specify configuration register (low or high). We can do this like in example :

#if (LED_BLUE_PIN > 7)
    LED_BLUE_GPIO->CRH = (LED_BLUE_GPIO->CRH & CONFMASKH(LED_BLUE_PIN)) |       GPIOPINCONFH(LED_BLUE_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
#else
    LED_BLUE_GPIO->CRL = (LED_BLUE_GPIO->CRL & CONFMASKL(LED_BLUE_PIN)) |       GPIOPINCONFL(LED_BLUE_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
#endif

The #if is preprocessor conditional directive, not the C language conditional instruction, so before compilation the preprocessor depending on value of LED_BLUE_PIN choose proper source code line and place them on source code file that will be compiled. Now, to turn LED on we can use following sequence :

GPIOC->BSRR = (1 << LED_BLUE_PIN);

and for turn led OFF :

GPIOC->BRR = (1 << LED_BLUE_PIN);

Complete source code :

//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 1. Blinking the LED.
// Copyright : Radoslaw Kwiecien
// http://en.radzio.dxp.pl
// e-mail : radek(at)dxp.pl
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN  8
//=============================================================================
// main function
//=============================================================================
int main(void)
{
volatile uint32_t dly;

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

#if (LED_BLUE_PIN > 7)
  LED_BLUE_GPIO->CRH = (LED_BLUE_GPIO->CRH & CONFMASKH(LED_BLUE_PIN)) | GPIOPINCONFH(LED_BLUE_PIN,     GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
#else
  LED_BLUE_GPIO->CRL = (LED_BLUE_GPIO->CRL & CONFMASKL(LED_BLUE_PIN)) | GPIOPINCONFL(LED_BLUE_PIN,     GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
#endif

while (1) {
  for(dly = 0; dly < 300000; dly++);
  LED_BLUE_GPIO->BSRR = (1 << LED_BLUE_PIN);
  for(dly = 0; dly < 300000; dly++);
  LED_BLUE_GPIO->BRR = (1 << LED_BLUE_PIN);
}
}
//=============================================================================
// End of file
//=============================================================================

 

 

 

 

 
(c) Radosław Kwiecień