Edited at

STM32F103C8 で遊ぶ

More than 1 year has passed since last update.


STM32F103C8とは

STMicroの32bitマイコン。

ARMコアで Cortex-M3

USBやCANが使える。

今回は、Blue Pill だとかという名前で知られているマイコンボードを使う。


Blue Pill

IMG_20170629_121857.jpg

eBayなどでは200円台。安い! Arduino開発環境でも使えるそうだ。

情報はここ

http://wiki.stm32duino.com/index.php?title=Blue_Pill


オリジナルは?

しかしながらオリジナルの設計がどうなっているのかわからない。

ライセンスわからないけど、中国では小麦の粒と汗で汚れたシャツに油と牛乳をたらしそれを壺にいれ倉庫に放置することによりガジェットが自然発生する。これも自然に発生したのだろう。


2017.8.15 追記

どうやら LeafLabs の Maple Miniのコピーっぽい

https://www.leaflabs.com/maple

https://developer.mbed.org/users/hudakz/code/MapleMini_Hello/

オリジナルのボードはCC-BY-SA2.0


比較

安いマイコン使って入場証を作りたい


  • マイコンチップは100円台

  • 電池駆動

  • ちょっと複雑なプログラム走らせたい


    • 複数プログラムをメニューで切り替える



  • 開発環境はマルチプラットフォーム(Windows,OSX,Linux)対応

  • 開発環境はオープン


候補 非ARM系


ATMEGA8A

    8KBytes Flash

512Bytes EEPROM
1KByte SRAM


LGT8F88A

    8KBytes Flash

504Bytes EEPROM
2KByte SRAM


候補 ARM系


STM32F030K6

    32KBytes Flash

4KByte SRAM


STM32F103C8

    64KBytes Flash

20KByte SRAM


LPC812M101

    16KBytes Flash

4KByte SRAM

STM32F103C8が際立ってますね。EEPROMが無いのですが、以下のようなSTM32F103でFlashをEEPROMのようにする資料がりました。

http://www.st.com/content/ccc/resource/technical/document/application_note/ee/ef/d7/87/cb/b7/48/52/CD00165693.pdf/files/CD00165693.pdf/jcr:content/translations/en.CD00165693.pdf

なのでとりあえず STM32F103C8 で考えることにしました。


ブートローダーを書き込む

モノによってはブートローダーが入っているのもあるけれども、そうでないものは書き込んで使おう。

ブートローダーが入ると


  • Arduino開発環境からオンボードのmicroUSB接続で書き込めるようになる(不具合あり)

  • Arduino開発環境からFT232などのUSBシリアルアダプタを使って書き込めるようになる(別売り)

なお、ST-Linkを使うとブートローダーが無くても書込できます。


準備


ブートローダをダウンロード

https://github.com/rogerclarkmelbourne/STM32duino-bootloader/tree/master/STM32F1/binaries

generic_boot20_pc13.bin

からダウンロードします。


Arduino開発環境にSTM32を追加する

あらかじめ、ArduinoIDEをダウンロード&インストールしているとして、

https://github.com/rogerclarkmelbourne/Arduino_STM32/archive/master.zip

から

Arduino_STM32-master.zip としてダウンロード、展開して~/Arduino/hardwareの中に展開します。

hardware/Arduino_STM32-master というようになります。

Linux以外の人は、これを見てみてね。

https://github.com/rogerclarkmelbourne/Arduino_STM32/wiki/Installation

この作業を終えると、ブートローダを書き込むためのstm32flashが使えるようになりますが、Arduino開発環境でSTM32のコンパイルをするためには、まだ下記の「# Arduino開発環境で遊ぶ」処理が必要ですのでご注意。


USBシリアルアダプタを使って書き込む方法

ジャンパーピンを書き込みモードにします。

IMG_20170629_121923.jpg


USBシリアル

CH340 を使った USBシリアル。いつもはこれを使ってますが、うまくいきませんでした。

IMG_20170629_121940.jpg

Linuxのドライバがアレということで、Windowsとかだと問題はないそうです。

しかしながら Ubuntu Linux 16.04 を使用しているのでトラップにハマりました。

仕方がないので秋月電子の超小型USBシリアル変換モジュール

[AE-FT234X]

http://akizukidenshi.com/catalog/g/gM-08461/

を使いました。

こんな感じに配線します。

IMG_20170628_022335.jpg

先にインストールしたArduinoのためのSTM環境に、書込ツールが入っているのでそれを使ってブートローダーを書き込みます。


