stm32 halライブラリ、makefileでprintf(float型)を使えるようにする!

こんにちは

時が過ぎるのが速すぎて焦っています。もう三月の後半・・・

今日はタイトル通りprintfの実装の仕方を書いていきます。

 

まずはstm32cubeでuartの設定をします。

f:id:sora_siro:20180322104348p:plain

f:id:sora_siro:20180322104400p:plain

こんな感じで・・・baud Rateなどはシリアル通信をするソフトなどとの兼ね合いを付けてください。

そしたらcubeにコードを生成してもらいましょう。

 

次に、syscalls.cをSrc直下においてください。ファイルのリンクを張っておきます。

syscalls.c

この状態でmakeしてもsyscalls.cはコンパイルされません。なのでmakefileに追記する必要があります。2か所あり、一つ目はsource内にsyscalls.cを追記することです。

######################################
# source
######################################
# C sources
C_SOURCES = \
省略
(ex)Src/main.c\
  Src/syscalls.c

2つ目はLDFLAGに-u _printf_floatと追記してください。

LDFLAGS = 省略 -u _printf_float

ここまででひとまずmakefileに追記することはおしまいです。

 

続いて、main.cを開いて下さい。

// includesにこのように書いて下さい。

 
#include <stdio.h>
 

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
void __io_putchar(uint8_t ch) {
HAL_UART_Transmit(&huart1(初期設定で使用したuartを設定してください), &ch, 1, 1);
}

 また、printfを使用する前に(int main()のINIT()のあとにでも)この関数を呼び出しておいて下さい。

setbuf(stdout, NULL);

 

まとめ

マイコンでprintfが最初から実装されていることにありがたみをとても感じました。

マクロ定義の使い方が難しい・・・

 

最後に

知見のある方でこうしたほうがいいのではないかってことがありましたら教えていただきたいです。

stm32f405rgtでspi通信(L3GD20)を使ってみる

早速進めていきたいと思います。

 

使用するもの

L3GD20

STM32F405RGT

 

使用するソフト

visual studio code

cmd( makefile , arm-none-eabi-gcc )

 

まずはstm32cubemxでSPI通信の設定をします。

今回はSPI2を Full-Duplex Masterに設定して、どこか一つのポートをGPIO_OUTPUTに設定します。

f:id:sora_siro:20180224155344p:plain

その後、SPIの設定を変更します。

f:id:sora_siro:20180224160233p:plain

SPIの通信速度によってプリスケーラの値は適宜変更してください。

ここで、L3GD20は10Mhzで通信を行えるので10Mhzで設定しました。

あとはGPIO_PIN_OUTPUTのラベルを付けておくと後でソフトを書くときに楽になるのでつけておくことをお勧めします。

 

ここまで設定をしたらコードを作成してもらいましょう。

これで、cubemxでの作業はおしまいです。

 

そしたらvisual studio codeでソフトを書いていこうと思います。(開発環境については)stm32のローカル環境構築のメモ1,stm32のローカル環境構築のメモ2を参照して頂ければ幸いです。

main.c( spi.c)内に記述していきます。

追加で記述したコードです。

// ジャイロ関連
#define WHO_AM_I 0x0F
#define CTRL_REG1 0x20
#define CTRL_REG4 0x23
#define OUT_Z_L 0x2C
#define OUT_Z_H 0x2D

#define Certain 0xD4
#define POWER_ON 0x0F
#define L3GD20_500dps 0x10
#define L3GD20_2000dps 0x20

#define SETTING 0x80

 

///////////////////////////////////////////////////////////////////////
// spi read 1 byte upper bit ( signed )
// [argument] Register
// [Substitutiong] nothing
// [return] 1byte upper bit data
///////////////////////////////////////////////////////////////////////
int16_t readShiftByte( uint8_t reg )
{
uint8_t address,val;
int16_t ret;
HAL_GPIO_WritePin( gyro_cs_GPIO_Port, gyro_cs_Pin, RESET );
address =( reg|SETTING );
HAL_SPI_Transmit( &hspi2, &address,1,100 );
HAL_SPI_Receive( &hspi2,&val,1,100 );
ret = (int16_t)(val<< 8);
HAL_GPIO_WritePin( gyro_cs_GPIO_Port,gyro_cs_Pin, SET );
return ret;
}

