Sunday, March 16, 2014

More ARM Adventures

Update 28/03/2014.

An excellent online book "Discovering the STM32 Microcontroller" by Geoffrey Brown is now available.  This comprehensive, up to the minute text leads the beginner through the main techniques involved in writing applications, and interfacing hardware devices to these increasingly popular microcontrollers. Communications with serial, SPI and I2C are covered, also interfacing to a colour LCD, a SD card and a Wii Nunchuk.

In an earlier post, I described how 32 bit ARM microcontrollers are now making substantial inroads into applications previously hosted by 8 bit micros.

In order to get started with ARM devices, I decided to make a minimalist breakout board for the STM32F303, which has an ARM Cortex M4 core. This has a floating point unit and additional DSP instructions making it quick for math intensive code.

The STMF32303 has a maximum clock frequency of 72MHz, but has several low power modes where it can be clocked from a low frequency internal clock source.  This is important for battery powered devices,  where battery life may be an important issue.  At 72MHz, I measured the current consumption at 35mA from the 3V3 supply.

One of the biggest challenges to the ARM newcomer, is understanding the vast menagerie of on-chip peripherals and how to initialise them.  Once this is mastered, programming becomes as simple as any other microcontroller.

Arduino manages to make the task of programming easier, by providing a few memorable C++ functions, which take care of basic I/O operations, effectively shielding the user from the minutiae of bit manipulation at register level.  It is this hardware/register abstraction layer which makes programming the Arduino so much simpler for beginners.

There is no reason why these user friendly functions cannot be recreated on the ARM. So if you prefer 


Instead of 

GPIO_SetBits(GPIOA, GPIO_Pin_1);

then this is perfectly understandable, and a lot less typing.  Abstracting complex functions to simpler, easier to remember commands is definitely the way to introduce newcomers to programming.  I'll cover more on this in a future blog-post.

For those wishing to remain within the Arduino comfort zone, Leaf Labs has produced an Arduino "look-alike" IDE for their STM32 based Maple, and Maple-mini products.  However, most of their IDE developments have been restricted to Linux platforms, having abandoned the PC as a platform a couple of years ago.


The STM32F303 has a rich set of peripherals including USARTS, Timers, SPI, I2C, ADCs and DACs. Additionally it has programmable gain op-amps and comparators which can help reduce the amount of analogue circuitry needed in an application.  There is also a capacitive  touch-sensor interface allowing user controls to be implemented easily on the pcb.  Almost all of the I/O pins are multi-function, and getting to know what is available where is one of the hardest tasks when first getting started with the ARM.

On the ARMiGo board, I have tried to simplify this by primarily putting the analogue interface signals along one side of the pcb and the digital signals along the other, but a closer inspection of the datasheet will show that further pin-swapping between functions is possible.

ST Microelectronics provide a comprehensive set of "wrapper" functions to assist the user in the process of setting up the peripherals. Ultimately these functions set the individual bit patterns in the peripheral control registers, but abstract a lot of this low level bit manipulation from the user.

In the same way that Arduino has a setup() function where most of the hardware initialisation is performed, I chose to have a separate file, which I call periph_config.c, where I put all of this setup code, and a single function Init(), called from the start of my main code, which calls the relevant functions in periph_config so as to initialise the hardware. It's then an easy matter just to change periph_config when you need a slightly different hardware configuration.

It would be relatively straightforward to automatically generate the periph_config file from some sort of GUI. Here the user would select the various functions needed and the file would be automatically generated.


ARMiGo is intended to take over when the Arduino just runs out of steam.  It has a 72MHz maximum internal clock frequency, provided from an 8MHz crystal that drives a phase locked loop. So raw speed is available when necessary, but using the clock divider, the 8MHz clock can be divided down to a plodding 125kHz, when much lower power is needed. In this condition the ARM will consume around 1mA.

Full speed USB is available on-chip, and STM have provided source code for CDC, virtual com port VCP and other USB profiles.  As well as being able to communicate directly over USB, as a slave device, with a PC or other device acting as host, all of the STM32 family have an embedded (factory programmed) bootloader which allows firmware to be programmed into the device directly from USB. This is known as DFU - device firmware upgrade.

For communicating with other devices, the STM32F303 has 3 USARTS available, plus SPI and I2C interfaces. In a recent application, I have sent data to a PC using one of the USARTs, at 921,600 baud, whilst using the SPI bus to take readings from a 24 bit ADC (AD7767) at 125kHz sampling frequency. One of the timer channels provides a 1MHz clock signal for the ADC.

The STM32F303 also has four individual 12 bit ADCs, which can sample at 5MHz. Each ADC has a front end multiplexer, allowing up to 4 analogue signals to be read from each ADC. This opens up interesting applications in energy monitoring, or as a low cost multifunction test instrument.  The excellent Miniscope project is based on the STM32F303 - be sure to watch the video of the arbitrary waveform generator - which uses one of the 12 bit DAC channels.

The STM32F303 has up to 35 I/O lines available, making it a little more flexible than Arduino or other ATmega328 boards. However, it should be appreciated that it is a 3.3V part, and whilst the digital I/O lines are 5V tolerant, the analogue ones are not.  This comes as a mixed blessing, as it can interface directly with newer 3V3 devices without the use of level converters, but caution is needed when using in a project that has mixed supply voltage logic.

ARMiGo is a low cost/low tech product to get people started with ARM. Whilst many other boards use ARM devices, the ARMiGo tries to remove to remove the clutter and provide direct access to all ports and peripherals, in an easy to use, plug in module.

No comments: