Project_OKI’s diary

エンジニアの勉強ブログ

STM32マイコン35(HAL_I2Cの関数について)

STM32マイコン35(HAL_I2C関数について)

1.本日の内容

 (1) HAL_I2Cに関連する関数の使い方について理解する。

 

  使用マイコン

 

・目次

 

2.内容

(1) HAL_I2C_Master_Transmit関数とは

 ・通常のI2C通信のデータを送信する為の関数。

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 

(2) HAL_I2C_Master_Transmit関数の使い方
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 引数について:
  ・I2C_HandleTypeDef *hi2c :I2Cバスのハンドルを指定
  ・uint16_t DevAddress   :通信先のスレーブのアドレスを指定(7ビット)   
     ※通常、スレーブデバイスのアドレスをここに指定。
      8ビットアドレスの最上位ビットは読み書きを示すビットで、
      この関数内で自動的に設定されます。
  ・uint8_t *pData       :送信するデータのポインタを指定。
  ・uint16_t Size          :送信するデータのサイズをバイト単位で指定
  ・uint32_t Timeout      :タイムアウト時間をミリ秒単位で指定  
 送信例:
 uint8_t data_to_send[2] = {0x12, 0x34}; // 送信するデータ
 HAL_I2C_Master_Transmit(&hi2c1,slaveAddress<<1,data_to_send,2,HAL_MAX_DELAY);

 ※slaveAddressは、通常7ビットで、R/W指定をするために、

  スレーブアドレスを1ビット左にずらし、0を入れる。

 参考:STM32マイコン25(LCD:ACM1602のI2C制御方法) - Project_OKI’s diary

 

 

※詳細は、ユーザーマニュアルを参照

 →UM1725 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

(3) HAL_I2C_Master_Reveive関数とは

 ・通常の外部のデバイスからI2C通信のデータを受信する為の関数。

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 
(4) HAL_I2C_Master_Reveive関数の使い方
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 ・hi2c: I2Cハンドル構造体へのポインタ。
  これは、I2Cインターフェースを管理するために使用されます。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・pData: 受信したデータを格納するためのバッファへのポインタ。
 ・Size: 受信するデータのバイト数。
 ・Timeout: 通信のタイムアウト時間(ミリ秒)。
 使用例:
 uint8_t received_data[2]; // 受信したデータを格納するバッファ
 HAL_I2C_Master_Receive(&hi2c1,(slaveAddress<<1)|1,received_data,2, HAL_MAX_DELAY);

 ※slaveAddressは、通常7ビットで、R/W指定をするために、

  スレーブアドレスを1ビット左にずらし、1を入れる。

  (8ビットの場合は、いらない)

 
(5) HAL_I2C_Master_Transmit_IT関数とは
 ・STM32マイコン向けに提供されるHALライブラリで用意されている。
 ・I2C通信を使用してマスターデバイスからスレーブデバイスに対して非同期のデータ受信を行うためのもの。
 ・関数呼び出し後に送信が完了するまで待機せず、送信がバックグラウンドで行われる。
 ・送信完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
(6) HAL_I2C_Master_Transmit_IT関数の使い方
HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
 ・I2C_HandleTypeDef *hi2c :I2Cバスのハンドルを指定
 ・uint16_t DevAddress   :通信先のスレーブのアドレスを指定 
 ・uint8_t *pData       :送信するデータのポインタを指定。
 ・uint16_t Size          :送信するデータのサイズをバイト単位で指定
 
 使用例:
 uint8_t sendData[2]; // 送信するデータのバッファ
 sendData[0] = 0xAA;
 sendData[1] = 0xBB;
 
 HAL_I2C_Master_Transmit_IT(&hi2c1, slaveAddress<<1,sendData,sizeof(sendData));
 
 
(7) HAL_I2C_Master_Reveive_IT関数とは

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 ・I2C通信を使用してマスターデバイスからスレーブデバイスに対して非同期のデータ受信を行うためのもの。
 ・非同期モードでデータ受信を行う。
 ・関数呼び出し後に受信が完了するまで待機せず、受信がバックグラウンドで行われる。
 ・受信完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
(8) HAL_I2C_Master_Reveive_IT関数の使い方
HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
 ・hi2c: I2Cハンドル構造体へのポインタ。
  これは、I2Cインターフェースを管理するために使用されます。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・pData: 受信したデータを格納するためのバッファへのポインタ。
 ・Size: 受信するデータのバイト数。

 

 使用例:

 uint8_t receiveData[2]; // 受信データを格納するバッファ
 HAL_I2C_Master_Receive_IT(&hi2c1, (slaveAddress<<1)|1, receiveData, sizeof(receiveData));

 

 

(9) HAL_I2C_Master_Seq_Transmit_IT関数とは

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 ・I2C通信を使用してマスターデバイスからスレーブデバイスに対してシーケンシャルな非同期のデータ送信を行うためのもの。
 ※シーケンシャル送信とは、複数のデータバイトを連続して送信する操作のこと。
  ・関数呼び出し後に送信が完了するまで待機せず、送信がバックグラウンドで行われる。
 ・送信完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
(10) HAL_I2C_Master_Seq_Transmit_IT関数の使い方
HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Request, uint8_t *pData, uint16_t Size);
 ・hi2c: I2Cハンドル構造体へのポインタ。
  これは、I2Cインターフェースを管理するために使用されます。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・pData: 受信したデータを格納するためのバッファへのポインタ。
 ・Size: 受信するデータのバイト数。
 
 使用例:
 uint8_t sendData[2]; // 送信するデータのバッファ
 sendData[0] = 0xAA;
 sendData[1] = 0xBB;
 
 HAL_I2C_Master_Seq_Transmit_IT(&hi2c1, slaveAddress<<1,I2C_FIRST_FRAME, sendData, sizeof(sendData));
 
 
(11) HAL_I2C_Master_Seq_Reveive_IT関数とは

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 ・I2C通信を使用してマスターデバイスからスレーブデバイスに対してシーケンシャルな非同期のデータ送信を行うためのもの。
 ※シーケンシャル送信とは、複数のデータバイトを連続して送信する操作のこと。
  ・関数呼び出し後に受信が完了するまで待機せず、受信がバックグラウンドで行われる。
 ・受信完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
(12) HAL_I2C_Master_Seq_Reveive_IT関数の使い方
HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Request, uint8_t *pData, uint16_t Size);
 ・hi2c: I2Cハンドル構造体へのポインタ。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・Request: 通信の種類を示すフラグや要求を指定するパラメータ。
      一般的には0を指定することで、通常の受信操作を行う。
 ・pData:受信データを格納するバッファへのポインタ。
      受信したデータはこのバッファに格納される。
 ・Size: 受信するデータのバイト数。

 

 使用例:

 uint8_t receiveData[2]; // 受信データを格納するバッファ
 
 HAL_I2C_Master_Seq_Receive_IT(&hi2c1,(slaveAddress<<1)|1, I2C_FIRST_FRAME, receiveData, sizeof(receiveData));

 

 

(13) HAL_I2C_Mem_Write関数とは

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 ・指定されたメモリアドレスに対してデータを書き込むための非同期関数。

 ・I2C通信を使用して特定のメモリアドレスにデータを書き込むために使用する。

 ・デバイスに対してデータを書き込むことができる。
 ・関数呼び出し後に書き込みが完了するまで待機せず、書き込みがバックグラウンドで行われる。
 ・書き込み完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
 
(14) HAL_I2C_Mem_Write関数の使い方
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 ・hi2c: I2Cハンドル構造体へのポインタ。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・MemAddress:書き込むメモリアドレス。
 ・MemAddSize:メモリアドレスのサイズ(バイト単位)。
         通常、1又は2バイトのアドレスが使用される。
 ・pData:書き込むデータが格納されたバッファへのポインタ。
 ・Size: 受信するデータのバイト数。
 ・Timeout: 通信のタイムアウト時間(ミリ秒)

 

 使用例:

 uint8_t sendData[2]; // 書き込むデータを格納するバッファ
 sendData[0] = 0xAA;
 sendData[1] = 0xBB;
 
 HAL_I2C_Mem_Write(&hi2c1, slaveAddress<<1, memAddress, I2C_MEMADD_SIZE_8BIT, sendData, sizeof(sendData), HAL_MAX_DELAY);

この例では、

・I2Cハンドル hi2c1 を使用

・slaveAddress のスレーブデバイスに通信

・memAddress で指定されたメモリアドレスに

・sendData バッファ内のデータを書き込み。

 

これは例えば、温度センサ(MLX90614ESF-DCH)など、メモリアドレスを指定して使用するI2Cデバイスを使用する際に、この関数を使用する。

 

 

(15) HAL_I2C_Mem_Read関数とは

 ・STM32マイコン向けに提供されるHALライブラリで用意されている。

 ・指定されたメモリアドレスのデータを読み取るための非同期関数。

 ・I2C通信を使用して特定のメモリアドレスのデータを読み込むために使用する。

 ・関数呼び出し後に読み取りが完了するまで待機せず、読み取りがバックグラウンドで行われる。
 ・読み取り完了時に割り込みが発生し、コールバック関数が呼び出されることがある。
 
(16) HAL_I2C_Mem_Read関数の使い方
HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
 ・hi2c: I2Cハンドル構造体へのポインタ。
 ・DevAddress: 通信相手のI2Cデバイスのアドレス。
 ・MemAddress:読み取るメモリアドレス。
 ・MemAddSize:メモリアドレスのサイズ(バイト単位)。
         通常、1又は2バイトのアドレスが使用される。
 ・pData:読み取ったデータを格納するバッファへのポインタ。
 ・Size: 読み取るデータのバイト数。
 ・Timeout: 通信のタイムアウト時間(ミリ秒)

 

 使用例:

uint8_t receiveData[2]; // 読み取ったデータを格納するバッファ
 
HAL_I2C_Mem_Read(&hi2c1, (slaveAddress<<1)|1, memAddress, I2C_MEMADD_SIZE_8BIT, receiveData, sizeof(receiveData), HAL_MAX_DELAY);

 

(17) CubeMXの設定

 ・File→New ProjectでSTM32F401を選択し、新しいプロジェクトを作成する。

  (a) Pin設定画面の下記ピンを設定する。

    ・PB9をI2C1_SDA   (LCD制御用 I2C_SDA)

    ・PB8をI2C1_SCL          (LCD制御用 I2C_SCL)

 

  (b) それぞれのピンの名前を右クリック、Enter User Labelで

    画像の名前に変更する。(変更しなくてもよい。)

 

 

  (b) ConnectivityのI2C1を選択し、LCDの仕様に合わせて、下記設定を行う。

Mater Feature
  I2C Speed Mode Standard Mode
  I2C Clock Speed 100000
Slave Features
      Clock No Stretch Mode Disable
 Primary Address Length selection 7-bit
 Dual Address Acknowledged Disable
 Primary slave address 0
 Generala Call address detection Disabled

 

   下記に簡単に、それぞれの設定の意味を示す。

設定項目 説明
Master Features I2C通信のマスター側の設定項目
I2C Speed Mode

I2Cのスピードモード設定。

標準モード、Fastモードが選択可能

※今回はそこまで速度が必要ないので標準。

I2C Clock Speed

I2Cのクロック速度設定。Hz単位で設定可能

※データシートより100kHzに設定

Slave Features I2C通信のスレーブ側の設定項目
Clock No Stretch Mode スレーブデバイスによるクロックのストレッチを禁止するか選択。
Primary Address Length selection

プライマリアドレスのビット数を7ビット

または10ビットで設定可能。

Dual Address Acknowledged スレーブデバイスが2つのアドレスを認識するかどうか選択可能。
Primary slave address スレーブデバイスのプライマリアドレスを設定可能。
General Call address detection ジェネラルコールアドレスの受信を有効にするか選択可能。

※仕様上、LCDのI2Cクロックスピードは100kHzまで可能。

線の長さなどによっては、そのスピードだと通信できない可能性がある。

その場合は、70kHzなどクロックスピードを落とすと通信出来るようになる。

 

 

 

  (c)NVICを設定 (割り込みを使用する場合)

 

  (d) 割り込みの優先順位を下げる。

 

  (e) プロジェクト名を付け、Toolchain/IEDをTrueSTUDIOに設定

 
 

3.関連記事

関連記事一覧:
 
組み込みC言語
 
STM32のデータシートなど:

 

STM32マイコン34(bss,text,dataセクションについて)

STM32(bss,text,dataセクション)

1.本日の内容

 (1) セクション及び、そのセクションの内容について理解する。

 

  使用マイコン

 

・目次

 

2.内容

(1) セクションとは

 ・プログラムはメモリに配置されて実行される。

 ・メモリ上にはプログラム内の「機械語」や「変数」「定数」など、

  各種用途ごとに分かれて配置される。

 ・その単位のことをセクションという。

メモリについては下記を参照

 →STM32マイコン33(CubeIDEの使い方:空きメモリ容量の確認) 

 

(2) セクションの種類と意味

 ※基本的なセクションの種類と意味

 (a) bssセクション(block started by symbol):

  →static修飾された変数(静的変数)やグローバル変数の中で、

   初期化されてない変数や、

   0で初期化された変数が配置される。

   (初期値を持たない静的変数など)

  ※static修飾子については下記記事を参照

 

 (b) dataセクション:

  →初期化された静的変数やグローバル変数を格納する領域

  →明示的に初期化された値を持つ。

  →プログラムがロードされるときにメモリに読み込まれ、

   実行中に変更される可能性がある。

 

 (c) textセクション:

  →プログラム(コード)の保存領域

  →プログラムの命令や関数のバイトコードが含まれる。

  →通常、読み取り専用のメモリ領域であり、実行時に変更されることはない。

 

 (d) heapセクション:

  →動的に割り当てられるメモリ領域

  →プログラム実行中にmalloc関数などを使用して、メモリの割り当てを行う。

  →ここに割り当てられた場合、明示的な解放命令(free関数など)がない限り、

   プログラム終了まで、メモリを保持する。

 

 (e) stackセクション:

  →関数呼び出しやローカル変数など、

   プログラムの実行中に自動的に割り当てられるメモリ領域。

  →プログラムが関数を呼び出すたびにスタックフレームが作成され、

   関数のパラメータやローカル変数がスタックに格納される。

   関数が終了すると、スタックフレームが解放され、メモリは再利用可能となる。

 

  ※スタックフレーム:

   関数が呼び出された時、その関数の実行に必要な情報を保持する為に

   スタックメモリ上に割り当てられる領域。

   関数のローカル変数、戻りアドレス、関数呼び出し時に保存される一時的な情報を格納する。

 