///////////////////////////////////////////////////////////////////////
// spi write 1 byte
// [argument] Register
// [Substitutiong] write data
// [return] nothong
///////////////////////////////////////////////////////////////////////
void writeByte( uint8_t reg, uint8_t val )
{
HAL_GPIO_WritePin( gyro_cs_GPIO_Port, gyro_cs_Pin, RESET );
HAL_SPI_Transmit( &hspi2, &reg,1,100 ); // 書き込みアドレス??��?��???��?��?
HAL_SPI_Transmit( &hspi2, &val,1,100 ); // 書き込み
HAL_GPIO_WritePin( gyro_cs_GPIO_Port,gyro_cs_Pin, SET );
}

///////////////////////////////////////////////////////////////////////
// l3gd20 set up ( spi )
// [argument] nothing
// [Substitutiong] nothing
// [return] nothig
///////////////////////////////////////////////////////////////////////
void setL3GD20( void )
{
uint8_t ret;
ret = readByte( WHO_AM_I );
printf("who am i = 0x%x",ret);
writeByte( CTRL_REG1, POWER_ON );
writeByte( CTRL_REG4,L3GD20_2000dps );
}

///////////////////////////////////////////////////////////////////////
// spi read 1 byte
// [argument] nothing
// [Substitutiong] nothing
// [return] 2000 deg/sec int data
///////////////////////////////////////////////////////////////////////
int getGyroZ( void )
{
int ret;
// *0.070 because you read l3gd20 manual
ret = ( readShiftByte(OUT_Z_H) | readByte(OUT_Z_L) ) * 0.070;
return ret;
}

(インデントが崩れているのは目をつぶっていただきたいです。

やばいインデント警察に捕まってしまう・・・)

そしたら、関数のプロトタイプ宣言などをして、

int main(void)
{

/* USER CODE BEGIN 1 */
 
/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM4_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_SPI2_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_ADC3_Init();

/* USER CODE BEGIN 2 */
setbuf(stdout, NULL);
setL3GD20();
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
printf( "gyro z axis %04d\r",getGyroZ() );
} //switch end
} // while end
/* USER CODE END 3 */

}

 とすることでジャイロセンサーの値を2000deg/secでtera termなどで表示することができると思います。この開発環境でprintfを実装する方法は後々このブログに書いていこうと思います。

詳しくはマニュアルやリファレンスマニュアルなどを参考にしてください。

 

最後に

つたない文章を最後まで読んでいただきありがとうございます。

知見のある方でここをこうしたほうがいいとのことがあれば教えていただきたいです。

stm32のローカル環境構築のメモ その2

前回のstm32のローカル環境構築のメモ その1の続きを書いていきたいと思います。前回はローカル環境にコンパイラなどを落としたので今回はそのあとのことを少々書きたいと思います。

ではいきなり始めていきます。

ソフトは visual studio code を使用します。

 

visual studio code (vs code) をインストールしてください。そしたら、vscodeでcmdをたたけるようにしましょう。(ほかのサイトなどを参考にしてください。)

その後、stm32cubeを使用するなり、mbed のサイトからmakefile形式でプロジェクトを作ったらあとはmakeとたたくだけです。

 

ここからははまった点をいくつか紹介します。

 

makeとコマンドを打つ前にbuildのディレクトリを作業スペース直下に作成されていないとエラーが出てしまうことがあります。

次に、stm32cubeで生成してもらったmakefile

binaries

直下の

$(BINPATH)\

というのを消さないとmakeがたたけないことがありました。

 下記のようにするといいです。

#######################################
# binaries
#######################################
BINPATH =
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
AR = $(PREFIX)ar
SZ = $(PREFIX)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
 

 

最後に

そのほかにもはまった点などが見つかった場合ここに追記していきたいと考えています。また、ここが間違っているとのことがあれば指摘していただけると幸いです。

 

あけましておめでとうございます。

もう新年があけてから一週間以上たってしまいました・・・。

今後。このブログではロボトレの制御の話とか前回挙げた開発環境の話の続きとかをできたらいいなと思っています。

今年もどうぞよろしくお願いします。

