Demo of the usage USBDevice library with Blue Pill STM32F103C8T6 board.
STM32F103C8T6 USBSerial Demo
This project contains demo of the USB serial usage for a cheap developer board Blue Pill with STM32F103C8T6 mcu.
The USB serial port provides a good communication channel between PC and microcontroller. Especially it can be useful for a debug purposes.
Notes
- by the specifications this board has only 64KB of the flash, but actually it can have 128KB, that will be useful for a debug builds as it requires about 100KB of the flash for this demo.
- the board can have some problems with an USB because it has wrong value of the pull-up resistor
- for steady reading of data from a serial port, the project contains python script serial_reader.py (it requires PySerial and six python libraries), that is steady to the board reloading
- the project depends on the fork of the USBDevice library. This fork contains some fixes and support of the BLUE_PILL_STM32F103C8 target.
- the mbed-os now contains correct code for a clock initialization of the BLUE_PILL_STM32F103C8 target, so you don't need to adjust the board clocks separately
serial_reader.py
- Committer:
- Konstantin Kochin
- Date:
- 2017-08-04
- Revision:
- 0:24604e97c40c
File content as of revision 0:24604e97c40c:
#!/usr/bin/env python from __future__ import print_function import argparse import sys from time import sleep import serial from serial.tools.list_ports import comports from six import binary_type _DEFAULT_BAUD_RATE = 115200 def _reset_baud_drate(serial): original_baudrate = serial.baudrate i = serial.BAUDRATES.index(original_baudrate) if i == -1: raise ValueError("Unknown baudrate {}".format(original_baudrate)) if i > 1: tmp_baud_rate = serial.BAUDRATES[i - 1] elif len(serial.BAUDRATES) > 1: tmp_baud_rate = serial.BAUDRATES[i + 1] else: raise ValueError("Only one baudreate is available") serial.baudrate = tmp_baud_rate serial.baudrate = original_baudrate def _read_from_serial_device(port, out=sys.stdout, reconnect_on_error=True, repeat_delay=2, **port_params): print('Read from the serial port "{}" (use Ctrl+C to exit)'.format(port)) while True: try: with serial.Serial(port=port, **port_params) as com_port: # hack: # when you connect usb-com port of the stm32f1 first time, it will work # but if you reconnect it, then it stop working, although com port readers doesn't show # any error. # However I found that it can be solved by 2 ways: # - host rebooting (but it's very inconvenient) # - changing baudrate. The new value doesn't matter, it should only be different than previous. # Moreover the old values without any problems can be reverted without any problems. # TODO: find reason of such strange behavior _reset_baud_drate(com_port) for line in com_port: if isinstance(line, binary_type): line = line.decode('utf-8') out.write(line) out.flush() except serial.SerialException as e: print("Error: {}".format(e)) if not reconnect_on_error: break sleep(repeat_delay) def _guess_serial_device_name(): ports = list(comports()) if len(ports) == 1: port = ports[0].device elif len(ports) == 0: raise ValueError("No serial devices found") else: print("Several serial devices are found. Please specify one of them explicitly:") for port_info in ports: print("- {}".format(port_info.device)) raise ValueError("Multiple serial devices are found.") return port def main(args=None): parser = argparse.ArgumentParser(prog='serial_reader', description='Helper program that read text from a serial port. ' 'Unlike other com programs it automatically reconnect ' 'to serial port if any error occurs. It is useful for ' 'microcntrollers debugging when you want to reboot it and' 'the connection will be lost for some time.') parser.add_argument('port', nargs='?', help='Serial port device name. It it is not specifies, then' 'it will be found automatically if it is possible') parser.add_argument('--baudrate', default=_DEFAULT_BAUD_RATE, help="baud rate. Default: {}".format(_DEFAULT_BAUD_RATE)) parsed_args = parser.parse_args(args) if parsed_args.port is None: try: port = _guess_serial_device_name() except Exception as e: print(e) sys.exit(1) else: port = parsed_args.port try: _read_from_serial_device( port, baudrate=parsed_args.baudrate ) except KeyboardInterrupt: print("Exit ...") if __name__ == '__main__': main()