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電源はマイコン以外のものを用意する。
FATFSを追加。
SPIを追加。
通信速度は、10Mを超えるとダメになることが多いらしいです。
SPI通信のSS(CS)用のピンを割り当てた。
(GPIOならなんでもいいが、参考先ではPB0に割り当てている。)
ここからfatfs_sd.cとfatfs_sd.hを入手し、それぞれ自分のSrcとIncに入れて、リフレッシュする。
https://controllerstech.com/wp-content/uploads/2020/07/SDCARD_SPI_OLD_F103.zip
以下3つのファイルを開いて、下記のコードを追加。
#include "fatfs_sd.h"
return SD_disk_initialize(pdrv);
return SD_disk_status(pdrv);
return SD_disk_read(pdrv, buff, sector, count);
return SD_disk_write(pdrv, buff, sector, count);
return SD_disk_ioctl(pdrv, cmd, buff);
#include "stm32f4xx_hal.h"
extern SPI_HandleTypeDef hspi1;
#define SD_CS_GPIO_Port GPIOB
#define SD_CS_Pin GPIO_PIN_0
volatile uint8_t FatFsCnt = 0;
volatile uint8_t Timer1, Timer2;
void SDTimer_Handler(void)
{
if(Timer1 > 0)
Timer1--;
if(Timer2 > 0)
Timer2--;
}
FatFsCnt++;
if(FatFsCnt >= 10)
{
FatFsCnt = 0;
SDTimer_Handler();
}
最後にmain.cを実装する。
#include "fatfs_sd.h"
#include "stdio.h"
#include "string.h"
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);
}
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);
}
自分はこれで動いた。
ファイルが書き込めているか否かは、パソコンで確認できる。