2. UART(Serial通信)とツールの使い方
目標
- STM32CubeIDEにおけるプロジェクト作成時の定形作業をできるようになる
- プロジェクトの作成からWrapperの作成までを定形作業とする
- HALライブラリの規則を知る
- UARTを使えるようになる
プロジェクト作成
- メニューバーから
File/New/STM32 Project
を選択するデータのダウンロードが自動で行われることがある
- マイコンの選択を行う
Commercial Part Number
に "F446RE"と入力するSTM32F446RET6
を選択する- 次へ進む
Project Name
を入力するプロジェクト名は自分で分かれば何でも良いです. 特にこだわりがないなら
UART
としておきましょう.Targeted Language
をc++
にする
マイコンの設定(CubeMX)
- conecctibityからUSART2を選択する
- Modeを
Asynchronous
に設定する Baud Rate
を115200
に設定する- マイコンの
PA2, PA3
がUART機能に割り当てられていることを確認する - 写真を参考にチェックを入れる
このチェックを入れることを前提としてライブラリの作成等をしているので,忘れないようにしましょう. マイコンの設定は
<Project Name>.ioc
のように拡張子がiocのファイルに保存されている.このファイルを開くとマイコンの設定の画面が開く.
プログラミング
wrapper.hpp
とmain.c
は同じ内容なので,次回以降の資料では省略する.
Wrapperファイルの作成
本環境ではmain関数がmain.c(C言語)に作成されるため,c++の機能を使用するためにWrapperを作成する必要がある.
1. Core/Inc
にwrapper.hpp
を作る
2. Core/Src
にwrapper.cpp
を作る
wrapper.hpp
c++とc言語を繋ぐための関数のプロトタイプ宣言をしている.extern "C" {}
で囲われた関数は内部的にc言語と同様に定義されるため,C言語のファイルから呼び出すことが可能である.基本的には,必要な機能はどのようなプロジェクトでも同じであるため,ファイルの中身はコピーして使いまわすことが多い.
wrapper.cpp
Arduino環境でソースコードを書くときと同様にコードを書くファイルである.
HALライブラリの解説
命名規則
STMマイコンのプログラムで使用する関数群のことを"HALライブラリ(HAL)"と呼ぶ.関数の命名規則は一貫して以下に従っている.
HAL_<periferal name>_<behavior>(<periferal handler>,...);
'UART
やGPIO
などのマイコンの機能の名前である.
<behaviot>
はどのような動作をするかを示している.例えば,通信で受信をするときにはReceive
のようになる.
<behaviot>
は複数のアンダーバーで区切られていることがある.
HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
UARTでデータを送信するための関数である.pData
には送信したい配列の先頭アドレスを渡す.Size
は送信データの長さ(byte)である.
Timeout
で指定した時間(ms)だけ通信が終了しなかった場合に関数を終了する.Timeout
は通信処理が上手くいかないときに処理全体がフリーズすることを防ぐためにある.
huart
にはペリフェラルのハンドラーのポインターを渡す.コード生成の時点でuart1であればhuart1
のように自動で宣言されている.
期待する動作
本プログラムはシリアルモニタに接続した状態で起動することを想定している.
起動時にHello World
と表示され,その後,count:<number>
と表示され
サンプルコード
wrapper.hpp
#ifndef INC_WRAPPER_HPP_
#define INC_WRAPPER_HPP_
#ifdef __cplusplus
extern "C" {
#endif
void init(void);
void loop(void);
#ifdef __cplusplus
};
#endif
#endif /* INC_WRAPPER_HPP_ */
wrapper.cpp
#include "wrapper.hpp"
#include "usart.h"
#include <string>
void init(){
uint8_t str[] = "Hello World";
HAL_UART_Transmit(&huart2, str,11,100);
}
void loop(){
HAL_Delay(100);
static uint16_t count = 0;
std::string str = "count:"+std::to_string(count++)+"\n";
HAL_UART_Transmit(&huart2, (uint8_t *)str.c_str(),str.length(),100);
}
main.c
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "wrapper.hpp"
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
loop();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */