ろこらぼ

僕の開発の手順とか実験結果とか感想とかをつらつら書き込んでいくお墓.僕の魂を成仏させるためのお墓です.いいね・ブクマ・コメント待ってます

STM導入-HALでUARTまで-

前回の導入記事の続き
www.nekorokomemordm.info


今回はHALを使ったUARTについてです.

UART

STM32CubeMXを確認してみると,UART2(俗にいうPCSerial的な)が既に宣言されているのがわかる.なので,UART2を使ってPCと通信をする.
while文を下記のように書き換える.

  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
	  ButtonStatus = HAL_GPIO_ReadPin(B1_Blue_GPIO_Port, B1_Blue_Pin);
	  HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, !ButtonStatus);
	  char transmitData[16];
	  sprintf(transmitData, "data is %d\r\n", !ButtonStatus);
	  HAL_UART_Transmit(&huart2, (uint8_t *)transmitData, sizeof(transmitData), 0x10);
  }
  /* USER CODE END 3 */

次にTeratermを起動して,接続をする.

BaudrateはCubeMXのConfigrationの中で,UART2をダブルクリックすると,下記画面が出てくるので確認をする.もしくは,uart.cの中のvoid MX_USART2_UART_Init(void)でも宣言されている.

f:id:ryuga13tk:20190122184118p:plain
これで,Build実行する.
f:id:ryuga13tk:20190122184127p:plain

UARTもこれで実行が確認できる.

受信完了割り込み

UARTでは受信完了割り込みや送信完了割り込みも用意されているのでそれを書いてく.
まず,STM32CubeMXでUART2を以下のようにUSART2 global interruptにチェックを入れる.
f:id:ryuga13tk:20190122184230p:plain

プログラムを以下のように変更する.
main関数の外に,割り込み完了用の関数を再定義しておく.この関数は,weakで既に宣言してあるので,mainで宣言する必要がある.

int ButtonStatus;
char RxData;
int warikomi_led;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  warikomi_led = !warikomi_led;
  HAL_UART_Receive_IT(&huart2, &RxData, 1);
  //-->割り込みの設定
  HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, warikomi_led);
}

次にmain関数で

warikomi_led = 0;
  while (1)
  {
	  HAL_UART_Receive_IT(&huart2, &RxData, 1);
	  //-->割り込みの設定
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

	  char transmitData[16];
	  sprintf(transmitData, "data is %c\r\n", RxData);
	  HAL_UART_Transmit(&huart2, (uint8_t *)transmitData, sizeof(transmitData), 0x10);
	  //-->受信データを返している
  }

これで,Teretermでキーボードを押すと,押した後にLEDが点滅して,押した英字が返ってくる.

f:id:ryuga13tk:20190122184403p:plain

送信完了割り込みは,ほとんど同じなので割愛._ITを付ければ,使える.

次回はベーシックタイマーペリフェラルの話.

STM導入からLチカまで

 

1 STM32マイコンとは

STM32マイコンとは,ARMのコアを積んだとっても賢いマイコン.

また,ARM-Cortex-M3を積んでいて,自分たちに最も近いものがNucleoシリーズ.これが,STM32マイコン.今回は,NucleoをMbedとしての開発ではなくて,HALでSTM32としての開発をまとめる.エンコーダを読み,それをUARTで吐き出すなどである.

2 対象ソフトインストール

開発手順としては,STM32CubeMXというソフトで,対象マイコンとそのマイコンで使用するペリフェラルの設定を行い,そこからコードを排出する.そのコードの中をTrueStudioで編集・実行・デバッグをする.STMStudioというものも用いてデバッグを行う.



◆下記サイトより,STM32CubeMXをダウンロードする.

https://www.st.com/ja/development-tools/stm32cubemx.html

 

先に,ほかのソフトウェアもダウンロードしておく.

◆TrueStudioをダウンロード.

https://www.st.com/ja/development-tools/truestudio.html

 

◆STMStudioをダウンロード.

https://www.st.com/ja/development-tools/stm-studio-stm32.html

 

すべて要会員登録である.

インストールに際して,注意点などは特にない.

しいて言うならば,TrueStudioをインストール中に,ドライバのインストールが割り込んでくるので,OKしておくこと.

f:id:ryuga13tk:20190107091223p:plain

関連付けるかどうかは,任意でOK.

 

3 プロジェクトの作り方

STM32CubeMXとは,STM32はレジスタをユーザが操作して,制御することができるが,その設定部分を代わりにやってくれるもの.

STM32CubeMXを起動すれば”New Project”をクリックして,ウィンドウを呼び出す.その際に,初回もしくは環境によってはダウロードが発生する.

f:id:ryuga13tk:20190107091311p:plain

画面左上に”MCU Selector”と”Board Selector”があるので,”Board Selector”を選択.”MCU Selector”では,マイコンではなくCPU単体での開発になる.”Board Selector”であれば,ボードが使用しているST-LINKやLED,PCとのSerial部分のペリフェラルを事前に設定してくれているので,明示的にどのピンがデフォルトで使用中であるかがわかる.

今回は,諸事情によりNucle-F411REを用いた開発手順をまとめる.

まず,”Board Selector”で,F411REと入力.

f:id:ryuga13tk:20190107091322p:plain

出てきたボードをダブルクリックしてプロジェクトを作成する.その際に,ボードにデフォルトでついているペリフェラルを使うかどうかと聞かれるのでYesと回答しておく.

f:id:ryuga13tk:20190107091340p:plain

まずはLチカから.出てきた画面は,CPUの各ピンに役割を設定するためのツール.左側からいじれば,ペリフェラルごとに設定ができる.

それじゃ,まずは下のほうにあるPA5がGPIOに設定されていることを確認する.

f:id:ryuga13tk:20190107091353p:plain

普通にGPIOを設定するだけではなく,右クリックして”Enter user label”を選べば,ユーザでピンの名前を設定することができる.

なので今回は,以下のように設定してやってみる.

f:id:ryuga13tk:20190107091406p:plain

今回はボード上についているブルーボタンも使う.CPUの左側一番上にあるB!~~を使うが,GPIO_Inputに,名前もB1_Blueに変更しておく.

f:id:ryuga13tk:20190107091418p:plain

 

f:id:ryuga13tk:20190107091440p:plain

これは,CPUや各ペリフェラルのクロック数を設定する画面であるが,まあ,設定できるところは最大にしちゃってもいいが,大人になったら消費電力のことも考えて,最適な値になるようにしなくちゃいけない.今回はデフォルトのままで行う.

 

Configratinoでは,各ペリフェラルの詳細設定を行うが,今回は何もいじらないのでパスしておく.エンコーダを読むときになれば,設定することになるので,その時に細かく書いておく.

f:id:ryuga13tk:20190107091458p:plain

 

 

最後の画面である.ここでは,実際に生成するコードに関しての設定を行うことができる.

その前準備としてメニュータブのProjectから設定を呼び出す.

f:id:ryuga13tk:20190107091536p:plain

 

Project NameをEX1GPIOにしておく.Project Locationは任意の場所でOK.

Toolchain/IDEをTrueStudioで設定する.

f:id:ryuga13tk:20190107091601p:plain

 

ここで,もしもTrueStudio以外の状態でコードを生成した場合,不具合だと思うが,STM32CubeMXのプロジェクトも最初からやらないと行けなくなる.

f:id:ryuga13tk:20190107091620p:plain

 

Code Generationで.このようにチェックを付けておく(なんとなく便利だから).

こうすることで,本来だとmain.cに書かれるペリフェラルのinit関数をペリフェラルごとに分散してくれる.

f:id:ryuga13tk:20190107091639p:plain




最後にこれをクリックすることで,任意のディレクトリにコードを生成する.

 

そうしたら,TrueStudioを起動する.

 

 

4 コーディングの方法(Lチカを行う)

1 TrueStudioの使い方

TrueStudioを起動すれば,メニュータブのファイルをクリックして”Open project from filesystem”をクリックして,ディレクトリ-(D)をクリックして,STM32CubeMXで作成したプロジェクトのディレクトリへ移動する.

f:id:ryuga13tk:20190107091658p:plain

 

プロジェクトの名前がEX1GPIOなので,そのフォルダをクリックしてひらく.

この時にそのプロジェクトがあり,チェックが入っていることを確認したら終了をクリックする.

そしたら,プロジェクトが追加されるので,EX1GPIOの中のsrc直下のmain.cを開く.

f:id:ryuga13tk:20190107091718p:plain

 

あとは,whileの中のUSERCODEBEGIN~USERCODEENDまでにコードを書く.こういったものがいくつかあるが,範囲外に書くと,STM32CubeMXで再びコードを排出したときに,書いたコードが消えるので注意を.



main関数の外にグローバル関数として,ButtonStatusを宣言しておく.

/* USER CODE BEGIN 0*/
int ButtonStatus;
/* USER CODE END 0*/

 

while内にこのように書く.

 while (1)
 {
 /* USER CODE END WHILE */
 /* USER CODE BEGIN 3 */
 ButtonStatus = HAL_GPIO_ReadPin(B1_Blue_GPIO_Port, B1_Blue_Pin);
 }
 /* USER CODE END 3 */



実行してみる.

トンカチマークでBuildして,虫のマークでデバッグを開始できる.

f:id:ryuga13tk:20190107091745p:plain

デバッグを開始して,デバッグを切って.

デバッグを押して,次はSTMStudioを使う.

 

2 STMStudioの使い方

STMTStudioを起動して,下記マークをクリックして,プロジェクトの.elfファイルを読み込む.

任意のディレクトリの中のDebugフォルダに.elfがあるので,それを読み込む.

f:id:ryuga13tk:20190107091808p:plain

するとこのように,出てくるので,この中からButtonStatusを探し出す.

ButtonStatusを見つけたらクリックして,右側のImportをクリックする.

ここに表示される変数は,すべてグローバル変数なので,モニタリングしたい関数はグローバルで宣言すること.また,宣言時に以下のように宣言すると,アドレスがおかしくなる.

int a, b, c;
------------------
int a = 0;
int b = 0;

f:id:ryuga13tk:20190107091834p:plain

 

Importすると,このようにButtonStatusが移動する.

これを,ドラッグアンドドロップする.

f:id:ryuga13tk:20190107091848p:plain

すると下のほうにButtonStatusと出てくる.ここまで終われば,

f:id:ryuga13tk:20190107091903p:plain

これをクリックしてデバッグを開始する.

そして,ボードのボタンを押すと・・・

f:id:ryuga13tk:20190107091919p:plain

このように値が動いているのがわかる.



これで,STMStuioはいったん終了する.エンコーダを読むときにもう一度扱う.

f:id:ryuga13tk:20190107091932p:plain

また,ここのVar Viewew 1 asを設定すれば,Curb以外にbar graphとtableで値を視認することが可能である.

では次にGPIOをいじるので,TrueStudioに戻り,whileの中をこのようにする.

 

 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 ButtonStatus = HAL_GPIO_ReadPin(B1_Blue_GPIO_Port, B1_Blue_Pin);
 HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, !ButtonStatus);
 }
 /* USER CODE END 3 */



もう一度Buildして実行をする.

これでボタンを押すとボード上のLD2がボタンに合わせて点滅することが分かる.

STM32の開発中に困ったんやけど・・・

どうもこんにちは.

この記事は二言三言だけ言って速攻終わるので,ふーん,ほーんって感じで見てください.

 

僕個人の開発環境が,家のデスクトップPCと持ち運び用のラップトップなのですが,特にGitで連携しているわけでもなくて(していた時期もあります),今までそれぞれその都度プロジェクト作ってコードを切り貼りしていたんですよね.

それで同じようにやったら,TrueStudioでコンパイルができても書き込み,デバッグができなくて頭抱えてたんです.

それでよく見てみたら,プロジェクトのディレクトリが記号と数字のエンコードされた状態になっていたんですよね.
それでああ,これ見たことあるなぁ・・・って思って,気づいたんですけど,ディレクトリが漢字だったんですね.

どおりでおかしいわけですよねぇ.


はい,締めです.


アプリケーションによっては,日本語に対応していないもの(少し前のKicadもそうでしたね)があるので,
ディレクトリ名はできるだけ英語にしましょうっていうことですね(◍•ᴗ•◍)

STM32F303K8T6とHALのSPIでL3GD20を動かした

どうもこんにちは.

今日はSTM32とHALのSPIを使ってジャイロセンサL3GD20を動かしてみましたので,それのまとめをします.

コードに関しては,諸事情により,パブリックに公開するわけにはいかないので,もしもほしければTwitterでDMください.

  1. 開発環境
    ・Windows10.
    ・System WorkBench for stm32.
     stm32のコーディングを行い,書き込む.
    ・CubeMX.
     GUIでできるあれ
    ・Arduino IDE.
     これはセンサデータを可視化するツールです.
    ・STM32F303K8T6が乗っているNucleo.
     スペックはググって.
    ・L3GD20.
     ・XYZ軸ジャイロセンサ
     ・分解能は16ビット
     ・2.4V~3.6V動作.
     ・IO電圧は1.8~電源電圧まで
     ・測定範囲は±250/500/2000dps(°/sec)
     ・インターフェースはI2CまたはSPI.
    以下画像の緑色の基板がL3GD20です.
    f:id:ryuga13tk:20180907044004j:image
    これは僕が設計したセンサ開発評価ボードです.
    おいおいは表面実装のSTM32F303K8T6を乗せるつもりです.Nucleo君とはおさらばの予定です.

    スペックとしては,ジャイロセンサL3GD20,CANのレシーバでMPU2515,エンコーダを読むためのピンを用意してあります.
    USBは100円ショップに売っている光るあれです(データ通信できるものこれしかなかった...).

  2. 開発手順
    まずはCubeMXの画面で以下のようにSPIとUARTの設定をしています.

    f:id:ryuga13tk:20180907042753p:plain


    CANとか関係ないやつも含まれていますが,まあ今後開発していきますよ.
    今回使うのは,下部のSPIの設定とUARTの設定.
    ちなみにSTM32とTeratermを使ってprintfを実装しているのですが,順序が逆転しますが今度投稿します.気になる人は調べてください.

    SPIの設定はこんな感じ

    f:id:ryuga13tk:20180907043011p:plain



    これをworkbenchへコード化して,SPIの実装をすれば完成です(パブリックに公開できない部分です).

  3. 結果
    動かしてみた結果が

    f:id:ryuga13tk:20180907043242p:plain

    これです.
    この画面はArduino IDEというツールを用いてセンサデータをグラフ化しています.
    ちゃんとジャイロが取れていますね.ちなみにセンサは各速度を出力しますが,角度になるようにしています.また,移動平均フィルタをかけています.

  4. 考察
    センサとしては応答性もそれなりに良くて,きれいな値を出すなっていうイメージでした.

    f:id:ryuga13tk:20180907043630p:plain
    これが各速度の生データです.0の時はきれいに0を出すので,大人しい子ですね.
    ただまあ,このセンサも例に漏れず,ドリフト角がそれなりにあることがわかったので,カルマンフィルタあたりを実装する必要があるなっていう感じです.
    元々カルマンフィルタ実装のために作ったセンサ基板だったので,やっと本題に入れるなって感じですが.
    まあ,簡単に角度を算出できるとは思ってなかったので,センサの動作確認とセンサデータの確認ができて満足です.


    次回からはカルマンフィルタの実装をしていくつもり(つもりはつもり)です.

STM32F303K8T6チップを使ってみたよ

環境

・Windows10

・STM32CubeMX

・System workbench for stm32

・STM32 ST-Link Utility

    1. STM32F303K8T6の概要と僕の開発歴の概略
      Arm32bitのCortex-M4です.
      最大周波数が72MHzで,I2C,UART,CANやらタイマーやらRTCが使えます.賢い.
      僕がこれを手に入れたのは,去年の学生ロボコン The landing diskが終わった頃でした.
      そのころ,大工大の交流会で
      大工大のかたに,NUCLEOのCPUを表面実装して,SWDでMbedのプログラム書き込めるしいいぞ~~~~って言ってもらえたんで,頑張って開発進めてたんですよ.1年前から.

      (2018年も交流会やるそうです
      https://twitter.com/OIT_RoboPro/status/1023875838184288256)
      →楽しかったですよ



      それが,まったくうまくいかなかったんですよね,

      なんでだろうな~~って思ってたら,
      あの,チップの向き間違えてました.

      チップの角にくぼみがあるんですけど,そこから反時計回りに1~って感じで,まあ,泣きましたね.

      それに気づいたのは,今年の学生ロボコン ネムコンが終わった後でしたね.ワンシーズン使うってあほですね.


    2. 開発手順
      画像張るの面倒くさいので,まあ,文字だけで手順テキトーに書いていきます.

      STM32CubeMXをインストール
      System workbench for stm32をインストール

      CubeMXが,CPUの設定をGUIで行えるものになっているので,開発時間は半分以下になると考えてもらっていいですね.かなりラクチン.
      workbenchがコーディングやデバッグをするやつです.SWDでデバッグできますね.

      それでいい感じに進めていって,問題が起きたんですよね.

      なぜか書き込めない・・・.

      そこで,プロジェクトの中にデバッグっていうフォルダがあるので,その中の.hexっていう拡張子のファイルを,STM32 ST-Link Utilityを使って書き込んでみたら,動いて,初めてのLチカを成功させ、僕の魂は成仏しました.

      この勢いを使って,来年度のロボコンでさらに成仏したいです.