microSDカードの読み書きをstm32のSPI通信で行う。(2024/6/12)

この動画が非常に参考になった。

自分の場合、このリンク先の「UPDATE 2」に該当した。
https://controllerstech.com/sd-card-using-spi-in-stm32/

回路は、以下の画像に注意して、(SDCのSPI列)
必ずSCLK以外のDO、DI、CSは、10kΩでプルアップし、3.3V電源はマイコン以外のものを用意する。

画像18


秋月電子のmicroSDカードスロットを使用。
SPIの前にSDIOに挑戦したが、自滅した。

FATFSを追加。

画像2

SPIを追加。
通信速度は、10Mを超えるとダメになることが多いらしいです。

割り当てられないときは、LEDのGPIOが有効になっていたり。


Band Rateが2.5MHzくらいに。

SPI通信のSS(CS)用のピンを割り当てた。
(GPIOならなんでもいいが、参考先ではPB0に割り当てている。)

画像5

ここからfatfs_sd.cとfatfs_sd.hを入手し、それぞれ自分のSrcとIncに入れて、リフレッシュする。
https://controllerstech.com/wp-content/uploads/2020/07/SDCARD_SPI_OLD_F103.zip

画像6

以下3つのファイルを開いて、下記のコードを追加。

画像18
 #include  "fatfs_sd.h"
画像18
return SD_disk_initialize(pdrv);

return SD_disk_status(pdrv);
画像19
return SD_disk_read(pdrv, buff, sector, count);
画像19
return SD_disk_write(pdrv, buff, sector, count);

return SD_disk_ioctl(pdrv, cmd, buff);
画像17
 #include  "stm32f4xx_hal.h"

 extern SPI_HandleTypeDef hspi1;

 #define  SD_CS_GPIO_Port GPIOB
 #define  SD_CS_Pin GPIO_PIN_0


画像17
volatile uint8_t FatFsCnt = 0;
volatile uint8_t Timer1, Timer2;

void SDTimer_Handler(void)
{
if(Timer1 > 0)
	Timer1--;
if(Timer2 > 0)
	Timer2--;
}
画像17
	FatFsCnt++;
	if(FatFsCnt >= 10)
	{
		FatFsCnt = 0;
		SDTimer_Handler();
	}

最後にmain.cを実装する。

画像21
 #include  "fatfs_sd.h"
 #include  "stdio.h"
 #include  "string.h"
画像17
FATFS fs;
FIL fil;
FRESULT fresult;
char buffer[1024];
char buffer2[1024];
UINT br, bw;

FATFS *pfs;
uint32_t fre_clust, tot_size, fre_size;

void send_uart(char *s)
{
	HAL_UART_Transmit(&huart2, (uint8_t *) s, strlen(s), 2000);
}
画像17
  fresult = f_mount(&fs, "/", 1);
  if(fresult == FR_OK){
 	  send_uart("SD CARD mounted successfully!!!\n");
  }else{
 	  send_uart("ERROR!!! in mounting SD CARD...\n");
  }

  if(f_getfree("", &fre_clust, &pfs) == FR_OK){
 	  tot_size = (pfs->n_fatent - 2) * pfs->csize * 0.5;
 	  sprintf(buffer, "Total size: %15lu B\n", tot_size * 1024);
 	  send_uart(buffer);
 	  fre_size = fre_clust * pfs->csize * 0.5;
 	  sprintf(buffer, "Free size: %15lu B\n", fre_size * 1024);
 	  send_uart(buffer);
  }

  if(f_open(&fil, "file1.txt", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK){
 	  strcpy(buffer, "ajwoeifjaponewpfniwenvpjoiwnheiwoapv\n");
 	  f_write(&fil, buffer, strlen(buffer), &bw);
 	  f_close(&fil);
  }

  if(f_open(&fil, "file1.txt", FA_READ) == FR_OK){
 	  send_uart("file1 open.\n");
      f_read(&fil, buffer2, f_size(&fil), &br);
      send_uart(buffer2);
      f_close(&fil);
  }

自分はこれで動いた。
ファイルが書き込めているか否かは、パソコンで確認できる。

画像19
画像20













この記事が気に入ったらサポートをしてみませんか?