Hello STM32
The STM32 is a decent chip but, unlike the AVR or traditional microcontrollers, fairly hard to get up and going. There's quite a bit of code out there using the ST standard libraries, non-free software, or bigger systems like eLua or FreeRTOS, but I prefer things closer to the metal.
This example includes a Makefile, startup script, linker script, and simple 'hello' example that sets up the basic hardware enough to flash a LED and write some characters out the serial port.
Want to get going? Download hello.zip, CodeSourcery's Lite toolchain, and give it a 'make'.
Makefile
# Makefile for building basic STM32 projects # # Michael Hope <michaelh@juju.net.nz>, 2010 # # Using the CodeSourcery 2009q3 Lite ARM EABI tools CROSS_COMPILE = arm-none-eabi- CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy # Name of the startup file. 'hd' for high density STARTUP = startup_stm32f10x_hd.s CFLAGS = -mcpu=cortex-m3 -mthumb -O -g # List of all binaries to build all: hello.bin # Create a raw binary file from the ELF version hello.bin: hello.elf $(OBJCOPY) -O binary $< $@ # Create the ELF version by mixing together the startup file, # application, and linker file hello.elf: $(STARTUP) hello.c $(CC) -o $@ $(CFLAGS) -nostartfiles -Wl,-Tstm32.ld $^ # Program the binary to the board using the builtin serial bootloader program: stm32loader.py -p /dev/ttyUSB0 -ewv hello.bin # Remove the temporary files clean: rm -f *.o *.elf *.bin
The Makefile is nice and simple and skips most of the intermediate steps that others do. The flow is (startup.s & hello.c & stm32.ld) -> hello.elf -> hello.bin.
Hello.c
/// A very basic STM32 demo that runs of the internal oscillator, /// flashes a LED, and writes out some serial data. /// /// Michael Hope <michaelh@juju.net.nz>, 2010 /// #include "stm32f10x.h" /// Spin delay void delay(int count) { // volatile so that the compiler doesn't optimise it out volatile int i; for (i = 0; i < 100000; i++) { } } /// Main function. Called by the startup code. int main(void) { // Most of the peripherals are connected to APB2. Turn on the // clocks for the interesting peripherals RCC->APB2ENR = 0 // Turn on USART1 | RCC_APB2ENR_USART1EN // Turn on IO Port A | RCC_APB2ENR_IOPAEN // Turn on IO Port B | RCC_APB2ENR_IOPBEN // Turn on the alternate function block | RCC_APB2ENR_AFIOEN; // Put Port A pins 8 through 15 into alternate function/50 MHz // mode. GPIOA->CRH = 0xBBBBBBBB; // Put PB0 into push pull 50 MHz mode GPIOB->CRL = 0x03; // The internal RC oscillator runs at 8 MHz. The divide by 16 // combined with the fractional divider means we just divide the // bus clock by the baud rate USART1->BRR = 8000000/38400; // Enable the UART, TX, and RX circuit USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; // Nothing else /needs/ to be setup but you could go further. The // chip defaults to 8 MHz RC with the busses running at the same // speed as the core. for (;;) { // Around 1/4 of a second delay(100000); // Write out a character USART1->DR = 'H'; // Turn all pins on GPIOB->ODR = ~0; delay(100000); // Write out another. Note that the delay takes long enough // so we know that TX is empty USART1->DR = 'i'; // Turn all pins off GPIOB->ODR = 0; } }
I haven't used the ST standard libraries as they reduce the readability of the code and greatly increase the code size. Sitting right on top of the registers is more efficient, readable, and transparent.
Other files
The startup script, linker script, and header files are all from the ST standard libraries. Note that the linker script (stm32.ld) and startup script are for the 512 k high density device used in the wiki:ETSTM32Stamp.
Tips
- Don't forget the -mcpu=cortex-m3. GCC generates code for the incompatible ARMv5 by default
- You can program the binary images from Linux and probably anything with Python using stm32loader
- Don't forget to turn on the clocks for the module - check out the RCC registers
- Keep an eye out for sub enable registers. The UART needs the module clock turned on, the UART enabled, the UART TX enabled, and UART TX enabled
- See the wiki:ETSTM32Stamp page for links to the manuals for the STM32