これ以外にも、リードオンリーデータセクション、コンスタントデータセクションなど、様々なセクションが存在する。

参考:STM32CubeIDEでメモリーの使用状況を確認する - moon's STM32づくし

 

(3) セクションをプログラムで確認
#include <stdio.h>

int bss_sec1;       // bssセクションに配置
int data_sec1 = 10; // dataセクションに配置 

int main(void){
    static int bss_sec2;        // bssセクションに配置
    static int data_sec2 = 20;  // dataセクションに配置 
    int stack_sec1;             // stackセクションに配置
    char *set;
    set = (char*)malloc(100);   // heapセクションに配置
}

プログラム:https://paiza.io/projects/l0SArvdE5IpuuImyDAmWBA

 

CubeIDEなどの場合、これらの容量がビルド時に確認できる。

これによって、ビルド時のそれぞれの容量が確認できる。

空きメモリの確認方法については下記参照

→STM32マイコン33(CubeIDEの使い方:空きメモリ容量の確認)

 

3.関連記事

関連記事一覧:
 
組み込みC言語

STM32マイコン33(CubeIDEの使い方:空きメモリ容量の確認)

STM32(CubeIDE:空きメモリ容量の確認)

1.本日の内容

 (1) CubeIDEで空きメモリ容量(RAMとFLASH)の確認を行う。

  (どの程度使っているかの確認)

 

  使用マイコン

 

・目次

 

2.内容

(1) メモリとは

 ・メモリは大きくROM(Read Only Memory)とRAM(Random Access Memory)に分類される。

 ・ROMの特徴

  (a) 読み出し専用のメモリ

  (b) 電源の状態に関係なく、消えることはない。(非発揮性)

 

 ・Flashメモリ

  (a) ROMの一つ、その中でもブロック単位でデータを消去して書き換えることが出来る。

  (b) データの永続的な保存が可能な為、ここに、プログラムコードやデータの保存に使用される。


 ・RAMの特徴

  (a) ランダムに読み書きが自由に出来る。

  (b) 電源を切ると、消去される。(発揮性)

 

メモリの詳細に関しては下記書籍など、基本情報技術者の知識を参照。


 

 

 

(2) STM32マイコンのメモリ

 ・STM32マイコンには、RAMとFLASHがあり、下記の様にマイコンによって異なる。

 ・プログラムの規模によって必要なFLASHやRAMの容量を決定する。

 ・Nucleof401REの場合は、STM32F401RET6が付いている為、

  FLASHは512KB、RAMは96KBある。

  規模が大きくなる場合、この値を気にする必要が出る。

STM32サイト:STM32F4 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

(3) 実際に作成したプログラムの容量、空き容量を確認する。

 通常プログラムをビルドすると、下記のように表示される。

 

 ・このtext、data、bssというのが現在使用しているメモリ容量になる。

  (実際には、下記以外の項目がある)

  Flash側:

   (a) text:プログラム(コード)の保存領域

  RAM側:

   (b) data:初期値がを持つ変数の初期値を格納している領域

   (c) bss:初期値を持たない(0で初期化される)変数の領域

 

(4) RAMとFlashの表示設定

 上記内容だと、実際にRAMとFlashがどの程度使われているのか分かりにくい。 

 CubeIDEのリンカの設定を変更し、RAMとFlashの使用容量を表示する。

 

 (a) 確認するプロジェクトの上で右クリック

 (b) プロパティをクリックして開く

 (c) C/C++ BuilderのSettingタブを開く。

 (d) Tool Settingsを選択し、MUC GCC LinkerのCommand欄を選択する。

 (e) Command欄には、gccと記載されている。

 (f) gccの後ろに、-Wl,--print-memory-usageを入力する。

    (gcc -Wl,--print-memory-usage とする)

 (g) 適用を行い、再度ビルドする。

 


 (h) ビルドすると、下記のような形で、

  ・RAMとFlashの使用量(Used Size)

  ・RAMとFlashのメモリ容量(Region Size)

  ・使用率(%age Used) 

  が表示されるようになる。

 
 

