STM32F4. Урок 13 — Работа с SD-картой

Эта библиотека предназначена для работы с SD-картой с файловой системой FAT через SDIO интерфейс с использованием DMA под управлением микроконтроллера STM32f4.

Примечание: существует библиотека для USB флешки с файловой системой FATFS (урок №32) и комбинированная USB+SD библиотека (урок №87).

Для создания данной библиотеки (FATFS) был использована библиотека с открытым исходным кодом от STM для работы с функциями SDIO.

Библиотека FATFS имеет очень хорошую англоязычную документацию, в которой описаны все необходимые функции и параметры.

Далее в статье будут описано несколько основных функций, позволяющих смонтировать флешку, открыть файл, прочитать или записать строку в него.

Скорость чтения блока составляет 2.4Мбайт/с в буфер 512 байт, скорость записи на карточку — 500 кбайт/с.

Начиная с библиотеки версии 1.4 можно переключать с 4х битного на одно-битный режим управления в файле «stm32_ub_sdcard.h» режиме SDIO. Если контакт контроля не используется, его можно отключить там же.

ПРИМЕЧАНИЕ: Torsten S. с форума по микроконтроллерам указал ошибку, которая имеет функция FATFS «f_write» (и, предположительно, «f_read»). Если в эту функция передается файл больше 512 байт, происходит ошибка, и файл неправильно читается/пишется. Функции автора “WriteBlock/ReadBlock” позволяют использовать файлы больше 512 байт, так что ошибка не возникает. Но необходимо проверить отсутствие ошибки при непосредственном использовании функции.

Возможные аппаратные ошибки:

SD-карта может неправильно работать из-за каких либо аппаратных ошибок. Вот список наиболее частых из них:

  1. Плохой контакт проводников (непропай)
  2. Короткое замыкание между контактами (капля припоя и т.д.)
  3. Неправильное подключение
  4. Неисправный разъем SD-карты
  5. Карта с неправильной файловой системой
  6. Карта не поддерживается
  7. Слишком длинные линии подключения
  8. Подтяжки вверх на линиях

Пример работы и подключение:

Данные о карте.

Подключение карты.

  1. Линии соединения делайте как можно короче
  2. Не используйте подтягивающие резисторы на всех линиях
  3. Используйте SD-карты <=1Гб
  4. Используйте файловую систему FAT (FAT16), не FAT32 и не NTFS

Используемые выводы и DMA:

1-битный режим:
PC8 : SDIO_D0 = SD-карта DAT0
PC12 : SDIO_CK = SD-карта Clock
PD2 : SDIO_CMD = SD-карта CMD
Примечание: вывод CD SD-карты должен быть подключен к Vcc!!

4х-битный режим:
PC8 : SDIO_D0 = SD-карта DAT0
PC9 : SDIO_D1 = SD-карта DAT1
PC10 : SDIO_D2 = SD-карта DAT2
PC11 : SDIO_D3 = SD-карта DAT3/CD
PC12 : SDIO_CK = SD-карта Clock
PD2 : SDIO_CMD = SD-карта CMD

Вывод обнаружения карты:
PC0 : SD_Detect-Pin (Hi = SD-карта не вставленна)

либо DMA2_STREAM3_CHANNEL4
или DMA2_STREAM6_CHANNEL4

Требования:

   Подключаемые модули CooCox-IDE: GPIO, MISC, SDIO, DMA.
   Поддерживаемые библиотеки: FATFS.

Перечисления:

 typedef enum {   FATFS_OK =0,   FATFS_NO_MEDIA,   FATFS_MOUNT_ERR,   FATFS_GETFREE_ERR,   FATFS_UNLINK_ERR,   FATFS_OPEN_ERR,   FATFS_CLOSE_ERR,   FATFS_PUTS_ERR,   FATFS_SEEK_ERR,   FATFS_RD_STRING_ERR,   FATFS_RD_BLOCK_ERR,   FATFS_WR_BLOCK_ERR,   FATFS_EOF,   FATFS_DISK_FULL }FATFS_t;
 typedef enum {   F_RD =0,    // зачитать (только если файл существует)   F_WR,       // записать (только если файл существует) и добавить данные   F_WR_NEW,   // записать (создать новый файл) и добавить данные   F_WR_CLEAR  // записать поверх (удалить старые данные) }FMODE_t;

Функции:

 void UB_Fatfs_Init(void);                                            // инициализации функций FATFS FATFS_t UB_Fatfs_CheckMedia(MEDIA_t dev);                            // проверка наличия карты FATFS_t UB_Fatfs_Mount(MEDIA_t dev);                                 // смонтировать карту FATFS_t UB_Fatfs_UnMount(MEDIA_t dev);                               // отключить карту FATFS_t UB_Fatfs_DelFile(const TCHAR* name);                         // удалить файл FATFS_t UB_Fatfs_OpenFile(FIL* fp, const TCHAR* name, FMODE_t mode); // открыть файл для чтения или записи FATFS_t UB_Fatfs_CloseFile(FIL* fp);                                 // закрыть файл FATFS_t UB_Fatfs_WriteString(FIL* fp, const TCHAR* text);            // записать строку в открытый файл FATFS_t UB_Fatfs_ReadString(FIL* fp, char* text, int len);           // чтение строки из открытого файла uint32_t UB_Fatfs_FileSize(FIL* fp);                                 // чтение переменной из файла FATFS_t UB_Fatfs_ReadBlock(FIL* fp, unsigned char* buf, uint32_t len, uint32_t* read);   // побайтное чтение файла FATFS_t UB_Fatfs_WriteBlock(FIL* fp, unsigned char* buf, uint32_t len, uint32_t* write); // побайтная запись в файл

Пример использования:

 //-------------------------------------------------------------- // File     : main.c // Datum    : 06.04.2013 // Version  : 1.1 // Autor    : UB // EMail    : mc-4u(@)t-online.de // Web      : www.mikrocontroller-4u.de // CPU      : STM32F4 // IDE      : CooCox CoIDE 1.7.0 // Module   : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der FATFS-SDIO-Library // Hinweis  : Diese zwei Files muessen auf 8MHz stehen //              "cmsis_boot/stm32f4xx.h" //              "cmsis_boot/system_stm32f4xx.c" //--------------------------------------------------------------  #include "main.h" #include "stm32_ub_fatfs.h"  int main(void) {   FIL myFile;   // Хэндлер файла    SystemInit(); // Инициализация настроек кварца    // инициализации функций FATFS   UB_Fatfs_Init();    // проверка наличия карты   if(UB_Fatfs_CheckMedia(MMC_0)==FATFS_OK) { 	// Смонтировать карту     if(UB_Fatfs_Mount(MMC_0)==FATFS_OK) {       // записать в файл в коневом каталоге       if(UB_Fatfs_OpenFile(&myFile, "0:/UB_File.txt", F_WR_CLEAR)==FATFS_OK) {     	//записать несколько строк в файл         UB_Fatfs_WriteString(&myFile,"Test der WriteString-Funktion");         UB_Fatfs_WriteString(&myFile,"hier Zeile zwei");         UB_Fatfs_WriteString(&myFile,"ENDE");         // закрыть файл         UB_Fatfs_CloseFile(&myFile);       }       // отключить карту    	  UB_Fatfs_UnMount(MMC_0);     }   }    while(1)   {    } }

В приложении проект CooCox отдельная библиотека для использования в других проектах. Автор оригинала статьи просит задавать вопросы на его сайте на немецком или английских языках.