Mis primeros pasos con STM32 (I): Standard Peripheral Library

Tras algunos años experimentando con los microcontroladores de Atmel y con los ESP de Espressif voy a probar cosas nuevas. He empezadon con los STM32 de STMicroelectronics, en concreto un STM32103C8T6. Se trata de un microcontrolador ARM Cortex-M3, sus principales características son:

Características
Frecuencia 72 MHZ
Flash 64 kB (Hasta 128 kB)
RAM 20 kB SRAM
ADC 2 x 12-bit, 0 to 3,6 V
GPIO 80 (5 V tolerant)
Debug SWD & JTAG
Timers 7, 16-bit up to 4 IC/OC/PWM
Interfaces I2C, USART, SPI, CAN, USB 2.0
Otros 7-Channel DMA, 16-bit motor controller, 2 watchdog timers, RTC

Éste es el primer artículo de una serie dedicados a estos microcontroladores y diferentes plataformas. Para aprender esta familia de controladores he comprado una placa STM32 Smart V2.0, y la plataforma con la que voy a comenzar es la Standard Peripheral Library de ST.

La Standard Peripheral Library está escrita en ANSI-C e incluye los drivers y el API (rutinas, estructuras de datos y macros) para manejar todos los periféricos del microcotrolador. También incluye un sistema de detección de fallos en ejecución para facilitar la depuración. Incluye una colección de ejemplos que cubren todo el API y sus interfaces. En el repositorio se incluye el manual de la SPL.

Para empezar me he decidido por el Hello World de los microcontroladores: Hacer parpadear un LED. La placa STM32 Smart V2.0 tiene un LED conectado al pin GPIOC13, y es el que utilizo en el ejemplo.

#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>


void Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--); // nCount / Clock speed = seconds
}

// GPIO structure for port initialization
GPIO_InitTypeDef GPIO_InitStructure;

int main(void) {
    // enable clock on APB2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,  ENABLE);

    // configure port PC13 for driving an LED
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // highest speed
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    // output push-pull mode
    GPIO_Init(GPIOC, &GPIO_InitStructure);             // initialize port

    // main loop
    while(1) {
        GPIO_SetBits(GPIOC, GPIO_Pin_13);    // turn the LED on
        Delay(0x17D7840); // delay 500 ms

        GPIO_ResetBits(GPIOC, GPIO_Pin_13);  // turn the LED off
        Delay(0x17D7840); // delay 500 ms
    }
}

El repositorio incluye dos linker scripts, uno general para la familia STM32 y otro específico para STM32103C8T6. También incluye un Makefile, es muy básico aunque puede usarse para cualquier proyecto ya que compila todos los drivers. El Makefile tiene la opción upload, pensada para ser usado con stlink de texane. Para instala stlink necesitamos cmake, build-essentials y libusb-1.0.0-dev. Una tengamos esos paquetes clonamos el repositorio, compilamos e instalamos:

$ git clone https://github.com/texane/stlink.git $ cd stlink stlink$ make release stlink$ cd build/Release stlink/build/Release$ sudo make install

Esto instalará el los herramientas en /usr/local/bin y añadirá las reglas udev para el St-Link en etc/udev/rules.d. Por último hay que comprar que se ha creado un grupo stlink, y de no sear así crearlo, y añadir en el al usuario que va a utilizar el dispositivo:

$ sudo groupadd stlink $ sudo usermod -aG stlink $(whoami)

Para que los cambios surtan efecto, tanto las nuevas reglas udev como los cambios al usuario, recomiendo reiniciar el equipo.

Para conectar el programador a la placa:

En el caso de que la placa esté siendo alimentada por el USB no es necesario conectar vcc. Ahora, para cargar el firmware al STM32 utilizaremos el comando:

$ make upload

En el caso de que todo haya salido bien el LED que se encuentrar al lado de los pulsadores parpadeará.