Nivel: Básico
¿Qué tengo que saber para este post?
- Instalar Software en tu Sistema Operativo.
- Un poquito de Estructuras de microcontroladores.
- Un poquito de Electrónica digital.
- Programación en C.
- git (no necesariamente, pero voy a dejar en un repo el código).
—————————————
Qué, Cómo y porqué
En este pequeño rincón del ciberespacio les quiero dejar mi experiencia al programar un microcontrolador de 32-bits ARM Cortex-M3, para ello utilizaré solo Herramientas de Software Libre y obviamente desde GNU/Linux (aunque pueden utilizar OSX o Windows si quieren sufrir). Para ello me valdré de herramientas de Software que además de Libres son gratuitas y de Hardware extremadamente barato y práctico que funciona out-of-the-box sin necesidad de instalar nada adicional.
El Hardware que voy a utilizar ya tiene casi 10 años en el mercado es un STM32F103C8/B que para nuestra suerte viene ya soldado con todo lo que necesitamos en una placa de Open Hardware denominada Blue Pill que tiene el asequible precio de $2US (o menos) y un programador/debuger ST-Link V2 (chino clon) que ronda también los $2US. Es decir que por $4US~$5US ya tenemos todo lo que necesitamos en material de Hardware.
En cuanto al Software que utilizaré es una plataforma libre que se ha puesto en una de las más interesantes alternativas a IDEs pesados como eclipse o propietarias como Keil µVision. Antes la alternativa era customizar tu IDE favorito con las tool-chains necesarias (lo cual daba mucho trabajo). Sin más preámbulo: PlatformIO, una solución integrada muy valiosa (incluso si sos programador de Arduino), este es un plug-in que se puede instalar en power editors como Atom o VS Code como también en el IDE CLion de JetBrains (Google). La verdad yo lo utilizo en VS Code, pero son libres de elegir cualquiera de las alternativas.
Les dejaré el siguiente video donde pueden ver lo fácil que es instalar PlatformIO en VS Code (en Atom es prácticamente igual).
Tengo la Blue Pill, el ST-Link V2 y PlatformIO instalado, ¿y ahora qué? Ahora mi estimado lector, llegó el momento de que hablemos de la otra porción de Software a utilizar, que son las herramientas de desarrollo. Esta placa está Arduinizada es decir que la podemos usar con el Framework de Arduino, pero si alguna vez entraste a este blog, sabés que:
Acá nos ensuciamos las manos y tratamos de tomar el µC por las astas y lo programamos de la manera más profesional posible, sin perder de vista todo lo que ocurre y aprovechando los recursos al máximo, entendiendo instrucción por instrucción lo que pasa y deja de pasar en nuestro sistema. Y para ello utilizaré libOpenCM3, porque comparte la cultura libre y es un proyecto muy interesante que busca estandarizar un HAL independientemente del fabricante.
Otra opción sería utilizar CMSIS que es el modo oficial de ARM y que «obliga» a implementar a todos los fabricantes, pero luego por encima de ello cada fabricante elige cómo quiere armar sus HAL y provee las lib necesarias para ello como hace ST para este micro en particular. Sinceramente, yo siempre utilicé CMSIS para programar esta familia de micros y realmente es una excelente opción, pero (como mencioné) libOpenCM3 además de tener una cultura libre, es análoga e incluso más abarcativa e intenta proveernos de un HAL universal para varios fabricantes.
Hola mundo, el blinky
Manos a la obra, lo primero es generar un proyecto nuevo en PlatformIO, darle un nombre, seleccionar la placa y elegir un framework para trabajar. Para ello hacemos clic en + New Project
y en la ventana emergente completamos los campos requeridos.
ACLARACIÓN: Los STM32F103C8 que vienen en las placas Blue Pill suelen venir con 128K de Flash, como si fueran CB a pesar de tener impreso C8 (lo que indicaría que son de 64K). Algunos dicen que esto es debido a que es una copia china y no un ST original, otros dicen que es más barato producir una sola variante en vez de 2 que difieren únicamente en la cantidad de Flash. En todo caso, la gran mayoría tienen 128K, así que bien por nosotros.
Esto puede tardar varios minutos dependiendo de nuestra conexión a Interenet, ya que debe descargar la lista de placas antes de poder seleccionar la BluePill y luego de hacer clic en Finish la primera vez descarga el compilador (arm-gcc-none-eabi) y libOpenCM3. Los próximos proyectos se crearán más rápido. Y luego de que termine todo ese proceso, nos aparecerá la carpeta de trabajo. En la subcarpeta src
se hace clic con el derecho y seleccionamos la opción New File
y le daré el nombre main.c
.
Escribí el siguiente código en el main.c
:
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
int main()
{
// Se configura el clock del sistema a 72Mhz
rcc_clock_setup_in_hse_8mhz_out_72mhz();
// Se habilita el clock en el periférico GPIOC
rcc_periph_clock_enable(RCC_GPIOC);
// Se configura el PC13 como salida push-pull (2Mhz max)
gpio_set_mode(
GPIOC,
GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
GPIO13);
while (1)
{
// Se invierte el PC13
gpio_toggle(GPIOC, GPIO13);
// Demora a ojo
for(uint32_t i=0; i <7200000;++i)
__asm__("nop");
}
}
Lo primero que debemos hacer es configurar correctamente el clock del sistema para CPU (linea 7). En este caso lo puse al máximo posible utilizando el cristal de 8Mhz que viene en la placa y utilizando el PLL interno lo llevamos a 72Mhz.
Luego, configuramos el pin donde está el LED de la BluePill el PC13 (PORTC/GPIOC pin 13). Para ello, debemos hacer 2 cosas, la primera es habilitar el clock del periférico (linea 10). Esto es algo que ocurre en todos estos micros, los clocks de los periféricos no están habilitados por default, por ello siempre antes de utilizar un periférico interno debemos sí o sí habilitar el clock a través del Reset and Clock Control (RCC)
. Y ahora sí, indicamos (linea 13) que queremos utilizar el GPIO13 del GPIOC como salida PUSH-PULL (con resistencias de Pull-Up y Pull-Down) como máximo a 2Mhz. Los periféricos de los micros de 32-bits son un poco más complejos que los de 8-bits. Los GPIOs en este micro tiene las siguientes configuraciones:
- SALIDA:
- Velocidades máximas: 2, 10 ó 50 Mhz
- Modo: Open Drain o Push-Pull
- Normal/Función alternativa (interrupción, canal PWM, etc.)
- ENTRADA:
- Flotante (sin Pull-Up ni Pull-Down)
- con Pull-Up/Down
- Analógica
Luego utilizamos dentro del bucle principal la función gpio_toggle()
para alternar el LED (linea 22) y por último hacemos una demora a mano con varias instrucciones nop
en assembler (lineas 25 y 26).
Lo único que falta es probarlo, conectamos el ST-Link V2 a la BluePill (SWDIO, SWCLK, 3v3 y GND). Y PlatformIO nos provee de botones muy útiles en la barra de estado para poder compilar y programar:
Y listo, ya deberíamos ver nuestro Blinky en la BluePill con libOpenCM3 y PlatformIO sobre GNU/Linux, más libre no se puede. Otra de las ventajas que tiene utilizar el ST-Link es que podemos utilizar el debugger para emular sobre el Hardware, paso a paso, pero eso lo vamos a dejar para otra ocación.
Repositorio en GitLab: https://gitlab.com/tute-avalos/libopencm3-01-blinky
Agustin Paredes
Muy bueno, muy fresquito ese ARM Cortex-M con software libre. Posiblemente invierta los 5 dólares para jugar un poco con ese monstruito. +10 lince y a reco.
msavalos
Lo suficientemente fresco que puede estar un micro con más de 10 años en el mercado. En argentina/peronia actualmente te puede llegar a salir un poco menos de 1k en moneda local el micro+programador/debugger. Es un fierrito, por costo/beneficio de lo mejor en su tamaño.