STM32 microcontroller boards

Introduction

Launched in 2007, the STM32 range of microcontrollers from STMicroelectronics feature a 32-bit Arm Cortex-M core (Cortex-M0, Cortex-M0+, Cortex-M3, Cortex-M4, Cortex-M7, or Cortex-M33) flash memory, static RAM, debugging interface, and various peripherals. These powerful microcontrollers can be found as the 'heart' of a number of development boards, which will be covered on this page, giving the user a lot of processing power in small form and at low cost.

Please see the following video for a more detailed introduction to STM32 and a brief look at a few of the boards available:

Please read on to learn about various STM32 development boards I have come across as well as projects to get to grips with the STM32 family.

Images on this page can be downloaded from the bottom of the page for better viewing.

Boards

Introduction

Development boards featuring STM32 microcontrollers give the user a deep dive in the world of electronics, and take away some of the difficulty in getting that first foot on the ladder. From the basics like blinking an LED, to responding and logging data from sensors, to communicating with devices over Wi-Fi, the possibilities are almost limitless. Each development board will have a range of features for the user's convenience, not just from what the microcontroller itself offers (speed, memory, I/O, etc.), but also the components included on the board, such as lights, switches, sensors, displays, and so on.

If you are interested in making your own STM32 based board please see the Build a development board section.

Blue Pill

I bought this board back in 2018 from eBay for about £3, advertised as 'STM32F103C8T6 ARM Cortex M3 STM32 System Development Board Arduino mbed' but wasn't aware at the time that it was more commonly known as the 'Blue Pill' (due to the board's colour). Unfortunately, I didn't add my experiences of the board to my site when I first got it and I've lost my original notes, so now I've returned to the board I've had to do so afresh, although I do recall first time round I had some difficulty getting the board to work. Unfortunately, second time round I also had difficulty despite eventual success and at least I've now publicly documented my experiences.

There is no brand or model identification on the board (at least on mine) except 'STM32' near the microcontroller, which is a STM32 F103C8T6 (Arm Cortex-M3 based), it appears to be a genuine part but some boards do have a fake part. Please see:

https://github.com/keirf/greaseweazle/wiki/STM32-Fakes

Along both long edges are 20 labelled connections for I/O and power of which headers can be soldered to (in my case two yellow headers were supplied, which I soldered to the board).There is a micro USB port located on one of the board's short ends, and a single 4-way black header on the other end, which has the pinout labelled on both sides of the board. Near the micro USB are x2 3-way yellow headers, both labelled 0 on the left and 1 on the right, and BOOT0 above the top one, BOOT1 below the bottom one, with a jumper fitted on each one. Under those headers is a reset switch. Toward the other end to the left of the black header is a PWR LED and PC13 LED (user LED, similar to the 'L' LED on an Arduino).

Please note that some Blue Pill boards have USB-C and other features different from the original incarnation.

Because I thought it would be the easiest way to program the board and as I assumed I had done so before, I tried to use the Arduino IDE to program it. To be able to use the Arduino IDE you need to install STM32 via the Boards manager, as outlined on this site: 

https://www.sgbotic.com/index.php?dispatch=pages.view&page_id=48#:~:text=The%20STM32%20Blue%20Pill%20is,board%20will%20erase%20this%20bootloader