3.関連記事

関連記事一覧:
 
組み込みC言語

 

 

STM32マイコン32(リスタート時の原因確認)

STM32 (リスタート時の原因確認)

1.本日の内容

 (1) CubeIDEでリスタート処理が発生した時の原因を取得する方法について記載する。

  主に、下記リスタートのフラグを確認し、原因の特定が出来る。

 

  下記は、STM32F103xxの場合。

  ・PINRSTF:PINリセットフラグ

  ・PORRSTF:POR/PDRリセットフラグ

  ・SFTRSTF:ソフトウェアリセットフラグ

  ・IWDGRSTF:独立型ウォッチドッグリセットフラグ

  ・WWDGRSTF:ウィンドウ型ウォッチドッグリセットフラグ

  ・LPWRRSTF:低電力リセットフラグ

 

  下記は、STM32F401xxの場合  

  ・PINRSTF:PINリセットフラグ

  ・PORRSTF:POR/PDRリセットフラグ

  ・SFTRSTF:ソフトウェアリセットフラグ

  ・IWDGRSTF:独立型ウォッチドッグリセットフラグ

  ・WWDGRSTF:ウィンドウ型ウォッチドッグリセットフラグ

  ・LPWRRSTF:低電力リセットフラグ

  ・BORRSTF:BORリセットフラグ

 

  今回は、IWDGを動作させ、実際にIWDGによってリセットしたかどうか値を取得し、確認する。

  使用マイコン

 

・目次

 

2.内容

(1) リセット原因の確認方法

 ・上記、リスタートフラグは、制御/ステータスレジスタ(RCC_CSR)の値で確認できる。

 ・制御/ステータスレジスタについては使用するマイコンによって変わるので、データシートを参照する。

 参照:リファレンス マニュアル | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

 ・データシートを参照すると下記のように記載している。

 ※RM0368データシートより抜粋

(2) リセット原因の意味

リセットフラグ 

内容 詳細
PINRSTF PINリセットフラグ

NRSTピンに外部からリセットトリガーが供給されることによるリセット

PORRSTF

POR/PDR

リセットフラグ

電源オンリセット(Power-On Reset)または

電源ダウンリセット(Power-Down Reset)の

発生を示すフラグ

SFTRSTF

ソフトウェア

リセットフラグ

プログラムの実行中にソフトウェアから発行されるリセット命令によるリセット
IWDGRSTF

独立型ウォッチドッグ

リセットフラグ

独立型ウォッチドッグによるリセット
WWDGRSTF

ウィンドウ型ウォッチドッグ     

リセットフラグ

ウィンドウ型ウォッチドッグによるリセット
LPWRRSTF 低電力リセットフラグ バッテリの電力が復旧し、マイコントを自動的に再起動する機能による低消費電力リセット
BORRSTF BORリセットフラグ 電源供給が一時的に低下したり不安定になったりした場合に発生するリセット

詳細は下記記事を参照

 ・組み込み基礎知識(PINRSTF/PORRSTF/SFTRSTF/IWDGRSTFなどの意味)

 

(3) リセット原因の取得とクリア

プログラムで、RCCのステータスレジスタの取得と、リセットを行う。

#include "stm32f10x.h"   //(stm32f103の場合)
 
