SDカード (FatFs) サンプルプログラム

(2015.11.28 作成)

(2019.6.11 修正)

 少し長いですが、STM32とArduinoでのサンプルプログラムを以下に示します。

 どちらもSDカードにTest.txtというファイルを作成しメッセージを書き込みます。そして再度ファイルを開き内容が書き込んだものと同一であることを確認します。

 以下のコードでSTM32、Arduinoともにほぼ似たようなコードで動作していることが分かると思います。

STM32 (STM32F103C8T6)

 F103C8T6基板での例を以下に載せます。F3Discoveryでもほぼ同様のコードで動作することは確認しています。書いたファイルの内容照合が一致するとLEDが点灯します。

#include "DKS_Common_F103xB.h"
#include "DKS_SPI_F103xB.h"
#include "DKS_Timer_F103xB.h"
#include "DKS_GPIO_F103xB.h"
#include "DKS_SD.h"
#include "DKS_F103C8T6.h"

#include <string>

DKS::STM32F103C8T6 board(DKS::BlackPill);
//DKS::DigitalIn cd;
DKS::DigitalOut cs;
DKS::Ticker ticker;
DKS::SPI::SPI spi;


extern "C" void TIM3_IRQHandler()
{
        if (LL_TIM_IsActiveFlag_UPDATE(TIM3) == 1)
        {
                LL_TIM_ClearFlag_UPDATE(TIM3);
        }
        DKS::FatFs::disk_timerproc();
}

int main(void)
{
        DKS::InitSystem();
        board.Init();

        // Prepareing FatFs
        spi.Init(SPI1, 0, 0, 0);        //PA5: SCL, PA6: MISO, PA7: MOSI
        cs.Init(GPIOB, LL_GPIO_PIN_8, DKS::Push_Pull, DKS::Pull_Up);
//      cd.Init(GPIOA, LL_GPIO_PIN_15, DKS::Pull_Up);   //card detect カード挿入時0
        ticker.Init(TIM3, 1, DKS::TimeUnit_MilliSec);
        rtc.Init(DKS::Rtc_ClockSource_LSE);
        DKS::FatFs::SetEnv(&spi, &cs, &ticker, 0, 0);

        //Local variables
        FATFS FatFs;   // 論理ドライブのワーク エリア(ファイル システム オブジェクト)
        FIL fil;       // ファイル オブジェクト
        FRESULT res;    // 戻り値
        const std::string fname = "Test.txt";
        const std::string msg = "This is the FatFs write test.";
        uint8_t writelen(0);
        char line[82]; //行バッファ
        std::string resMsg(line);

        // Create File object
        res = f_mount(&FatFs, "", 0);
        if (res != FR_OK)       return EXIT_FAILURE;
        res = f_open(&fil, fname.c_str() , FA_CREATE_ALWAYS | FA_WRITE);
        if (res != FR_OK) return EXIT_FAILURE;

        // Write text
        writelen=f_puts(msg.c_str(), &fil);
        if (writelen != msg.length()) return EXIT_FAILURE;
        res = f_close(&fil);
        if (res != FR_OK) return EXIT_FAILURE;

        // Read Test
        res = f_open(&fil, fname.c_str(), FA_READ);
        if (res != FR_OK) return EXIT_FAILURE;
        f_gets(line, sizeof(line) , &fil);
        res = f_close(&fil);
        if (res != FR_OK) return EXIT_FAILURE;

        //Confirm result
        if (resMsg == msg) nucleo.led->write(1);
        else return EXIT_FAILURE;

        while(1) {      }
}

 上記プログラムは以下のマイクロ SDカード モジュールを用いて動作確認を行っています。


Arduino (UNO)

 Arduino UNO R3で動作するソースコードです。IDE上のサンプルと同一のものです。ファイルを作成して書き込むのはSTM32と同じですが、Arduinoではシリアルポートを使用して結果を逐一報告します。

#include <TimerOne.h>
#include <SPI.h>
#include <string.h>

#include <DKS_Util_Base.h>
#include <DKS_SPI_Arduino.h>
#include <DKS_Timer_Arduino.h>
#include <DKS_GPIO_Arduino.h>
#include <DKS_RTC_Base.h>
#include <DKS_SD.h>

void CallBack(void)
{
  disk_timerproc();
}

DKS::SPI::SPI spi;  //SCK=D13, MISO=D12, MOSI=11
DKS::DigitalIn cd(8);
DKS::DigitalOut cs(9);
DKS::Ticker ticker(&CallBack, 1, DKS::TimeUnit_MilliSec);
FATFS FatFs;   // FatFs system object
FIL fil;       // File object
char line[82]; // line buffer

void setup() {
  Serial.begin(9600);

  //Declare local variables
  FRESULT res;    // return value from FatFs
  uint8_t writelen(0);

  //Set FatFs
  DKS::FatFs::SetEnv(&spi, &cs, &ticker, &cd, 0, DKS::SPI::SPI_Speed_100kHz);

  Serial.println("");
  Serial.println(F("Hello. This is the FatFs test code."));

  // Create file as writeable
  Serial.println(F("***** Create File ******"));
  res = f_mount(&FatFs, "", 0);
  if (res == FR_OK)   Serial.println(F("f_mount OK"));  else    Serial.println(F("f_mount NG"));
  res = f_open(&fil, "Test.txt" , FA_CREATE_ALWAYS | FA_WRITE);
  if (res == FR_OK)    Serial.println(F("f_open OK"));  else    Serial.println(F("f_open NG"));

  // write some text
  writelen = f_puts("This is write test.\r\n", &fil);
  Serial.print(F("Write "));  Serial.print(writelen, DEC); Serial.println(F(" bytes."));
  writelen = f_puts("Can you read?", &fil);
  Serial.print(F("Write "));  Serial.print(writelen, DEC); Serial.println(F(" bytes."));
  res = f_close(&fil);
  if (res == FR_OK) Serial.println("f_close OK");  else Serial.println("f_close NG");

  //Read text
  Serial.println("***** Read Test ******");
  res = f_open(&fil, "Test.txt", FA_READ);
  if (res == FR_OK) Serial.println("f_open OK"); else Serial.println("f_open NG");
  // read and print every line
  while (f_gets(line, sizeof(line) , &fil)) Serial.println(line);
  res = f_close(&fil);
  if (res == FR_OK) Serial.println("f_close OK");  else Serial.println("f_close NG");
}

void loop() {}