Project_OKI’s diary

エンジニアの勉強ブログ

STM32マイコン_15(レジスタ操作でLED点滅2)

​​​​

STM32:レジスタ操作でLED点滅

1.本日の内容

(1) STM32マイコン(nucleo f401RE)を使用して、LEDの点灯/消灯を行う。

 (2) 今回は、HALの関数を使わず、レジスタを操作し、LEDを点滅させる。

 (3) #defineを使用し、LED ON/OFF用の関数を作成する。

 前の記事:STM32マイコン_10(レジスタ操作でLED点滅) - Project_OKI’s diary

 

・目次

 

2.内容

​​(1) やる内容の詳細​

  ・STM32マイコン(nucleo f401RE)を使用して、LEDの点灯/消灯を行う。
    ・nucleof401についてる青ボタンを押した時
    ・プログラムを実行し、LEDを2秒ごとに点滅する。

  ・レジスタの操作でON/OFF出来ることを確認する。

  ・#defineでLED ON/OFFを制御する関数を作る。

(2) 使用部品​
個数 部品名 型番
1 USBケーブル USBミニBタイプ
1 mbed(マイコンボード) ​​ nucleo f401RE

​​​​

(3) STM32CubeMXの設定、プログラムを出力

  CubeMXの設定は下記記事の

 「(3)STM32CubeMXの設定、プログラムを出力」を参照

  →STM32マイコン_5(スイッチ入力とLED点灯、消灯) - Project_OKI’s diary


(4) AtricTrueStdioでプログラム作成

 (a) プログラムの書き込み
   ・トンカチマークをクリックして、ビルドする。
   ・エラーが出ないことを確認する。
   ・下記プログラムを記載する。

/* USER CODE BEGIN 3 */
LED1_GPIO_Port->ODR |= GPIO_ODR_OD5; //プルアップ
HAL_Delay(2000);
LED1_GPIO_Port->ODR &= ~GPIO_ODR_OD5; //プルダウン
HAL_Delay(2000);
/* USER CODE END 3 */
(5) プログラムの説明
 (a)LED1_GPIO_Port->ODR |= GPIO_ODR_OD5;
   ・LEDを点灯させる。
   ・リファレンスRM0368の8.4.6を参照。
   ・ODRがポートの設定となっている。
         ・A|B とは、 A = A|Bのことで、AとBのORを取っている。
    ・GPIO_ODR_OD5 = 0x00000020 = 0b0000000000100000となる。
   →stm32f401xe.hに記載。
    (サクラエディタなどGPIO_ODR_OD5をグレップ検索する。)
   ・GPIO_ODR_OD5のORを取ることで、5bit目のみHighにすることができる。
 
   ・ANDとORの考え方
    参考:C言語基礎知識21(演算子)の複合演算子を参照
   ・レジスタについて
 
 (b)LED1_GPIO_Port->ODR &= ~GPIO_ODR_OD5;
   ・LEDを消灯させる。
   ・これも(a)と同じ考え方。
   ・ ~GPIO_ODR_OD5(0b1111111111011111)のANDを取ることで、5bit目のみLowにする。
   →考え方はC言語基礎知識21(演算子)の複合演算子を参照
 
(6) AtricTrueStdioでプログラム作成(LED ON/OFF関数作成)
 ・Led1(ON)だと、PA5のLED1を点灯
 ・Led1(OFF)だと、PA5のLED1を消灯する関数を作成する。
/* Private typedef -----------------------------------------------------------*/
 /* USER CODE BEGIN PTD */
 ///ONOFF型作成(ON =1, OFF =0)
 typedef enum{OFF=0	///<OFF指定
 	      ,ON	///<ON指定
 }ONOFF;
 /* USER CODE END PTD */
 
 /* Private macro -----------------------------------------------------------*/
 /* USER CODE BEGIN PM */
 #define OutGPIOBit(port,pin,data)	(port->ODR=((port->ODR&~(pin))|((data==0) ? 0 : (pin))))
 //LED ON/OFF関数の作成
 #define Led1(dt) OutGPIOBit(LED1_GPIO_Port,LED1_Pin,dt)  //LED1:LEDのON/OFF
  /* USER CODE END PM */
 
   while (1)
   {
     /* USER CODE END WHILE */
 
     /* USER CODE BEGIN 3 */
 	  Led1(ON); //LED ON
 	  HAL_Delay(2000);  //2秒wait
 	  Led1(OFF); //LED OFF
 	  HAL_Delay(2000);  //2秒wait
   }
   /* USER CODE END 3 */
 
(7) プログラムの説明
 (a) typedef enum ・・・
  ・ONを1、OFFを0で使用できるようにする。
 
 
 (b) #define OutGPIOBit(port,pin,data) (port->ODR=*1|((data==0) ? 0 : (pin))))
  ・#define A B で BをAに置き換え。
 
  ・(data==0) ? 0 : (pin) :dataが0の時、0、dataが0以外の時pinを返す。
  ・port->ODR&~(pin)  :上記の通りport->ODRがpinの&を取る。
  ・dataが0の時:port ->ODR = port->ODR&~(pin)|0
  ・dataが1の時:port ->ODR = port->ODR&~(pin)|(pin)
  となる。
   →参考:
   これにより、指定したポートのON/OFFをすることができる。
  
 (c)  #define Led1(dt) OutGPIOBit(LED1_GPIO_Port,LED1_Pin,dt)
  ・上記(b)で定義したOutGPIOBitにLED1のportとpinを入れて、Led1関数として作成
  ・LED1の ON/OFF用の関数
  ・Led1(ON) でLED1を点灯、Led1(OFF)でLED1を消灯出来る。  
 
 

3.関連記事

組み込みC言語

*1:port->ODR&~(pin