nanbuwks@LATITUDE:~/Arduino/hardware/Arduino_STM32-master/tools/linux64/stm32flash$ ./stm32flash -w ~/Downloads/generic_boot20_pc13.bin -v -g 0x0 /dev/ttyUSB0
stm32flash Arduino_STM32_0.9

http://github.com/rogerclarkmelbourne/arduino_stm32

Using Parser : Raw BINARY
Interface serial_posix: 57600 8E1
Failed to read ACK byte
Unexpected reply from device on command 0x01

あれれー。

https://sourceforge.net/p/stm32flash/tickets/81/

によると、CH340はだめだそうだ。

仕方がないので秋月に行ってFT232系のアダプタを買ってきた。

TUDE:~/Arduino/hardware/Arduino_STM32-master/tools/linux64/stm32flash$ ./stm32flash -w ~/Downloads/generic_boot20_pc13.bin -v -g 0x0 /dev/ttyUSB0 

stm32flash Arduino_STM32_0.9

http://github.com/rogerclarkmelbourne/arduino_stm32

Using Parser : Raw BINARY
Interface serial_posix: 57600 8E1
Version : 0x22
Option 1 : 0x00
Option 2 : 0x00
Device ID : 0x0410 (Medium-density)
- RAM : 20KiB (512b reserved by bootloader)
- Flash : 128KiB (sector size: 4x1024)
- Option RAM : 16b
- System RAM : 2KiB
Write to memory
Erasing memory
Wrote and verified address 0x08001c14 (100.00%) Done.

Starting execution at address 0x08000000... done.

書けた。

オンボードのUSBコネクタにPCを繋いたときの、PC(Linux)のdmesg。


[158817.551373] usb 1-1.2: new full-speed USB device number 16 using ehci-pci
[158817.645603] usb 1-1.2: New USB device found, idVendor=1eaf, idProduct=0003
[158817.645610] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[158817.645614] usb 1-1.2: Product: Maple 003
[158817.645617] usb 1-1.2: Manufacturer: LeafLabs
[158817.645619] usb 1-1.2: SerialNumber: LLM 003

うん、なんか動いているみたいです。


ST-Linkを使ってブートローダーを書き込む

st-flashを使います。

https://github.com/texane/stlink

cloneしてmakeして・・・と思ったら、以前 ChibiOS の勉強会に行った時に既にインストールしていました。そちらを使います。

(2018/11/1追記 Arduinoフォルダの中の hardware/Arduino_STM32-master/tools/linux64/ 中に stlinkファイルありました)


$ st-flash write ~/Downloads/generic_boot20_pc13.bin 0x8000000
st-flash 1.3.0-9-g88c6162
2017-08-17T13:17:48 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Loading device parameters....
2017-08-17T13:17:48 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Device connected is: F1 Medium-density device, id 0x20036410
2017-08-17T13:17:48 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 1024 bytes
2017-08-17T13:17:48 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Attempting to write 7188 (0x1c14) bytes to stm32 address: 134217728 (0x8000000)
Flash page at addr: 0x08001c00 erased
2017-08-17T13:17:49 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Finished erasing 8 pages of 1024 (0x400) bytes
2017-08-17T13:17:49 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Starting Flash write for VL/F0/F3 core id
2017-08-17T13:17:49 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/flash_loader.c: Successfully loaded flash loader in sram
7/7 pages written
2017-08-17T13:17:49 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Starting verification of write complete
2017-08-17T13:17:49 INFO /home/nanbuwks/Downloads/chibios-verifast-master/stlink/src/common.c: Flash written and verified! jolly good!


Arduino開発環境で遊ぶ

ボードマネジャでインストールします

ツール → ボード → ボードマネジャで

Arduino SAM Boards (32-bits ARM Coretex-M3) by Arduino

を選びます。


ボードを選ぶ

image.png

"Generic STM32F103C Series" を選びます。


Upload Methodを選ぶ

image.png

オンボードのUSBコネクタを使うとき STM32Duino bootloader

USBシリアルを使うとき Serial を選択して「シリアルポート」を選ぶ

STLinkアダプタを使うとき STLink

を選びます。


BLINK

image.png

13をPC13に変更すると動作します。


ST-Linkを使う

このように配線。書込も確認。

IMG_20170629_014214.jpg

