へっぽこ元ロボコニスト

ロボコンに燃え尽きた自分が日々の出来事を書くだけのブログです twitter:@mozyanari_tech

MENU

2017/4/10


スポンサーリンク

研究室行ってきました

することがない・・・・・

なので,終始喋って終わりました

でも,明日は,教授の授業とアルバイト面接,明後日はB4対象の導入ゼミ,明々後日は,担当の先生とのミーティングと色々あるので楽しみです

 

なので,家に帰ってSTMで遊んでました

というのも,友達がPICをし始めてそれに触発されてやってみました

 

まずは環境作りから

yuqlid.hatenablog.com

この人のを参考にして,インストールしてみました

やべえ,めっちゃ簡単や!

前,ネットを参考に一度作ったんですが,何個もプログラムを入れないといけないので挫折してしまったんですが,これは一個だけで済みました

 

自分のNucleoボードは

akizukidenshi.com

STM32F401を使っています

 

そして,ただ光るだけのサンプルをいじりました

目標は,ボード上にあるUSERボタンを押すと,LED2が光るようになることです

 

まず,起動したら,プロジェクトを作る

[File]→[New]→[C++ Project]

①Ac6 STM32 MCU GCCを選択して

f:id:masanari7430:20170410231945p:plain

 

②ここはそのまま

f:id:masanari7430:20170410232040p:plain

 

③自分の今使っているSTMを選択して(今回はF4-nucleo)

Nextを押す,Finishはまだ!!!

f:id:masanari7430:20170410232150p:plain

 

④Cube HALを選択

最初はHALがないので下の[Download taget firmware]でダウンロード

そしてFinish

f:id:masanari7430:20170410232318p:plain

このHALのおかげでRXの時していたレジスタたたきが無くなるので最高です

 

で,[src]の中のmainを書き換えます

/**
  ******************************************************************************
  * @file main.c
  * @author Ac6
  * @version V1.0
  * @date 01-December-2013
  * @brief Default main function.
  ******************************************************************************
  */
   
   
  #include "stm32f4xx.h"
  #include "stm32f4xx_nucleo.h"
  #include "stm32f4xx_hal_uart.h"
   
   
  int main(void)
  {
  int PB_state = 0;
   
  //HALライブラリを使うための初期化関数
  HAL_Init();
  //ボード上のLED2を有効化
  BSP_LED_Init(LED2);
  //ボード上のボタンを有効化
  BSP_PB_Init(BUTTON_KEY,BUTTON_MODE_GPIO);
   
   
  while(1){
  PB_state = BSP_PB_GetState(BUTTON_KEY);
  if(PB_state == 0){
  BSP_LED_On(LED2);
  }else{
  BSP_LED_Off(LED2);
  }
  }

 

このプログラムは,最初のサンプルを参考にライブラリを開けながら,手探りでやってみたものです

大体,コメントアウトしてるのが説明でわかる気がします

※uartのヘッダはいりません,なぜか入ってしまっています

 

で,その次に汎用的な書き方でやってみたのが以下の通りです

 

 

 

/**
  ******************************************************************************
  * @file main.c
  * @author Ac6
  * @version V1.0
  * @date 01-December-2013
  * @brief Default main function.
  ******************************************************************************
  */
   
   
  #include <stm32f401xe.h>
  #include <stm32f4xx_hal.h>
  #include <stm32f4xx_hal_gpio.h>
  #include <stm32f4xx_hal_rcc.h>
   
   
  int main(void)
  {
  //システムの初期化
  SystemInit();
  //HALライブラリを使うための初期化関数
  HAL_Init();
   
  //クロック供給
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
   
  //GPIO.Cを初期化
  //構造体生成
  GPIO_InitTypeDef GPIO_Assign_C;
   
  //C_PIN13の設定
  GPIO_Assign_C.Pin = GPIO_PIN_13;
  GPIO_Assign_C.Mode = GPIO_MODE_INPUT;
  GPIO_Assign_C.Pull = GPIO_PULLUP;
  GPIO_Assign_C.Speed = GPIO_SPEED_FREQ_LOW;
   
  //PIN13の設定を書き込み
  HAL_GPIO_Init(GPIOC,&GPIO_Assign_C);
   
  //GPIO.Aを初期化
  //構造体を初期化
  GPIO_InitTypeDef GPIO_Assign_A;
   
  //A_PIN5の設定
  GPIO_Assign_A.Pin = GPIO_PIN_5;
  GPIO_Assign_A.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_Assign_A.Speed = GPIO_SPEED_FREQ_LOW;
   
  //PIN5の設定を書き込み
  HAL_GPIO_Init(GPIOA,&GPIO_Assign_A);
   
  while(1){
  int push_state = 0;
   
  push_state = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13);
   
  if(push_state == 0){
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
  }else{
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
  }
   
  }
   
   
  }

 

くそ長いです

まず,汎用のIOポートを動かすには設定が要るのですがその設定の前にクロックを流さないといけません

この供給はIOのみならずTIMや,UART,SPIなど何かピンを動かそうとすると必ずいるものです

//クロック供給
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

 

また,この関数を実行するには

#include <stm32f4xx_hal_rcc.h>

このヘッダが要るので注意です

 

その次に,IOポートの設定をするんですが

#include <stm32f4xx_hal_gpio.h>

の中に変数の構造体が定義されているのでそれを使います

//構造体生成
  GPIO_InitTypeDef GPIO_Assign_C;

 

こんな感じで,好きな名前を付けた構造体を作ります

次は,その構造体にデータを入れるんですが,1とか数字を入れるのではなく,ヘッダで定義されている文字でデータを入れます

//C_PIN13の設定
  GPIO_Assign_C.Pin = GPIO_PIN_13;
  GPIO_Assign_C.Mode = GPIO_MODE_INPUT;
  GPIO_Assign_C.Pull = GPIO_PULLUP;
  GPIO_Assign_C.Speed = GPIO_SPEED_FREQ_LOW;

 

今回は

  • USERスイッチがPC13につながっている
  • 入力ピンにする
  • 内臓プルアップを付ける
  • ピンの反応速度を遅めにする

にしました

もちろん内臓プルダウン,反応速度を倍以上にすることも出来ます

 

最後にこの設定を書き込みます

//PIN13の設定を書き込み
  HAL_GPIO_Init(GPIOC,&GPIO_Assign_C);

 

第一引数はGPIOx(x=A,B,C・・・)

第二引数は設定した構造体のアドレスを入れます

 

もし,PA1-3までをまとめて同じ設定にしたいなら

GPIO_Assign_A.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;

にすればいいです

この理由はGPIO_PINの定義をみてその値を二進数に変換すればわかると思います

うまく被らないようになっているからです

この考えはPS3のコントローラ開発の時に同じことをしていたので少し感動しました

 

また,A1は入力A2は出力ならA1を設定した後,構造体の中を書き換えて,再設定すればいいだけです

 

出力も大体同じで設定出来ます

 

で設定したIOの入出力はまたまたHALのヘッダでとれます

読み取りは

push_state = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13);

Readで

第一引数はどの種類か?

第二引数は何番のピンか?

です

 

出力は

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);

Writeで

第一引数はどの種類か?

第二引数は何番のピンか?

第三引数はsetでHigh,resetでLow

です

 

こんな感じで出来ました.

このプログラムは全部gitに上げています

github.com

またこれからも上げていきたいと思います

 

これが出来たのは,少し違う環境でSTMをやっていた後輩がいてその子からプログラムを貰ったのと,

積んでいた参考書

shop.cqpub.co.jp

のおかげです

 

その後輩は今NHKを頑張っているので,本選に行ってくれたらいいなぁ