Once that is done you can select the board in the Arduino IDE (note: I'm using Arduino IDE V2.1.1): Tools->Board->STM32 MCU based boards->Generic STM32F1 series. Also set the Board part number (Tools->Board part number...). For example, I selected 'BluePill F103C8'. Set USB support to CDC (generic "Serial" supersede U(S)ART) (Tools->USB support) and Upload method to HID Bootloader 2.2 (Tools->Upload method). Remember to also set the port (Tools->Port). Oddly, when I plugged in my board, Windows detected it as 'Maple' (incidentally, there are other Cortex-M3 based boards with that name), and COM11.

When I opened up the Blink example (File->Examples->Basics->Blink) and tried to upload it I got the error:

Failed uploading: uploading error: exit status 1

Despite it going through the motions. So possibly the Arduino bootloader isn't present on the board and I needed to put it on it. I found that there are some Blue Pill boards that already have the Arduino bootloader preloaded so it's important to check that when buying one if your intention is to use it as an 'Arduino'.

To get the Arduino bootloader on to my board I followed this tutorial:

https://microcontrollerslab.com/program-stm32-blue-pill-through-usb-port-bootloader/

I had a number of USB-TTL serial converters and the one I used showed up in the Windows Device manager as 'Silicon Labs CP210x USB to UART Bridge'. I first tested it before even connecting to the Blue Pill by by putting a shunt on TX ad RX and then plugging the converter into the computer's USB. Using PuTTY I selected 'Serial' and entered the COM port number of the converter in the 'Serial line' box and clicked the 'Open' button. Typing  caused the characters to appear in the window and the data LED to flash on the converter board, suggesting it was working.

So I moved on with the tutorial. Note that the STM32 Flash loader that the tutorial says to download has been replaced with STM32CubeProgrammer  and since I had already downloaded it I tried to use it instead but it wouldn't detect the target and I also had same problem using STM32 Flash loader. It turns out the issue was with the USB to serial converter so I tried my Prolific PL2303 but on Windows 10 it shows in the device manager as 'phased out' and is unusable. However, I followed these instructions:

https://answers.microsoft.com/en-us/windows/forum/all/pl2303hxa-phased-out-since-2012-version-38310/2ef1d8fa-59fc-421e-9510-b1f63c68d4f9

And the converter now works although restarting my computer will likely revert it back to the previous driver.

Continuing with the tutorial: don't forget to set BOOT0 to the '1' position before programming the bootloader and put back to the '0' position before plugging it back into your PC. However, even with the bootloader now installed on the Blue Pill, it still failed to upload an Arduino sketch. I tried by chance setting the Upload method to 'Maple DFU Bootloader 2.0' and Windows suddenly detected the board as 'BluePill F103C8' and when I tried uploading the sketch again it worked. Note: for me, the Blue Pill didn't show up as 'Maple Mini' in the Arduino IDE as the tutorial suggests.

Oddly, although the Arduino IDE reported that it couldn't reset the device after uploading the sketch, the LED (PC13) was blinking as expected. Note that the blink sketch uses LED_BUILTIN but I didn't need to alter it to 'PC13' as the tutorial says to do. Note also that PC13 is connected to 3.3V via a resistor rather than to GND, so turning the pin on (high) will turn the LED off, not on as with an Arduino's on-board 'L' LED.

Nucleo-64

My second STM32 board, the Nucleo-64 (NUCLEO-C031C6) from STMicroelectronics, was purchased from Mouser in 2023 for £8.46 ($10.65), and packs a lot for the small price. Note that while there are variations of the Nucleo-64, each offering different features, the focus will be mainly on the NUCLEO-C031C6. The board uses a STM32C031C6 microcontroller with features including:

Arm Cortex-M0+ 32-bit core running at 48MHz.

12KB SRAM

32KB flash program memory

45 I/O and a number of common interfaces (I2C, SPI, USART)

12-bit ADC

RTC (Real-Time Clock)

My Nucleo-64 came in a small brown box and as well as the board itself there was a leaflet with a QR code linking to the technical information, resources, etc. The link is:

www.st.com/en/evaluation-tools/nucleo-c031c6.html

Here are some useful links...

Datasheet for the various Nucleo-64 boards:

https://eu.mouser.com/datasheet/2/389/en_DM00105918-1501215.pdf

User manual for the NUCLEO-C031C6:

https://www.st.com/resource/en/user_manual/um2953-stm32-nucleo64-board-mb1717-stmicroelectronics.pdf

Schematic for the NUCLEO-C031C6:

https://www.st.com/content/ccc/resource/technical/layouts_and_diagrams/schematic_pack/group2/9e/c0/20/c5/ec/bf/40/26/MB1717-C031C6-B02_Schematic/files/MB1717-C031C6-B02_Schematic.PDF/jcr:content/translations/en.MB1717-C031C6-B02_Schematic.PDF

The board features both Arduino (Uno V3) compatible I/O pins in the form of the familiar female headers (which also extended downwards from the board's underside) and a new standardized ST connector (Morpho) via male connectors on the board's edges and also extend downward, giving access to all I/O available from the microcontroller. Considering the Nucleo-64 is about half the price of an Arduino Uno but much more powerful you can see how good value it is, however, there is one thing to keep in mind. The Nucleo-64's I/O pins operate at 3.3V, unlike Arduino Uno's I/O which run at 5V, and although most of the Nucleo-64's I/O pins are 5V tolerant (marked with ‘FT’ in the STM32C031C6 datasheet) they won't output more than 3.3V, which may cause incompatibility with some Arduino shields.

Most Arduino shields designed for the Uno should fit the Nucleo-64 board and the hats on the on-board buttons can be removed to avoid getting in the way of an attached shield.

The board has four LEDs which are for USB communication (LD1, red/green), over current (500mA) warning (LD2, red), powered by 5V source (LD3, green), and user/Arduino (D13) LED (LD4, red). Additionally, there are two push buttons, USER (B1) and RESET (B2).

Here’s a guide if you want to use the board with the Arduino IDE:

https://www.instructables.com/Quick-Start-to-STM-Nucleo-on-Arduino-IDE/

Since I didn't already have the IDE installed on the computer I wanted to use I went with the newest Arduino IDE at the time V2.1.1. Following the guide, everything was in the same place in the new IDE but when I got to the part where you need to install the STM32 Core board the IDE warned that it was deprecated and advised to install a new package index. You can't copy and paste it from the window but for your convenience here is the URL I had to manually copy:

https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json

Then I continued with the tutorial and installed the 'STM32 MCU based boards' V2.6.0 since that includes my board. When I plugged the board into my PC via the micro USB, Windows detected it and installed it. Interestingly, the board shows up as a removable storage drive (E: on my computer) having 104KB of 124KB free, formatted as FAT. On the drive are 2 files, DETAILS.TXT and MBED.HTM. With the board plugged in and installed, LD1 is lit red, LD3 is lit green solid and LD4 blinks rapidly (the preloaded 'blink' example, it would appear).

In the Arduino IDE I chose my board using Tools->Board->STM32 MCU based boards->Nucleo-64 and set the port it's connected to using Tools->Port. Selecting Tools->Get Board Info returned with the board's VID, PID and SN (BN unknown). The examples for my board, found at File->Examples-> and listed under Examples for Nucleo-64 were complicated, so I avoided them for now and went with the simple blink example. It uploaded very quickly, and the IDE reports there is 32768 total bytes for program storage and that it uploaded on NOD_C031C6 (E:). LD1 goes red when uploading a sketch. However, after the sketch uploaded, no LED on the board was blinking. However, I tried the IWDG_Button example (IWatchdog->IWDG_Button) and that worked. It demonstrates the use of a watchdog, blinking LD4 a few times every 10 seconds if the user button isn't pressed. I tried the simple blink example again and now it was working, so I'm not sure what went wrong there.

Build a development board

Although I had already had experience with a number of STM32 development boards I thought it would be a worthwhile project to make my own, especially after I bought from  Temu two STM32F030F4P6 chips for £2.38 ($2.96). Granted, I could get the chips for £1 ($1.24) each from RS electronics but there was a minimum order of 100, whereas Mouser had them for 80p ($0.99) each with no minimum order, but you need to spend £30 ($37.27) to get free shipping whereas Temu requires £15 minimum spend. Of course, there was the risk that the chips from Temu could be fake, even with the single (positive) review at the time of buying them, but having received and tested them they appear to be genuine and working.

Here is a link to the chip's datasheet:

https://www.st.com/resource/en/datasheet/stm32f030f4.pdf

And a brief summary of the IC's specification:

32-bit Arm Cortex-M0 CPU 48MHz maximum.
16KB flash.
4KB SRAM.
12-bit ADC (9 external channels, 2 internal).
RTC calendar/alarm.
15 GPIOs.
x1 I2C/x1 USART/x1 SPI.
Serial wire debug (SWD).

The chip's package is TSSOP20 and measures just 6.5mm x 6.4mm, and each pin is 0.3mm wide, so not breadboard or prototype board friendly. Fortunately I had purchased some TSSOP-20 adapter boards to convert between the SMD footprint to the much easier to handle through-hole standard. If you plan to do a similar thing yourself but don't have much experience with SMD I recommend researching different SMD soldering techniques and practising on some less expensive chips first. However, I'll go through how I soldered the chip:

What I did was clean the adapter board with isopropyl then added liquid flux to the chip pads, then using a soldering iron with small bit I applied solder to the chip pads, ensuring any shorts were removed. Next I soldered male headers to the adapter board underside using breadboard to hold them in place while I soldered (once you have finished soldering, the adapter board is in the breadboard ready to be tested). The most difficult part was next: holding the chip with tweezers while I heated one corner pin to solder it - it really helps to have steady hands and use a microscope which indeed I used. After soldering the opposite corner pin I used flux across the pins and soldered each pin individually at the point where the pin touches the pad. Once all the pins were soldered I checked for continuity and shorts and removed any bridges I found.

I have put together a schematic of the circuit I used initially on breadboard and later on th intention is to solder to a prototype board.

As you can see the circuit is fairly simple, the STM32 (U1) is powered off 3.3V, a switch (SW1) selects the boot mode (which can just be a 3-way header with a shunt), and an LED (D1) gives conifrmation that power has been applied. NRST has an internal pull-up but a capacitor (C3), as recommended in the IC datasheet, helps prevent false trigerring of the reset line. Because the STM32 can run off either an internal or external timing element the intention is that an external resonator or crystal can be plugged into connector J1 but if the internal clock is used then PF0 and PF1 are free to be used as GPIO. Because a typical resonator has the necessary built-in capacitors it's more convenient than a crystal, which would require external capacitors to be added but a crystal has the advantage of being more stable than a resonator. The various GPIO, power, and RST can be routed to headers.

When I was first testing the STM32 I powered the circuit using a Waveshare PL2303 USB UART module with its VCCIO shunt set to 3.3V, allowing it to provide 3.3V on the VCCIO pin and operate as a 3.3V UART device; as well as powering the STM32 it also communicates with the chip. I plugged the PL2303 module into my Surface Pro and then opened STM32CubeProgrammer, making sure the Port selection in UART configuration was set to the PL2303 module COM port (plugging it in after the app is opened means it can't be selected). I didn't change any of the default settings which are 115200 baud, parity Even, RTS 0, DTR 0. In the log window I saw some promising info:

Activating device: OK

Chip ID: 0x444

BootLoader protocol version: 3.1

In the RM0360 Reference manual:

https://www.st.com/resource/en/reference_manual/rm0360-stm32f030x4x6x8xc-and-stm32f070x6xb-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

It says the Chip ID should be 0x444 for STM32F030x4, so it appears to be reading correctly from the chip. However, in the STM32CubeProgrammer log window I also got:

Warning: Device is under Read Out Protection

Response received from device: NACK

Error: GETID command not acknowledged!

Reemission of GetID command

Disconnected from device.

This also happens if I clicked on the Read button. It's also odd it says GETID not acknowledged even though it got the chip ID.

I tried using a lower baud (9600) but that made no difference. I also tried uploading using the Arduino IDE, with Board set to Generic STM32F0, Board part number: STM32F0 Demo board (HSE 8MHz), Upload method: STM32CubeProgrammer (Serial) but got the same error Warning: Device is under Read Out Protection.

Please note:

HSE=high-speed external clock.
HSI=High-speed internal oscillator.

Next, I followed this guide for using the Nucleo's on board ST-link programmer with an external STM32 board:

https://time4ee.com/articles.php?article_id=101

Using STM32CubeProgrammer I could access the MCU core page, Run, Halt, and Reset. If I did halt, I could step, and I could see registers change such as the PC. But if I clicked Read Core Reg it got stuck, although I could do other operations. On the Option Bytes page clicking Apply or Read never completed. All this was tested with Boot0 (pin 1) connected to 3.3V. ST32CubeProgrammer shows in the target information panel (see below) that the device is STM32F03x, device ID is 0x444, Rev 1.0, 16KB flash, Cortex-M0, bootloader version 0x10.

Looking into the read issue further I came across this post:

https://electronics.stackexchange.com/questions/336677/do-i-really-need-to-put-stm32-microcontroller-into-bootloader-mode-to-program-it

Which explains that you only need to put the microcontroller into bootloader mode if you're going to program it over the UART, using the bootloader. Generally speaking, you can program the microcontroller over SWD at any time - SWD or Serial Wire Debug is the interface being used between the Nucleo and the STM32.

I had done the basic checks, making sure the STM32 was getting 3.3V on VDD and VDDA, referenced to GND. I found it odd that I could interact with the STM32 using STM32CubeProgrammer only when boot0 was connected to +3.3V, not 0V, I did also try using a resonator connected to the STM32 and boot0 connected to GND but could not halt the CPU nor step through it like I could when boot0 is connected to +3.3V, but that may be because the flash was empty. 

There was also the possibility the chip was fake but its markings matched up with images of the same chip found online and it read back the correct chip ID. I even looked at the chip under UV light and didn't see anything suspect. Of course it's possible I could have damaged the chip during soldering or the possibility that the chip was a factory reject and only partially working.

The fix I found while looking online was to do the following:

In ST32CubeProgrammer I clicked on the Option Bytes shortcut at the side, expanded Read Out Protection, changed the RDP value from 0 to AA (Level 0, no protection) and clicked Apply, which was successful. I then went to Memory and file editing, clicked Read and it successfully read in the memory (address set to 0x8000000), which was blank as expected (all FFs). Considering I couldn't read before, it seems the read issue was fixed. How the protection option got set in the beginning is a mystery.

Note: this was with boot0 at GND.

I unplugged the board, plugged back in, clicked Connect and this time no read error popped up. Also, under Option Bytes, clicking on Read worked whereas before it had hung. The only odd thing is LD1 on the ST-link part of the Nucleo kept flashing red fast while ST32CubeProgrammer is open, which it did before and I assumed was due to not being able to read from the MCU. Apparently it could be a driver issue but it works as intended so doesn't appear to be a problem.

Now that I had removed the read issue I tried programming using the Arduino IDE to allow programming with minimal difficulty. I opened the Blink example (Basics->Blink), hovering over LED_BUILTIN I could see it was set to PA4, so I connected an LED with limiting resistor (I used 1K) from PA4 (pin 10) to GND. Note: boot0 set to GND. 

I had saw online that it was recommended to use the 'underscore' versions of the pins, e.g. PA_4, and that is what I have used mostly but with a bit of experimentation I have worked out the full details. It appears that the underscore and non-underscore versions can be used interchangeably when a pin is used as an analog input, example both PA0 and PA_0 work. But an analog capable pin when used as a digital input or output must use the non-underscore version, example PB_1 won't work but PB1 will. For digital only pins, either version can be used.

In the IDE I set board to STM32 MCU based boards->Generic STM32F0 Series and Board part number to STM32F030F4 Demo board (HSI internal RC oscillator), and Upload method to STM32CubeProgrammer (SWD). I connected the ST-link to my Surface (the PA4 LED was on), and in the Arduino IDE set the port number appropriately and clicked Upload. After compiling and uploading, the PA4 LED was flashing as expected. In the IDE output I could it had correctly detected the ST-link as NUCLEO-C031C6, Blink.ino.bin is opened and parsed from 0x08000000, and the program is run from address 0x8000000. 

I closed the IDE and opened STM32CubeProgrammer, clicked Connect and it did an automatic read and displayed memory contents from 0x08000000, which not surprisingly weren't blank. The PA4 LED was now off so perhaps the CPU was automatically halted. Going into the CPU section, clicking the Run button causes PA4 LED to continue blinking. We can click the Halt button and the LED will stop blinking, we can click the Step button and watch the PC value change (see image below). We can click Run again to resume blinking.

The next test was to try another I/O pin, this time, PA5 (pin 11), but also to try out toggling the pin at a different speed (which any GPIO should be suitable for). I modified the Blink example to use PA5 but removing both delays to toggle the pin on/off as fast as possible. Using digitalWrite() is slow but an easy way to do the test. Using my multimeter set to frequency on the PA5 pin and GND I got a reading of 220.6KHz. I then programmed the STM32 again but this time I set the Board part number to STM32F030F4 Demo board (HSE 8Mhz) and connected an 8MHz resonator, pins 1 and 3 to STM32 pins 2 and 3, resonator pin 2 to GND. After uploading the sketch again (since I changed from internal to external clock) I got a frequency reading of 223KHz, which wasn't much faster than the using HSI. This appears to be because the default internal RC oscillator is 8MHz and that's what the board part number STM32F030F4 Demo board (HSI Internal RC oscillator) uses. The advantage of using the internal oscillator is that it frees up two GPIO pins but the internal oscillator isn't as stable not accurate as using external quartz crystal/resonator.


For faster speed toggling we could use the digitalWriteFast library (don't forget to install it if you don't already have it):


#include <digitalWriteFast.h>


void setup() {

  pinMode(PA_5, OUTPUT);

}


void loop() {

  digitalWriteFast(PA_5, HIGH);

  digitalWriteFast(PA_5, LOW);

}

Using the internal clock setting resulted in 283.3KHz, and external 8MHz resonator 287.5KHz.


To toggle even faster we can do direct port manipulation:


void setup() {

  pinMode(PA_5, OUTPUT);

}


void loop() {

  GPIOA->ODR|=0b0000000000100000;

  GPIOA->ODR&=~(0b0000000000100000);

}

Using the internal clock resulted in 903.2KHz and external 8MHz 954.7KHz. Note that I did also confirm these frequency measurements with my oscilloscope.


Something to keep in mind is that there is a delay between the end of loop() and executing the first instruction back at the start of loop(), that is, the pin stays off longer than it is on. If we do successive pin toggling before the end of loop() we can get a higher speed. So if we changed loop() to:

void loop() {

  while (true) {

    GPIOA->ODR|=0b0000000000100000;

    GPIOA->ODR&=~(0b0000000000100000);

  }

}


Because the while() loop always executes the program never gets to the end of loop() and thus we can toggle the pin faster: on internal clock 3.192MHz, external 8MHz 3.182MHz. 


Next, I did a digital input test by writing a sketch which responds to a switch to light an LED whenever the switch is pressed. It requires an LED with a 1K limiting resistor to PA6 (pin 12) and GND, and switch to PA7 (pin 13) and 3.3V. Here is the code:


const int inpPin=PA_7;  //Input pin

const int outPin=PA_6;  //Output pin


void setup() {

  // put your setup code here, to run once:

  pinMode(inpPin,INPUT_PULLDOWN);

  pinMode(outPin,OUTPUT);

}


void loop() {

  // put your main code here, to run repeatedly:

  if (digitalRead(inpPin)) {

    digitalWrite(outPin,HIGH);

  }

  else {

    digitalWrite(outPin,LOW);

  }


  delay(500);

}


It sets up the single input and output in setup(), using INPUT_PULLDOWN to enable an internal pull-down resistor. In loop(), if the input is HIGH (the switch is pressed) the LED is turned on otherwise it is turned off. I purposely added a 0.5s delay just to help show it is indeed code controlling the LED, as consequence the LED won't react immediately when you press the switch, however, similarly the LED will stay on briefly when releasing the switch.


The STM32 has a number of pins that can behave as analog inputs, the particular one we are dealing with has 9 external sources, ADC_IN0 to ADC_IN9 except ADC_IN8. We can for example use PA0 (ADC_IN0), pin 6. Note that the ADC_INx pins are 3.3V pins.


I wrote a sketch to get the analog value from PA0 and output it to the serial port. However, unlike on a typical Arduino where we can program and access the serial port from a single USB port, the STM32 setup that we're using doesn't work that way. Instead we have to connect a USB to UART adapter to the STM32. I used a Waveshare PL2303, with the VCCIO shunt on 3.3V so it operates in 3.3V mode. It’s connected as follows:

STM32 PL2303

GND (pin 15) GND

PA3/USART1_RX (pin 9) TXD

PA2/USART1_TX (pin 8) RXD


Note: for this test we only actually need to connect to the STM32’s TX pin but we will use the RX pin in the next sketch so it can be connected as well.


Connect a potentiometer (10K or 100K should be fine) with its middle pin connected to STM32 pin 6, and the other two connections to GND and 3.3V respectively. This is the code:


void setup() {

  Serial.begin(9600);

}


void loop() {

 int sensorValue=analogRead(PA_0);

 Serial.println(sensorValue);

 delay(1000);

}


After uploading the sketch to the STM32, open PuTTY or a similar program, and open a serial connection for your USB-UART board, set to 9600 speed. You should see a value being printed every second, which increases/decreases as you turn the wiper pot one way or another. The lowest value, 0, represents 0V and the highest, 1023, represents 3.3V. Your pot, however, may not have perfect resistance range so you may not see the full range of values but you can connect PA0 to GND to see 0 or to 3.3V to see the maximum value, but even then you may not see 1023. Indeed, I was only see 1021 when PA0 connected to 3.3V and measuring with my voltmeter I could see the supposed 3.3V rail was only 3.1V, possibly a decoupling issue. I connected the VCCIO pin (3.3V out) from the PL2303 to the STM32 PA0 pin and saw 1023 in PuTTY so indeed the issue was a sagging power rail.


Considering the STM32 has 12-bit ADC you may wonder why the analog value maxes out at 1023, this is because by default it's set to 10-bit resolution. If you want 12 bit resolution put the following in setup():


analogReadResolution(12);


Next, 2-way serial communication: have the USB to UART adapter connected as before, and an LED with series limiting resistor between PB1 (pin 14) and GND. Here is the sketch:


const int outPin=PB1;  //Output pin


void setup() {

  Serial.begin(9600);

  pinMode(outPin,OUTPUT);


  Serial.println("Serial started.");

}


void loop() {

  if (Serial.available()>0) {   //Serial available?

    int charIn=Serial.read();

    

    if (charIn=='y') {

      digitalWrite(outPin,HIGH);

      Serial.println("Turning LED on.");

    }

    else {

      if (charIn=='n') {

        digitalWrite(outPin,LOW);

        Serial.println("Turning LED off.");

      }

    }

  }

}


Using PuTTY or similar program open a serial connection set to 9600. If you type a ‘y’ the LED will turn on with accompanying message, typing ‘n’ will turn the LED off with appropriate message. Only lowercase characters are accepted and other keys won't do anything.

Projects

Introduction

To give an idea of what's possible with STM32 boards please see this video:

All content of this and related pages is copyright (c) James S. 2023