STM32/CubeMX/SW4STM32/ST-Linkv2(nucleo)でLチカする話
前回の記事でmacでのSTMマイコンの開発環境構築までを行った.
macでstm32な環境をとりあえず作る
今回は,構築した開発環境でプロジェクトを作成してプログラムを書き,プログラマ(ST-LINKv2)を利用してマイコンチップにプログラムの書き込みを行い,Lチカを動作させるところまでを紹介しようと思う.
前回の最後でDFUでの書き込みを行いたいと述べたが,ST-LINKを使った方が簡単だったので,まずはそちらの手法を述べたいと思う.
STM32CubeMXでコードを生成する
STMマイコンのプログラムを書くにあたって,ペリフェラルまわりの設定を簡単に行えて,それをコードとして吐き出してくれるのがこのSTM32CodeMXである.これを使うと初期設定がとても楽に行えるので,まずはこれで使うペリフェラルの設定を行う.
STM32CodeMXを開いて,New Projectを選択.
するとMCUを選択する画面が現れる.今回は秋月でも手に入る,STM32F042K6T6を利用する.PartNumberSearchから型番を選び,チップを選択してプロジェクトを作成する.
するとPinOutの画面が出る. 左側にはペリフェラルが並んでおり,使いたいペリフェラルがある場合はここで選択して欲しいペリフェラルを有効にする.すると右側のPinOutの画面にも出力/入力ピン等が反映されるようになっている. ここではLチカに最低限必要な設定を行う. 適当なGPIPピンを選択してGPIO_OutPutを選択する. すでに色が変化しているところは何かの機能がすでに予約されているピンなので注意する. すると選択したピンはGPIO_OutPutとして設定され,ピンの色が緑色に変化する. さらに,ピンの名前はピンを右クリックし,EnterUserLabelから自由に変更することが可能である.
次にMCUを動かすクロックの設定を行う. Clock Configurationタブをクリックしてクロックに関する設定を行う. 問題がなければそのままの設定で動作する. ペリフェラルによってはクロックの設定が誤っていると動作しないものがあるが,このソフトウェアはそのような状況の場合は警告を出し,自動で訂正する機能が備えてある. 今回は内臓クロック48MHzで動作させる.他にもConfigurationタブ等でペリフェラルの詳細設定ができるが,今回は行わない.参考までにUSBでDFUモードとして動作させる時はconfigurationタブでこんな設定をすれば良さそうである.
ここまでできたら,Generate Codeアイコンをクリックしてコードを生成するが,初回はsetting画面が出る.
ToolChain/IDEは,System Workbench for STM32を使う場合はSW4STM32を選択する.
(出てこなかったらProject->Settingsを開いて設定する)
OKをクリックするとコードが生成される.
これで基本的なコードの生成は完了だ.
WorkbenchでSTM32CubeMXで生成されたコードを開いてLチカコードを挿入!
ここからは,STM32CubeMXで生成したコードをSystem Workbench for STM32で読み込んでプログラムを記述する過程を紹介する.
まずは先ほどCubeMXで生成したコードをインポートする.
インポートは下記のofficialのサイトが説明をしてくれているので参照する.
OpenSTM32 Community Site | Importing a STCubeMX generated project
Fileからimportを選択する. Existing Projects into Workspaceを選択して,先ほど生成したコードのディレクトリの該当ファイルをopenする.
するとimportされ,Src->main.cを見るとこのようになっている. これらがCubeMXで生成されたコードになる.
/* USER CODE BEGIN 〜 */ /* USER CODE END 〜 */
という範囲があるがこのBEGINとENDの中にコードを記述していく. この範囲に記述することで,あとでCubeMXに戻って再度ペリフェラル等の設定を変更してCode Generate を再度行っても,この範囲にあるコードは変更されずに残り,ペリフェラルの初期化コード等がキチンと追加されるようになっている.つまりこの範囲外に書いたコードは再びCode Generate すると消えてしまうことになるので注意する.
ここでコードを一瞥してもらうと,下の方にGPIOのinitがあり,先ほど定義したRED_LED等が見える.
これらのGPIOを繰り返しON/OFFするコードを追加しよう.
mainループのwhile内に,
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
という記述があるが,この/* USER CODE BEGIN 3 */
の下に
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_0); HAL_GPIO_TogglePin(GPIOF, RED_LED_Pin); HAL_Delay(1000);
を追加しよう.
これらメソッドは,HAL Driverを使ってMCUのGPIOとDelayを制御するメソッドである. STM32CubeMXをつかうと自動的にHALなコードが生成され,以前のStdPeriphではなく,HALを使ってコードを書いていくことになるらしい.StdPeriphと比べ,HALは抽象化されており,よりオブジェクト指向的な要素が強いようである.これからの開発にはHALを用いることが推奨されているようなので,今回はHALを用いて書いていく.
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_0);
はGPIOFのGPIO_PIN_0のOUTPUTを反転させるメソッドである. この辺りの引数に何を入れるかは,先ほど見たMX_GPIO_Initメソッドを覗くことで理解できると思うので割愛する. ピン名には先ほどCubeMXで自分が変更したRED_LEDというPinもLED_RED_Pinという形で指定することができるようだ.
ここまで終了したらBuildをする. とんかちのアイコンをクリックすることでBuildできる. 正しくBuildされるとプロジェクトツリーにBinariesの下に.elfという拡張子でバイナリファイルが生成されているはずである.こいつを次のセクションでMCUに書き込む.
書き込み!
ST-LINKv2をつくる
書き込みをするにあたってwriterを必要とする. 今回はST-LINKv2を使って書き込みを行っていこうと思うが,この書き込み機を買うと結構なお値段となる.今回はSWD方式での書き込みをやっていこうと思うが,SWD方式の書き込み機であれば秋月でも手に入るnucleo boardという開発ボードの一部がこの書き込み機となっており,分離して使用することができる.お値段的にもこちらのほうがリーズナブルなので,今回はこちらのnucleo boardの書き込み機部分(ST-LINKv2部分)を分離して書き込み機に変身させる. とはいっても作業はものすごく簡単で,パキッと折るだけである. 作業自体は下記の記事を参考にすると良いと思う.
NucleoとかいうST-LinkをFRISKケースに入れる - STM32 - Tokoro's Tech-Note
STM32に手を出してみた
あとはピンヘッダ等が邪魔なので取り除く. ジャンパピン部分はジャンパする必要は特にない. CN4という左側の6本のピンヘッダがMCUと接続するピンとなっているので,書き込み機として使いやすいようなコネクタ等に付け替えておくと便利だ. 私は普通のピンヘッダのメスを横につけており,そこからオスオスの延長ケーブル経由で書き込んだりということもできるようにしてある.なかなか便利だ. 書き込み機の準備はこれで完了である.
チップに配線!
ST-LINKのCN4は上(1番ピン)から下記のようなピンアサインとなっている.
Pin No. | Name |
---|---|
1 | VDD_TARGET |
2 | SWCLK |
3 | GND |
4 | SWDIO |
5 | NRST |
6 | SWO |
これらをチップの適切な端子に接続する. 接続するピンに関してはデータシートを参照する.
電源ライン,およびBOOT0ピンの配線も行う. BOOT0ピンはGNDレベルにすることでFlashからロードするモードとなるので,今回はGNDに落とす.
いよいよ書く!
書き込むにはデバイスにあらかじめ3.3Vの電源を供給しておく必要がある.これを忘れると書き込み時にWrong Device Detected
と言われて書き込むことができない.
書き込みを実行するにあたり,Debugのconfigurationを行う. Run -> Debug Configurations を選択し,Ac6 STM32 Debuggingにプロジェクトが設定されていることを確認する.DebugをクリックするとBuildされ,書き込まれる. なお上部のバーの虫のアイコン(BUGだ)でも同様のことができる. 書き込みするときのコンソールはこんな感じ.
Open On-Chip Debugger 0.10.0-dev-00275-gd486ac2-dirty (2017-03-06-15:17) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD adapter speed: 1000 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_open_drain connect_assert_srst srst_only separate srst_nogate srst_open_drain connect_assert_srst Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : clock speed 950 kHz Info : STLINK v2 JTAG v23 API v2 M v10 VID 0x0483 PID 0x374B Info : using stlink api v2 Info : Target voltage: 0.007890 Error: target voltage may be too low for reliable debugging Info : STM32F042K6Tx.cpu: hardware has 4 breakpoints, 2 watchpoints Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : Unable to match requested speed 1000 kHz, using 950 kHz adapter speed: 950 kHz STM32F042K6Tx.cpu: target state: halted target halted due to debug-request, current mode: Thread xPSR: 0xc1000000 pc: 0x08000e74 msp: 0x20001800 Info : Unable to match requested speed 8000 kHz, using 4000 kHz Info : Unable to match requested speed 8000 kHz, using 4000 kHz adapter speed: 4000 kHz ** Programming Started ** auto erase enabled Info : device id = 0x10006445 Info : flash size = 32kbytes STM32F042K6Tx.cpu: target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000003a msp: 0x20001800 wrote 5120 bytes from file Debug/led_test.elf in 0.310023s (16.128 KiB/s) ** Programming Finished ** ** Verify Started ** STM32F042K6Tx.cpu: target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000002e msp: 0x20001800 verified 4612 bytes in 0.047620s (94.580 KiB/s) ** Verified OK ** ** Resetting Target ** Info : Unable to match requested speed 1000 kHz, using 950 kHz Info : Unable to match requested speed 1000 kHz, using 950 kHz adapter speed: 950 kHz shutdown command invoked
きちんとSTLINKv2として認識されて書き込みとVerifyができた. 正しく書き込めるとnucleoなST-LINKv2のLEDが緑色に光るようだ. 書き込み機をマイコンから外して,電源ON/OFFまたはリセットをしてもきちんと動く.
これでLチカまで到達できた. Lチカができたということは開発の一通りの流れが理解できたということなので,ここまでくればこっちのものである.あとは自由にペリフェラルを追加して自分の思うままにコードを書くだけだ.めでたし.
ちなみに種々のペリフェラルに関しては下記の記事がとても参考になる. CubeHALでSTM32を使うお勉強 : しろうさぎのblog
References
- ST-LINK/V2 - ST-LINK/V2 in-circuit debugger/programmer for STM8 and STM32 - STMicroelectronics
- NucleoとかいうST-LinkをFRISKケースに入れる - STM32 - Tokoro's Tech-Note
- NUCLEO-L152REにわざわざST-Link v2を接続してOpenOCDで接続してみた - ヾノ*>ㅅ<)ノシ帳
- あおいマウス: STM32 Nucleo Board STM32F401のST-LINK v2
- STM32いじってます
- STM32に手を出してみた
- STM32のハードウェア的環境を今更ですが
- STM32 ST-LINK/V2 書き込み - CCWO
- STM32の開発環境を構築する(わりと楽に) - yuqlidの日記
- stm32の開発環境構築 - Qiita
- STM32F103C8T6をHALで使ってみる。 - ガレスタさんのDIY日記
- STM32CubeのHALをCoIDEに移植してみました ( 工学 ) - チカラの技術 - Yahoo!ブログ
- CubeHALでSTM32を使うお勉強 : しろうさぎのblog
- OpenOCD + ST-LinkでFirmware書き込み - uragami note
- OpenOCD+ST-LinkでARM開発環境の構築 - Qiita
- HAL Driverが使えるSTM32系開発環境を作る - 鳥の巣箱
- 5V耐性 - Darkside(リンクエラー修正しました)