STM32F746DiscoでSTM32CubeIDEプロジェクトを通じてSDカードを扱う
STM32CubeF7からSDカードプロジェクトを作ると簡単ですが、様々なボードに対応しているためフォルダー構造が複雑ですし、ファイル容量も大きいです(不要なコードを削除すればある程度は小さくなります)。
またSTM32CubeIDEに慣れてしまうとGUIのペリフェラル設定が使えないのも困ります。
そこでSTM32CubeIDEベースでSDカードが使えるようにしてみます。
では始めましょう!!!
ちなみに私のSTM32CubeIDEは日本語化しているのでメニューの表現が日本語になります。日本語化していない方は日本語⇔英語を読み替えて見てください。
まずSTM32CubeIDEプロジェクトを作ります。
ファイル>新規>STM32 Projectを選択するとTarget Selectionウィンドウが開きます。
Board SelectorタブのBoards Listで32F746DISCOVERYを選択して「次へ」ボタンを押します。
プロジェクト名に適当な名前を入れて(本例ではF746DiscoFatfsSDwithRTOCにしています)「完了」ボタンを押します。
本プロジェクトのCore>Src>main.cに”STM32F746DiscoveryでSDカードを扱う”で使用したmain.cコードを順次コピペしていきます。
”STM32F746DiscoveryでSDカードを扱う”のmain.cでは1回のみ実行されるStartThreadタスクでSDカードWrite/Readをしています。同様にStartThreadタスクを追加してもいいのですが、作ったプロジェクトには1msおきに実行されるStartDefaultTaskタスクがあるので、そのStartDefaultTaskタスクの繰り返しでないところにコピペします。
具体的にはコメントで”USER CODE BEGIN 5”と”Infinite loop”となっている間に、”「その1」”のStartThreadタスクの中身を丸々コピペします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void StartDefaultTask(void const * argument) { /* init code for USB_HOST */ MX_USB_HOST_Init(); /* USER CODE BEGIN 5 */ /* ここにStartThread関数の中身全体を入れる */ /* Infinite loop */ for(;;) { osDelay(1); } /* USER CODE END 5 */ } |
ちなみに”USER CODE BEGIN”と”USER CODE END”の間、以外のところにユーザーコードを書くとiocファイルを変更したとき綺麗サッパリ消されてしまうのでご注意を。
せっかく書いた大量のコードを失うリスクを多少なりとも減らすためにはiocファイルのProject Managerタブ>Code Generator>Generated files>Backup previously generated files when re-generatingにチェックを入れておけば直前のコードだけはバックアップされます。
またBSP_LED_On関数もないので削除します。これはSDカードWrite/Readが終わったことを知らせるインジケーターです。このインジケーターはLD1(PI1)なのでPI1の初期設定をOutputにして(あとでGUI設定ファイルを修正するときに合わせてやります)、BSP_LED_Onの代わりに
HAL_GPIO_Writ ePin(GPIOI, GPIO_PIN_1, GPIO_PIN_SET);
を追記します。
また” STM32F746DiscoveryでSDカードを扱う”のmain.cの最初の方にあるPrivate variables以下の
1 2 3 4 |
FATFS SDFatFs; FIL MyFile; char SDPath[4]; uint8_t workBuffer[2*_MAX_SS]; |
も本プロジェクトのUSER CODE BEGIN PV以下にコピーします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void StartDefaultTask(void const * argument) { /* init code for USB_HOST */ MX_USB_HOST_Init(); /* USER CODE BEGIN 5 */ FRESULT res; /* FatFs function common result code */ uint32_t byteswritten, bytesread; /* File write/read counts */ uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */ uint8_t rtext[100]; /* File read buffer */ /*##-1- Link the micro SD disk I/O driver ##################################*/ if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0) { /*##-2- Register the file system object to the FatFs module ##############*/ if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK) { /* FatFs Initialization Error */ Error_Handler(); } else |
プロジェクト>プロジェクトのビルドを実行します。
そして実行>デバック>STM32 Cotex M C/C++ Applicationを押すと起動構成プロパティーの編集ウィンドウが開くのでそのまま「OK」を押すとプログラムがダウンロードされて実行開始待ち状態にるので適当なマイクロSDカードを挿して、実行>再開を押してプログラムを走らせます。
しかし残念ながら実行結果としてSDカードWrite/Readは正常終了しませんしLD1も点灯しません。。
これは一つは” STM32F746DiscoveryでSDカードを扱う”プロジェクトでは最初に
1 |
if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0) |
をやっていますが、本プロジェクトではStartDefaultTaskタスクの最初の
1 |
MX_FATS_Init(); |
内で”FATFS_LinkDriver”を実行しているため2回目の”FATFS_LinkDriver”でエラーしているためです。
ということで2回目の”FATFS_LinkDriver”を削除します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void StartDefaultTask(void const * argument) { /* init code for USB_HOST */ MX_USB_HOST_Init(); /* USER CODE BEGIN 5 */ FRESULT res; /* FatFs function common result code */ uint32_t byteswritten, bytesread; /* File write/read counts */ uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */ uint8_t rtext[100]; /* File read buffer */ /*##-1- Link the micro SD disk I/O driver ##################################*/ if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0) { /*##-2- Register the file system object to the FatFs module ##############*/ // if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK) { /* FatFs Initialization Error */ Error_Handler(); } else |
あとGUI設定ファイル(iocファイル)のConnectivity>SDMMC1でNVIC SettingsとDMA Settingsが有効になっていません。
それぞれ
・NVIC Settings>SDMMC1 global interruptのEnableにチェックを入れます。
・DMA Settings>Add”ボタンを押してSDMMC1_TX、SDMMC1_RXを追加します(設定は初期値のままでいいです)。
を行います。
あとLD1のGPIO設定をします。
再度、ビルドして実行すると今度はLD1が点灯して、SDカードWrite/Read正常終了が確認できます。
ちなみにEthernet(ETH)をDisableにすると初期化部分が速くなります。