MicroPython
MicroPython is a complete implementation of Python 3, written in C and optimised to run on microcontrollers. It provides a full Python compiler and runtime on the hardware itself, plus an interactive prompt (REPL) so you can execute supported commands immediately. Alongside a selected subset of the core Python library, it exposes modules that give you direct access to low-level hardware. See micropython.org for details.
Peripherals on the core board
STM32F411CE block diagram
The silkscreen drops the
Pprefix:A0meansPA0. MicroPython addresses these I/O as PAx, PBx, PCx.STM32F411CE block diagram
GPIO
Definitions
PA0–PA15, PB0–PB10, PB12–PB15, PC13–PC15 Pin.IN — configure the pin for input; Pin.OUT_PP — configure the pin for output, with push-pull control; Pin.OUT_OD — configure the pin for output, with open-drain control; Pin.AF_PP — configure the pin for alternate function, push-pull; Pin.AF_OD — configure the pin for alternate function, open-drain; Pin.ANALOG — configure the pin for analog.
pull can be one of:
Pin.PULL_NONE — no pull-up or pull-down; Pin.PULL_UP — enable the pull-up; Pin.PULL_DOWN — enable the pull-down.
Usage
GPIO
from pyb import Pin
C13 = Pin('PC13',Pin.OUT_PP,Pin.PULL_NONE) # PC13 push-pull output, no pull
C13 # print the PC13 configuration in the REPL
C13.high() # drive high
C13.value() # read the PC13 levelExternal interrupts
Definitions
ExtInt.IRQ_RISING ExtInt.IRQ_FALLING ExtInt.IRQ_RISING_FALLING pyb.Pin.PULL_NONE pyb.Pin.PULL_UP pyb.Pin.PULL_DOWN
Usage
GPIO external interrupt
from pyb import Pin, ExtInt
callback = lambda e: print("PA0 <KEY> intr")
ext = ExtInt(Pin('PA0'), ExtInt.IRQ_RISING, pyb.Pin.PULL_NONE, callback)
ext.swint() # trigger the callback by hand, runs callback() onceADC
Definitions
STM32F411 I/O map
ADC0
External channels:
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PB0, PB1Internal channels: temperature, VBAT, VREF
Usage
ADC external channels
from pyb import Pin,ADC
IN0 = ADC(Pin('PA0'))
IN0.read()
IN1 = ADC(Pin('PA1'))
IN1.read()ADC internal channels
from pyb import Pin,ADC
adc_in = pyb.ADCAll(12, 0x70000) # 12-bit resolution, internal channels
adc_in.read_core_temp() # temperature
adc_in.read_core_vbat() # VBAT
adc_in.read_vref() # VREFTimer
Definitions
STM32F411 I/O map
Timer pinout on the STM32F4x1C:
When USB is in use, PA11 is taken.
| Timer | Channel 1 | Channel 2 | Channel 3 | Channel 4 |
|---|---|---|---|---|
| TIM1 | PA8 | PA9 | PA10 | PA11 |
| TIM2 | PA0, PA5, PA15 | PA1, PB3 | PA2,PB10 | PA3 |
| TIM3 | PA6, PB4 | PA7, PB5 | PB0 | PB1 |
| TIM4 | PB6 | PB7 | PB8 | PB9 |
| TIM5 | PA0 | PA1 | PA2 | PA3 |
| TIM9 | PA2 | PA3 | ||
| TIM10 | PB8 | |||
| TIM11 | PB9 |
Timer input clocks:
96 MHz (411) / 84 MHz (401): TIM1, TIM9, TIM10, TIM11 48 MHz (411) / 42 MHz (401): TIM2, TIM3, TIM4, TIM5
Usage
Timer as a periodic interrupt
import pyb
from pyb import Timer
TIM1 = Timer(1, freq=2) # 2 Hz
TIM1.counter() # get counter value
TIM1.callback(lambda t: pyb.LED(1).toggle())
TIM1.freq(5) # change the frequency to 5 Hz
TIM1.deinit() # release TIM1Timer PWM
import pyb
from pyb import Pin, Timer
TIM2 = Timer(2, freq=1000) # 1 kHz
# Timer.PWM_INVERTED: 0% -> high, 100% -> low
# Timer.PWM: 0% -> low, 100% -> high
TIM2_CH1 = Pin('PA0',Pin.PULL_NONE) # PA0: TIM2, CH1, no pull
TIM2_CH1 = TIM2.channel(1, Timer.PWM, pin=TIM2_CH1,pulse_width_percent = 0) # 0% duty
TIM2_CH1.pulse_width_percent(50) # 50% duty, 0-100%
TIM2_CH1.pulse_width(int(TIM2.period()/2)) # set the compare value directly, 50% dutyTimer input capture
polarity can be one of:
Timer.RISING — capture on the rising edge Timer.FALLING — capture on the falling edge Timer.BOTH — capture on both edges
from pyb import Pin, Timer
import pyb
TIM1 = Timer(1,prescaler=96-1, period=65535-1,mode=Timer.UP) # /96 -> 1 MHz, reload 65535-1, count up
TIM1_CH1 = Pin('PA8',Pin.PULL_NONE) # PA8: TIM1, CH1, no pull
TIM1_CH1 = TIM1.channel(1, Timer.IC,polarity=Timer.BOTH, pin=TIM1_CH1)
TIM1_CH1.callback(lambda t: print(TIM1_CH1.capture()))
pyb.delay(5000)
TIM1_CH1.callback(None)
TIM1.deinit()
print('TIM over')RTC (real-time clock)
Definitions
None.
Usage
from pyb import RTC
RTC = RTC()
RTC.datetime((2020, 1, 1, 3, 12, 00, 0, 0)) # set the time: 2020-01-01, Wednesday, 12:00:00
RTC.datetime() # read the time
hex(RTC.info()) # boot time and reset source
callback = lambda e: print("RTC WakeUP")
RTC.wakeup(2000,callback)
# pyb.stop() # stop mode; if USB is connected, USB CDC hangs,
# RTC.wakeup(0)
pyb.standby() # if USB is connected, USB CDC disconnects; on wake the board resetsUART
Definitions
Cross-connect with the USB-to-serial adapter.
STM32F411 I/O map
UART1:
TX-PA9,RX-PA10 UART2:TX-PA2,RX-PA3 UART6:TX-PA11,RX-PA12 (taken byUSB) UART_REPL: UART1
Usage
UART2
from pyb import UART
uart2 = UART(2, 9600)
uart2.write('hello')
uart2.read(5) # read 5 bytes; returns None if nothing is buffered
uart2.readline() # read one line, terminated by a newline
uart2.any() # number of bytes availableSPI
Definitions
STM32F411 I/O map
SPI2:
NSS-PB12,SCK-PB13,MISO-PB14,MOSI-PB15 SPI4:NSS-PB12,SCK-PB13,MISO-PA1,MOSI-PA11 (taken byUSB) SPI5:NSS-PB1,SCK-PA10,MISO-PA12,MOSI-PB0 (taken byUSB)
Usage
from pyb import SPI
spi2 = SPI(2, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi2.send('hello')
spi2.recv(5) # receive 5 bytes on the bus
spi2.send_recv('hello') # send and receive 5 bytesI2C
Definitions
STM32F411 I/O map
I2C1:
SCL-PB6,SDA-PB7 I2C2:SCL-PB10,SDA-PB9 I2C3:SCL-PA8,SDA-PB8
Usage
from machine import I2C
i2c = I2C(1, freq=400000) # hardware I2C: I2C1, PB6, PB7
i2c = I2C(scl='PB6', sda='PB7', freq=100000) # software I2C
i2c.scan() # returns a list of slave addresses
i2c.writeto(0x42, 'hello') # write 5 bytes to the slave at 0x42
i2c.readfrom(0x42, 5) # read 5 bytes from the slave
i2c.readfrom_mem(0x42, 0x10, 2) # read 2 bytes from memory 0x10 of slave 0x42
i2c.writeto_mem(0x42, 0x10, 'xy') # write 2 bytes to memory 0x10 of slave 0x42Servo control
Definitions
The Servo module uses TIM5, so the two cannot be used at the same time — pick one. Servo IDs 1–4 map to PA0, PA1, PA2, PA3.
Usage
from pyb import Servo
s1 = Servo(1) # servo on position 1 (PA0, VIN, GND)
s1.angle(45) # move to 45 degrees
s1.angle(-60, 1500) # move to -60 degrees over 1500 ms
s1.speed(50) # for continuous-rotation servosSwitch
Definitions
On the STM32F4x1Cx core board the button (
KEY) is PA0.
Usage
from pyb import Switch
sw = Switch()
sw.value() # returns True or False
sw.callback(lambda: pyb.LED(1).toggle())LED
Definitions
On the STM32F4x1 core board the blue LED (
C13) is PC13.
Usage
from pyb import LED
led = LED(1) # 1 = blue
led.toggle()
led.on()
led.off()