最大65,536バイトのフラッシュメモリのうち、スケッチが12,980バイト(19%)を使っています。
グローバル変数は2,816バイトのRAMを使用しています。
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/tools/linux/stlink_upload ttyUSB0 {upload.altID} {upload.usbID} /tmp/buildbcb54ea7edda04e2802a263e09041e39.tmp/Blink.ino.bin
2017-06-29T01:42:04 INFO src/stlink-common.c: Loading device parameters....
2017-06-29T01:42:04 INFO src/stlink-common.c: Device connected is: F1 Medium-density device, id 0x20036410
2017-06-29T01:42:04 INFO src/stlink-common.c: SRAM size: 0x5000 bytes (20 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 1024 bytes
2017-06-29T01:42:04 INFO src/stlink-common.c: Attempting to write 12980 (0x32b4) bytes to stm32 address: 134217728 (0x8000000)

Flash page at addr: 0x08000000 erased
Flash page at addr: 0x08000400 erased
Flash page at addr: 0x08000800 erased
Flash page at addr: 0x08000c00 erased
Flash page at addr: 0x08001000 erased
Flash page at addr: 0x08001400 erased
Flash page at addr: 0x08001800 erased
Flash page at addr: 0x08001c00 erased
Flash page at addr: 0x08002000 erased
Flash page at addr: 0x08002400 erased
Flash page at addr: 0x08002800 erased
Flash page at addr: 0x08002c00 erased2017-06-29T01:42:04 INFO src/stlink-common.c: Finished erasing 13 pages of 1024 (0x400) bytes
2017-06-29T01:42:04 INFO src/stlink-common.c: Starting Flash write for VL/F0/F3 core id
2017-06-29T01:42:04 INFO src/stlink-common.c: Successfully loaded flash loader in sram

Flash page at addr: 0x08003000 erased

0/12 pages written
1/12 pages written
2/12 pages written
3/12 pages written
4/12 pages written
5/12 pages written
6/12 pages written
7/12 pages written
8/12 pages written
9/12 pages written
10/12 pages written
11/12 pages written2017-06-29T01:42:05 INFO src/stlink-common.c: Starting verification of write complete

12/12 pages written2017-06-29T01:42:05 INFO src/stlink-common.c: Flash written and verified! jolly good!

書けました。


OLEDを使って遊ぶ


怪しいOLEDモジュール

IMG_20170629_112320.jpg

I2Cで購入したけど・・・なんだこりゃ。SCKとSDA???


AVR系Arduino互換機で確認

まずはLeonardo互換機を使って、動作の確認。

U8glibを使い、サンプルプログラムのGraphicsTest.inoで動きました。


//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send AC

ここを適用しています。I2Cには違いないようです。AdaFruitのSSD1803の設定で動作しました。


STM32F103C8 + AdaFruitライブラリ

次に、STM32F103C8につなぎます。U8glibではエラーが出て動かなかった

ビルドオプションが変更されました。全体をリビルドしています。

警告:ライブラリU8glibはアーキテクチャ[avrに対応したものであり、アーキテクチャsam]で動作するこのボードとは互換性がないかもしれません。
In file included from /home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/boards.h:38:0,
from /home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/wirish.h:54,
from /home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/Arduino.h:30,
from /home/nanbuwks/Arduino/libraries/U8glib/src/clib/u8g_com_arduino_common.c:46:
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/wirish_types.h:66:1: error: unknown type name 'bool'
typedef bool boolean;
^
In file included from /home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/wirish.h:54:0,
from /home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/Arduino.h:30,
from /home/nanbuwks/Arduino/libraries/U8glib/src/clib/u8g_com_arduino_common.c:46:
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/boards.h:111:1: error: unknown type name 'bool'
bool boardUsesPin(uint8 pin);

・・・

/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isLowerCase':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:106:30: error: 'false' undeclared (first use in this function)
return (islower (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:106:38: error: 'true' undeclared (first use in this function)
return (islower (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isPrintable':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:113:31: error: 'false' undeclared (first use in this function)
return ( isprint (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:113:39: error: 'true' undeclared (first use in this function)
return ( isprint (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isPunct':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:121:31: error: 'false' undeclared (first use in this function)
return ( ispunct (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:121:39: error: 'true' undeclared (first use in this function)
return ( ispunct (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isSpace':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:130:31: error: 'false' undeclared (first use in this function)
return ( isspace (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:130:39: error: 'true' undeclared (first use in this function)
return ( isspace (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isUpperCase':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:137:31: error: 'false' undeclared (first use in this function)
return ( isupper (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:137:39: error: 'true' undeclared (first use in this function)
return ( isupper (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h: In function 'isHexadecimalDigit':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:145:32: error: 'false' undeclared (first use in this function)
return ( isxdigit (c) == 0 ? false : true);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/cores/maple/WCharacter.h:145:40: error: 'true' undeclared (first use in this function)
return ( isxdigit (c) == 0 ? false : true);
^
exit status 1
ボードGeneric STM32F103C seriesに対するコンパイル時にエラーが発生しました。
Arduino Version: unknown
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/examplesにboards.txtがありませんでした。1.5以前のものですか?
Arduino Version: unknown

ので、AdaFruitのSSD1693ライブラリを使いました。

ライブラリ付属のサンプルプログラム、

「ファイル」-「スケッチ例」-「Generic STM32F103C Series用のスケッチ例 」のところにある「Adafruit_SSD1306」-「ssd1306_128x64_i2c_stm32」を呼び出し、

ssd1306_128x64_i2c_stm32.ino をコンパイルすると・・・


![IMG_20170629_010952.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/20776a4b-8922-d6f7-d558-0f393eddc173.jpeg)

/tmp/arduino_modified_sketch_946602/ssd1306_128x64_i2c_STM32.ino:28:26: fatal error: Adafruit_GFX.h: No such file or directory
#include <Adafruit_GFX.h>
^
compilation terminated.
exit status 1
ボードGeneric STM32F103C seriesに対するコンパイル時にエラーが発生しました。
Arduino Version: unknown

となったので、

http://www.stm32duino.com/viewtopic.php?f=19&t=2096&p=28233&hilit=1306#p28233

ここを参考にして、

https://github.com/adafruit/Adafruit-GFX-Library


/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306

に展開した。

(2017/11/1 修正)

「スケッチ」-「ライブラリをインクルード」-「ライブラリを管理」で

「Adafruit_GSX_Library」をインストールした。

また、以下のエラーが出たので

(記事初出時に使用した2017/6/20バージョンのArduino_STM32だと、以下のエラーが発生したが、2017/10/31のArduino_STM32だと以下は起こらなくなっていたので記述を取り消し)


/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawPixel(int16_t, int16_t, uint16_t)':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp:115:14: error: 'swap' was not declared in this scope
swap(x, y);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawFastHLine(int16_t, int16_t, int16_t, uint16_t)':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp:571:16: error: 'swap' was not declared in this scope
swap(x, y);
^
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawFastVLine(int16_t, int16_t, int16_t, uint16_t)':
/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp:639:16: error: 'swap' was not declared in this scope
swap(x, y);
^
exit status 1
ボードGeneric STM32F103C seriesに対するコンパイル時にエラーが発生しました。


/home/nanbuwks/Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/


Adafruit_SSD1306_STM32.h


#define swap(a, b) { int16_t t = a; a = b; b = t; }

を追加した。

(2017/11/1追加)

2017/10/31のArduino_STM32だと以下のエラーが出るようになった。


/home/nanbuwks/Downloads/arduino/linux64/arduino-1.8.5_STM32/hardware/Arduino_STM32-master/STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp:26:22: fatal error: HardWire.h: No such file or directory
#include <HardWire.h>
^
compilation terminated.


./Arduino/hardware/Arduino_STM32-master/STM32F1/libraries/Wire

の中にHardWire.h , HardWire.cppが無くなっているのが原因。

http://www.stm32duino.com/viewtopic.php?f=2&t=2627&p=34928&hilit=HardWire.h#p34928

を参考に

Arduino_STM32-masterの中にある STM32F1/libraries/Adafruit_SSD1306/Adafruit_SSD1306_STM32.cpp

を修正


#include <avr/pgmspace.h>
//#ifndef __SAM3X8E__ || __STM32F1__
//#include <util/delay.h>
//#endif
#include <stdlib.h>

//#include <HWIRE.h>
//#include <HardWire.h>
//HardWire HWIRE(1,I2C_FAST_MODE); // I2c1
HardWire HWIRE(2,I2C_FAST_MODE); // I2c2

を以下のように書きなおす。


#include <avr/pgmspace.h>
//#ifndef __SAM3X8E__ || __STM32F1__
//#include <util/delay.h>
//#endif
#include "Wire.h"
#define WIRE_WRITE HWIRE.write

#include <stdlib.h>

//#include <HWIRE.h>
//#include <HardWire.h>
//HardWire HWIRE(1,I2C_FAST_MODE); // I2c1
HardWire HWIRE(2,I2C_FAST_MODE); // I2c2

動きました。

IMG_20170629_023401.jpg