본문 바로가기
프로젝트 기록/23SEMA_Control_STM32

[STM32] SDcard 쓰기 방법 총정리 (SPI기반, FatFS middle ware 사용)

by 소요이 2023. 5. 26.
728x90

 

1. SPI 패리패럴 설정

- 기반 Connectivity: SPI 통신 기반으로 SD카드에 데이터를 씀

- 프로젝트 사용 패리패럴: SPI2

- Full-Duplex Master 모드 선택 (전이중 통신 Master)

- Clock Parameters: Baud Rate가 10MBits/s 정도가 되도록 해서 안정적 통신 가능하도록 할 것.

  SPI2의 Prescaler값을 조정하여 10.5MBits/s로 설정하였음

 

 

 

 

2.  SPI관련 Pin out 설정

 - SPI2 Mode를 설정하여 기능을 사용하기 시작하면, 자동으로 관련 핀들이 생김.

 - MISO, MOSI, SCK 핀은 할당된 핀으로 자동 연결됨

 - CS핀은 자동 생성되지 않아 원하는 핀으로 직접 설정해야 함

 

 +) 이번 프로젝트에서는 CS핀 하드웨어 핀을 따로 연결하지 않았음. 

 - 이유: SPI2에 연결된 디바이스가 하나밖에 없고, 전원 공급 후 차단되기 전까지는 계속 SPI통신이 필요함.

 

- 디바이스가 하나뿐일 때: CS핀을 사용하면 디바이스 자동 "stand-by" 모드로 전환 기능 사용 가능(SPI통신이 비활성화 될 때)

 - 디바이스가 여러 개일 때: 반드시 CS핀으로 각 디바이스에 unique한 식별자를 부여하고, 이을 통해 어떤 디바이스와 통신을 할 지 결정해야 함.

 - 즉, 여러 디바이스를 관리하거나, SPI 디바이스의 특정 상태를 관리할 필요가 있다면 CS 핀을 사용해야 함

 

사용하는 Clock Configuration: SPI2 패리패럴로 공급되는 PCLK1 = 42 MHz (데이터 시트에서 확인 가능)

 

 - 정석으로 사용할 경우, CS핀의 설정은 아래와 같음

GPIO_Output : SD_CS
GPIO output level : High로 설정

 

 

 

 

 

3. FASFS 설정

 

- Middleware > FATFS > User-defined 체크

-  긴 파일명을 지원:

     USE_LFN항목을 'Enabled with static working buffer on the BSS' 로 변경

- 한 번에 쓸 최대 섹터 크기 설정:

     MAX_SS(Max Sector Size) 항목을 4096 으로 변경 (한 번에 최대 4096바이트 (4KB)의 데이터 읽기/쓰기 가능)


 +) 섹터: 블록 저장 장치에서 데이터를 읽고 쓰는 가장 작은 단위

 - FAT 파일 시스템에서는 일반적으로 512바이트로 설정되어 있음
- MAX_SS 값을 키우면 읽기 및 쓰기 속도를 향상시킬 수 있지만, 더 많은 메모리를 사용하게 됨

 

 

 

 

 

4. Generate Code 

Generate Code (Alt + k) 를 하면, 자동으로 추가되는 디렉토리는 다음 노란 표시 부분과 같음.

핑크색으로 표시된 파일들을 변경해줘야 함.

 

 

 

 

5. 드라이버 관련 작업

1) 수정해 줘야 하는 파일:

 

- < user_diskio.c >: 아래 링크 참고하여 수정하면 됨 (알아보기 쉽게 되어있음)

https://www.micropeta.com/User_DiskIO

user_diskio.c
0.00MB

DSTATUS USER_initialize(), DSTATUS USER_status(), 

DRESULT USER_read (), DRESULT USER_write (), DRESULT USER_ioctl () 함수들 변경

 

+) 수정의 의미: "디버깅에 도움이 되도록, 실제 동작의 결과값을 반영하여 return"

원래의 코드는 실제로 진행된 동작과는 관계없이, 항상 성공했다는 값을 반환함. -> 문제 파악 어려움

아래와 같이 수정하면 쓰기 동작의 성공 여부를 확인할 수 있음

 

return하는 값이 RES_OK 에서 SD_disk_read값으로 바뀌었음

 

 

- < stm32f4xx_it.c > : 인터럽트 관련 파일, Core > Src 내에 있음

코드에서 systick_Handler 함수 찾아서 아래 부분만 추가

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
	if(Timer1 > 0)
		Timer1--;
	if(Timer2 > 0)
		Timer2--;
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

 

 

 

2) 새로 추가해야 하는 파일:

- <fatfs_sd.c>, <fatfs_sd.c> : https://www.micropeta.com/video29

 

아래 위치에서 New > Source File 선택 후, 위 사이트에서 코드 복사해서 추가하면 됨

추가해야 하는 파일 위치
파일 추가하는 법

 

fatfs_sd.c
0.01MB
fatfs_sd.h
0.00MB

(내가 사용한 파일들 첨부)

 

 

+) 기존 github 코드에서 변경한 부분:

- fatfs_sd.h : SPI패리패럴 변경, CS핀 포트 및 핀 변경

좌: 참고한 원본 코드 / 우: 내 프로젝트 코드

- fatfs_sd.c: 보드 종류에 따라 HAL 라이브러리 이름 변경

좌: 참고한 원본 코드 / 우: 내 프로젝트 코드

+) 인용

테스트 코드, 참고한 과정 포함된 블로그: https://m.blog.naver.com/eziya76/221188701172

SD Card with Blue Pill using STM32CubeIDE: https://www.micropeta.com/video29

 

 

 

최종 구현:

https://skook.tistory.com/182

 

[SDcard] 최종 동작 정리

SD카드 기록 설명서 주의사항: "PA8 - PD2 핀 반드시 연결" : 연결외부 인터럽트 트리거 핀을 사용하는 TIM3을 기반으로 하기 때문에, 두 핀을 연결해야 정상동작 가능 0. 출력 형식 00:17:56 / speed: 0.00km/

skook.tistory.com