日々の進捗報告 わくわく

f:id:sora_siro:20171209235657p:plain

ロボトレの基板発注!!

果たして動くのか?いまから楽しみです。

 

追記 フットプリントが間違っている箇所があったため残念ながら走らせることができない状態に・・・周辺機能を確認して再発注!!

プログラムについて記事を書くかもしれないです。

mbed・stm32のローカル環境構築のメモ その1

はじめに

こんばんは。先日、stm32マイコンをローカルで開発できるようにしたいと思っていましたが、パソコンなどの知識が全然なく自分の力で構築することは無理だと思っていたところyuqlidさんのブログのVisual Studio Codeでstm32の開発環境構築に挑戦した話を拝見して同じようにやればできるのではないかと思い実際に環境を導入しようとしました。しかし、最後のvisual codeとの連携のところではまってしまい知り合いの方に助けていただきなんとか構築することができました。

実際にやるときの流れやはまるポイントのやり方を紹介していきたいと思います。ほとんどがyuqlidさんのブログを大変参考にしているのでそちらを見たほうがいいと思います。

 

構築環境  windows10 pro , core i5

コマンドプロンプト(cmd)を使用してコンパイルなどはします。

今回はmbedのプログラムをcmdでコンパイルできるところまで書きます。

 

 

まず初めにMake for Windows,GNU ARM Embedded Toolchain , The GNU MCU Eclipse Windows Build Tools

をインストールしてください。

Make for Windowsはインストールした後にパスを通さないとcmdで使用することはできないのでパスを通します。

パスの通し方は、コントロールパネル→システムとセキュリティ→システム→

システムの詳細設定→環境変数 その後ぱPATHを編集orダブルクリック→参照

参照はMake for Windowssのインストーラー通りのままインストールして設定したときは「C:\Program Files (x86)\GnuWin32\bin」になりました。\GnuWin32\binにパスを通してください。

また、GNU ARM Embedded Toolchain はインストール終了後にチェックボックスにパスを通すというものがあるのでそこにチェックをつければokです。The GNU MCU Eclipse Windows Build Toolsはパスを通していません(まだhファイルをインクルードしていないので必要性がないため)必要性が出たら構築してここにやり方を書こうと思っています。

(*私は Rapid Environment Editorを使用してやりました。使い方はネットで調べてください。)

さて、実際にパスが通ったか確認してみましょう。まずcmdを起動します。起動したらそこに「make -v」と打ち込んでください。パスが通っているとバージョンがわかります。同様に「arm-none-eabi-gcc -v」と打つとmakeと同じようにgcc-armのバージョン確認ができます。通ってなかったときはmakeはパスを通しなおす。arm-none-eabi-gcc のほうは一度アンインストールしてもう一度インストールしなおしてチェックボックスにチェックを付けたほうが楽かもしれないです。

 

これで下準備は終了です。

そして、makefileさえあればmbedのコンパイルもstm32のコンパイルもできます。

ブラウザを開いてmbed compilerを開きましょう。

開いたらプログラムのファイルの横で右クリック、プログラムのエクスポートを押します。そこでエクスポートツールチェインをgcc(arm embedded)にしてエクスポートしてください

f:id:sora_siro:20171202215937p:plain

ダウンロードしたら解凍して適当な場所に移動してください。

cmdを起動してください。cmdで先ほど解凍したディレクトリの階層まで移動してください。( 例 > cd Documents/test )

そこにmakefileがることを確認してください( > dir )

そしたら >makeとたたいて下さい

するとコンパイルされるはずです。

 

 

まとめ

知見のある方でこうしたほうがいいのではないかってことがありましたら教えていただきたいです。

 

参考サイト

 

Visual Studio Codeでstm32の開発環境構築に挑戦した話 – yuqlidの日記

qiita.com

大変参考になりました。ありがとうございます。

この場をかりてお礼申し上げます。

 

 

ロボトレのマシンの設計の進捗

ロボットトレースという競技に出るためのマシンを設計中

基板の外形はまず設計してからじゃないと配線できないからね!

マイコンはstm32f405rgtを使う予定です。

マシンが形になっていくこのときが設計をしていて一番楽しい時間だ!

f:id:sora_siro:20171127214849p:plain