STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (4) スイッチを使ってみよう


STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (3)の続きです。
今度は、スイッチを使ってみましょう。

スイッチは、B1して登録されています。
まずは、「.ioc」ファイルをあけて確認してみましょう。

スイッチにつなるPC13がB1となっていることを確認できましたね。
では、これを押したら、LEDが点灯するプログラムを書いてみましょう。

もし、Aしたら、Bをする
そうではない時はCをする

もし、B1のスイッチを押したら、LEDを点灯する。
そうではないときは、LEDは消灯する。

これをC言語にします。
ifはもし
elseはそうではないとき

if(条件){
やること}else{
やること}

条件:B1のスイッチが押されたとき
B1の内容を読むのはreaPinと書きます。
if(HAL_GPIO_ReadPin とします。

B1ピンを設定します。
if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin))
さらに、これが押されたときを入れましょう。
今回の場合、0の場合が押されたときになります。
if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin)==0)
とします。
=0ではなく==0です。
=0だと動きません。

次に、やることを記述します。
今回は、LEDを点灯させます。
LEDは1にすると点灯します。
ここで、1や0って何?ということですが、1はHi,0はLoといい、基準電圧の上限下限にあることを指します。
STM32は3.3Vが基本なので、3.3VをHiとし、0VをLoとなります。
(正確には使うマイコンの仕様によって1.xV以下をLoと認識するようになっていたりします)
今回は、LEDにつながるピンを1つまり、3.3Vにすると、LEDに電気が流れてLEDが点きます。
これをするには、writePinで設定します。

PinStateには1を入れてあげることで3.3Vが出力されます。
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 1);
となります。
これで、B1が押されたらLEDが点灯する内容が記述できましたが、これではC言語として文法が成り立っていません。
試しにビルドしてみましょう。
エラーになります。

それでは、C言語のif文のフォーマットにして入力してみましょう
if(条件){
やること}else{
やること}

単純に{}で囲うだけです。

    /* USER CODE BEGIN 3 */
      if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin)==0){
      HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 1);
      }else{
          HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 0);
      }
      LED_State = HAL_GPIO_ReadPin(LD2_GPIO_Port, LD2_Pin);
      B1_State = HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);
  }
  /* USER CODE END 3 */

今回、else(そうではないときは)にLEDを消灯するプログラムを加えています。
そうではない時は、条件がないば場合はなくても良いです
では消してみましょう。

すると、ボタンを1度押すとLEDが光るが、再度押しても消えないと思います。
なぜでしょうか?

もし、B1のスイッチを押したら、LEDを点灯する。
そうではないときは、LEDは消灯する。
の消灯するが無いためです。

LEDが点灯していたら、消す、消灯していたら点灯すると記述すると面倒ですよね?
ここで、Lチカの時に入れたTogglePinを使います。
TogglePinとは反転させるという意味で、この点灯の場合は、消灯に、消灯の場合は、点灯にしてくれます

    /* USER CODE BEGIN 3 */
      if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin)==0){
      HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
      }
      LED_State = HAL_GPIO_ReadPin(LD2_GPIO_Port, LD2_Pin);
      B1_State = HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);
  }
  /* USER CODE END 3 */

ここまでで実は、しれっとLED_StateとB1_Stateとを入れています。
https://qiita.com/usashirou/items/e1cb59a508dac64b8a3c
でやったように、
int LED_State = 0;
int B1_State = 0;
を私は49行目辺りに追加しています。
ViewにもB1_Stateを追加しています。
これで動くはずですが、うごきましたか?

ここで問題が発生します。
ボタンを押してもLEDが消えないのです、またはつかないのです。
B1_Stateも変わらないです。
これは、チャタリングという現象によるものです。
チャタリングの解消には、いくつかの手法があるのですが、今回は、ここまではやりません。

(編注:なお、本来Nucleoのボードには抵抗とコンデンサが入っており、チャタリングは起きないはずなのですが、私はかなり顕著に起きてしまいました。
この辺については、どこかで触れるかもしれません。)