//リスタート原因取得関数
void GetSysResetSts()
{
	uint32_t ulSts;                          // リセットステータス
	
	// クリアステータスの取得
	ulSts = RCC->CSR & (RCC_CSR_PINRSTF | RCC_CSR_PORRSTF |
                        RCC_CSR_SFTRSTF | RCC_CSR_IWDGRSTF |
                        RCC_CSR_WWDGRSTF | RCC_CSR_LPWRRSTF);
 
     // リセットステータスの取得
     if (ulSts & RCC_CSR_SFTRSTF){
     	// ソフトウェアリセット時処理
     }

     if(ulSts & RCC_CSR_IWDGRSTF){
     	// IWDGリセット時処理
     }
     
     if(ulSts & RCC_CSR_WWDGRSTF){
          // WWDGリセット時処理
     }
     
     if(ulSts & RCC_CSR_PORRSTF){
     	// POR/PDRリセット時処理
     }

     if(ulSts & RCC_CSR_PINRSTF){
	//ピンリセット時処理 
} if(ulSts & RCC_CSR_LPWRRSTF){ // 低電力リセット時処理 } // リセットステータスのクリア RCC->CSR |= RCC_CSR_RMVF; }

 

 ・RCC_CSR_SFTRSTF/RCC_CSR_IWDGRSTF/RCC_CSR_WWDGRSTF/RCC_CSR_PORRSTF

 RCC_CSR_PINRSTF/RCC_CSR_LPWRRSTF/RCC_CSR_RMVF

 これらは、stm32f401xe.hに定義される。

 グレップで検索を行うと、確認できる。

 ・RCC_CSR_RMVFのフラグを立てることにより、リセットステータスをクリアできる。

 

(4) STM32F401REで確認

 実際に、上記プログラムの動作をSTM32F401REを使用して確認する。

 今回は、IWDGを有効にして、IWDGでリセットされた場合、

 LEDを消灯させる。

 IWDGのCubeMXの設定については、下記ブログを参照

 →STM32マイコン23(WDTでプログラム暴走時のリスタート処理) - Project_OKI’s diary

 また、PA 5をGPIO出力のHIGHの設定にする。

 

 

 ・プログラムの作成

/* USER CODE BEGIN PFP */
void GetSysResetSts();
/* USER CODE END PFP */
 /* USER CODE BEGIN 2 */
  GetSysResetSts();
 /* USER CODE END 2 */
/* USER CODE BEGIN 4 */
//リスタート原因取得関数
void GetSysResetSts()
{
	uint32_t ulSts;                        ///< リセットステータス

	/// クリアステータスの取得
	ulSts = RCC->CSR & (RCC_CSR_PINRSTF | RCC_CSR_PORRSTF |
                        RCC_CSR_SFTRSTF | RCC_CSR_IWDGRSTF |
                        RCC_CSR_WWDGRSTF | RCC_CSR_LPWRRSTF);

     // リセットステータスの取得
     if (ulSts & RCC_CSR_SFTRSTF){
     	// ソフトウェアリセット時処理
     }

     if(ulSts & RCC_CSR_IWDGRSTF){
     	// IWDGリセット時処理 (LEDを消灯)
    	 HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
     }

     if(ulSts & RCC_CSR_WWDGRSTF){
          // WWDGリセット時処理
     }

     if(ulSts & RCC_CSR_PORRSTF){
     	// POR/PDRリセット時処理
     }

     if(ulSts & RCC_CSR_PINRSTF){
	//ピンリセット時処理
     }
     if(ulSts & RCC_CSR_LPWRRSTF){
	// 低電力リセット時処理
     }

     // リセットステータスのクリア
     RCC->CSR |= RCC_CSR_RMVF;
}
/* USER CODE END 4 */

 

これを動作させると、最初の2秒は点灯するが、

それ以降は、一瞬LEDが付くが、LEDがすぐ消灯するようになる。

また、ブレークを行い、CSRレジスタを確認すると以下のようになる。

(IWDGを使っているからか、不安定だった)

 

ここでは、IWDGのみ確認したが、以上の方法でリセットが発生した時の確認処理を追加できる。

 
 

3.関連記事

関連記事一覧:
 
組み込みC言語

STM32に関する資料まとめ

STM32に関する資料まとめ

自分がよく確認するドキュメント一覧です。

 

目次

STM32F4関連

・STM32F4リファレンス検索

 →リファレンス マニュアル | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・STM32F4ユーザーマニュアル検索

 →ユーザ マニュアル | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・STM32F4ドキュメント

 →STM32F401 - PDF Documentation

 

・Description of STM32F4 HAL and LL drivers

 →UM1725 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・STM32F401xB/C and STM32F401xD/E advanced ARM®-based 32-bit MCUs

 →RM0368 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

 

STM32F1関連

・STM32F1ドキュメント

 →STM32F1シリーズ - PDF Documentation

・Description of STM32F1xx HAL drivers

 →UM1850 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・STM32F103VETドキュメント

 →STM32F103VET6 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

RM0008(リファレンスマニュアル)

 

mbed(STM32F401RE関連)

・ピン配置、基本性能

 →NUCLEO-F401RE | Mbed

・mbedボードハードウェアユーザーマニュアル

 →UM1724 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

CubeIDE関連

・CubeIDEユーザーガイド

 →UM2609 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・TrueStdioからCubeIDEへの移行ガイド

 →UM2578 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

・CubeIDEクイックスタートマニュアル

 →UM2553 | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

 

 

組み込み基礎知識(PINRSTF/PORRSTF/SFTRSTF/IWDGRSTFなどの意味)

組み込み基礎知識(PINRSTF/PORRSTF/SFTRSTF/IWDGRSTFなどの意味)

1.目的

  • 下記言葉の意味について簡単に記載する。

  ・PINRSTF:PINリセットフラグ

  ・PORRSTF:POR/PDRリセットフラグ

  ・SFTRSTF:ソフトウェアリセットフラグ

  ・IWDGRSTF:独立型ウォッチドッグリセットフラグ

  ・WWDGRSTF:ウィンドウ型ウォッチドッグリセットフラグ

  ・LPWRRSTF:低電力リセットフラグ

  ・BORRSTF:BORリセットフラグ

 

目次

2. PINRSTFフラグとは

  PINRSTFフラグは、NRSTピンのPINリセットが発生したことを示す。

  NRSTによるリセットが発生すると、このフラグがセット(1)になる。

  

  nucleof401reの場合、黒いボタンがリセットボタンになっている。

 

 

3. PORRSTFフラグとは

  PORRSTF(Power-On/Power-Down Reset Flag)は、

  マイコンの電源オンリセット(Power-On Reset)または

  電源ダウンリセット(Power-Down Reset)の発生を示すフラグ。

 

  電源を初めて供給されたり、電源が一時的に断たれたりした場合、

  電源オンリセットまたは電源ダウンリセットが発生する。

  このリセットは、回路が正常な動作状態に戻るために実行される初期化プロセス。


  PORRSTFフラグは、

  リセットが発生すると、このフラグがセット(1)される。

  フラグがセットされると、ソフトウェアからPORRSTFフラグを読み取ることで、

  直前のリセットが電源オンリセットまたは電源ダウンリセットであることを判断することができる。

  

4. SFTRSTFフラグとは

  ソフトウェアリセットにより、リセットしたことを示すフラグ。

  マイコンの一連の初期化処理を実行して、自身をリセットし、再起動する。


  ソフトウェアリセットは、

  ・リセットが発生すると、このフラグがセット(1)される。

  ・プログラムのエラーハンドリングや特定の条件に対する対応
  ・システムの再起動などの目的で使用される。(フォルトエラー時など)

 

  ソフトウェアリセット関数

 #include "stm32f1xx.h"
 
 NVIC_SystemReset();

 

5. IWDGRSTFフラグとは

  ・IWGD(独立型ウォッチドッグ)によって、リセットが発生した時、

   セットされるフラグ。

  ・リセットが発生すると、このフラグがセット(1)される。

 

6. WWDGRSTFフラグとは

  ・WWGD(ウィンドウ型ウォッチドッグ)によってリセットが発生した時、

   セットされるフラグ。

  ・リセットが発生すると、このフラグがセット(1)される。

   IWGD及びWWDGについては、下記記事を参照

   参考:STM32マイコン23(WDTでプログラム暴走時のリスタート処理) - Project_OKI’s diary

 

6. LPWRRSTFフラグとは

  バッテリの電力が復旧した場合にマイコンを自動的に再起動する機能が低消費電力リセット。

  つまり、低消費電力モードから通常の動作モードに戻る際に発生する。

  このリセットが発生すると、このフラグがセット(1)される。

  

7. BORRSTFフラグとは

  ・電源供給が一時的に低下したり不安定になったりした場合に発生する。

  ・電源電圧が(パワーダウンするほどでもないが)ちょっと下がったときにリセットをかける。

  ・この機能はデフォルトではOFFになっており、

   オプションバイトの設定で、有効にし、3段階の閾値電圧で設定する。

  参考:STM32のブラウンアウトリセット - 滴了庵日録

 

 

 

組み込みC言語
・STM32マイコン32(リスタート時の原因確認)

STM32マイコン31 (CubeIDEの使い方:レジスタ確認)

CubeIDEの使い方(レジスタ確認)

1.目的

  • レジスタの意味について記載する。
  • CubeIDEやAtlicTrueStdioでのデバック時、breakした時のレジスタ状態を確認する方法について記載する。

  • 上記は、デバック時に問題が発生した時の原因追及の為の手がかりとなる。

目次

2. レジスタとは

 ・CPUが命令を実行するために取り出した情報を保持する記憶装置をレジスタという。

 ・特にSTM32マイコンでは、内部のメモリ空間に存在する特殊な記憶領域の事をいう。

 ・このレジスタは、ハードウェアの制御やデバイスの設定、データの読み書きなどで使用される。

 

3. レジスタの種類

 ・STM32マイコンでは、一般的には下記の種類のようなレジスタがある。

 (1) 汎用レジスタ(General-Purpose Registers)

  これらのレジスタは、一般的なデータ操作や演算に使用される。

  プログラムの実行中に一時的なデータを保存するために使用される。

 

 (2) ステータスレジスタ(Status Registers)

  これらのレジスタは、ハードウェアの状態や条件を示すために使用される。

  例えば、割り込みフラグやエラーフラグなどが含まれる。

 

 (3) 制御レジスタ(Control Registers)

  これらのレジスタは、ハードウェアの動作や機能を制御するために使用される。

  例えば、タイマやUARTの設定、クロックソースの選択などが制御される。

 

 (4) イベントレジスタ(Event Registers)

  これらのレジスタは、ハードウェアのイベントやトリガーの状態を保持する。

  例えば、タイマのカウンタが特定の値に達したことを示すイベントレジスタがある。

 

 (5) ペリフェラルレジスタ(Peripheral Registers)

  これらのレジスタは、各種ペリフェラルバイス(UART、SPI、I2Cなど)の制御やデータの送受信に使用される。

  各ペリフェラルごとに固有のレジスタが存在し、そのペリフェラルの機能や設定を制御する。

 

 ・データシートを参照すると、実際には、下記のようにGPIOを制御するGPIOレジスタや、IWDGを制御するIWDGレジスタなどがあり、

 GPIOレジスタの中でも機能によってポート設定レジスタや、ポート出力データレジスタなど、様々なレジスタがある。

 そのレジスタを制御することにより、機能が使える。

 

 

詳しいレジスタやその機能については、STM32のリファレンスマニュアルを参照。

参照データシート(STM32F103):リファレンス マニュアル (日本語) | STM32, STM8ファミリはSTの32bit/8bit汎用マイクロコントローラ製品

 

4. レジスタの確認方法

 ・CubeIDEやAtlicTrueStdioのデバッカには、このレジスタがどのような状態になっているか確認する方法がある。それは、SFRsビューを使用する。

 

 ・レジスタの確認(SFRs)ビューの使用(UM2609 5.2 SFRsビューの使用方法より)
   [SFRs]ビューには、プロジェクトで使用されている STM32 デバイス

   ペリフェラルレジスタ、ビット・フィールドに関する情報が含まれる。

  参照:http://UM2609(CubeIDEユーザーガイド)

  (これは、CubeIDEのユーザーガイドだが、AtlicTrueStdioも同じ)

 

 ・プロジェクトをデバッグする場合、レジスタやビット・フィールドにはターゲットから読み出された値が設定される。

 

 確認方法
  (1) クイックアクセスにSFRsと入力
  (2) SFRs(デバック)をクリックして選択。
  (3) レジスタ画面が表示される。
  (4) 参照したいレジスタの名前をクリックすると、

   その時のレジスタの内容が見ることが出来る。

 上記画像では、GPIOCのODRレジスタ(GPIO OUT)のレジスタを確認している。

 GPIOCのODR8は、PC8で、PC8がHighの時、0x1,Lowの時0x0となる。

 レジスタを使用したGPIOの設定については、下記を参照

 →STM32マイコン_10(レジスタ操作でLED点滅) - Project_OKI’s diary

  STM32マイコン_15(レジスタ操作でLED点滅2) - Project_OKI’s diary

  

 ※これにより、breakをした時に、その時のレジスタの状態を参照することが出来る。 

 

5. SFRsビューに関して

(1)[SFRs]ビュー下部には、選択した行に関する詳細情報が表示されます。
  Access permission には、次のような詳細情報が含まれます。
  • RO(読出し専用)
  • WO(書込み専用)
  • RW(読出し / 書込み)
  • W1(1 回書込み)
  • RW1(読出し /1 回書込み)

 

(2)[Read action] には、レジスタまたはビット・フィールドの読出し時に読出し動作が存在する場合にのみ、次の情報が表示される。
  • clear
  • set
  • modify
  • modifyExternal


(3) ツールバーの RD ボタン

 このボタンは、選択したレジスタの強制読出しに使用する。

 この機能は、レジスタまたはレジスタ内の一部ビット・フィールドにReadAction が設定されていても、レジスタを読み出せる。

 

 RD ボタンをクリックしてレジスタを読み出すと、 

 ビューに表示されている他のレジスタもすべて再読み出しされ、 

 すべてのレジスタの最新の状態が反映される。

 

(4) 基数フォーマット・ボタン(X16、X10、X2) 

 レジスタ表示の基数(2進数/10進数/16進数を変更するときに使用する。

 

(5) Configure SVD settings ボタン

 現在のプロジェクトの[CMSIS-SVD Settings]プロパティ・パネルを開く。

 

(6) Pin ボタン(「自動切り換えなし」オプション)

 [Project Explorer]ビューが他のプロジェクトに切り換わっても、

 現在表示されている SVD ファイルに対するフォーカスを維持する。

 

関連記事

過去の記事:

知らないと損するお金の話(ふるさと納税、確定申告とワンストップ納税どっちが得?) - Project_OKI’s diary

C言語基礎知識6(関数) - Project_OKI’s diary

C言語基礎知識7(構造体1) - Project_OKI’s diary

C言語基礎知識8(enum:列挙型) - Project_OKI’s diary

C言語基礎知識9(typedef) - Project_OKI’s diary

C言語基礎知識10(extern宣言) - Project_OKI’s diary

C言語基礎知識11(#define) - Project_OKI’s diary

 

組み込みC言語