STM Урок 44. SDIO. FATFS



Урок 44

 

SDIO. FATFS

 

Проект создаём из проекта I2CLCD80. Назовем его SDIO_FATFS. Запустим проект в Cube.

Лапки портов PD4-PD7, PB8, PB9 отключим, это пережиток прошлых занятий

 

image03

 

Включим SDIO

 

image05

 

У нас включатся следующие лапки портов

 

image04

 

На основе данной информации составим таблицу подключения ножек флеш-карты Micro SD

 

Порядок подключения Micro SD к микроконтроллеру STM32F407VG

Контакт Micro SD

Ножка порта МК

Назначение вывода

1

PC10

SDIO_D2

2

PC11

SDIO_D3

3

PD2

SDIO_CMD

4

3V

+3,3 V (VDD)

5

PC12

SDIO_CK

6

GND

GND (VSS)

7

PC8

SDIO_D0

8

PC9

SDIO_D1

 

В Clock Configuration настроим делители (нажмите на картинку для увеличения)

 

image07_0500

 

 

Включим PD12 на выход

 

image06

 

Включим FATFS / SD Card

 

image01

 

В FATFS Configuration включим поддержку больших секторов на всякий случай

 

image00

 

И самое главное те, у кого нет в модуле или на плате, на которой установлен держатель, подтягивающих сопротивлений, включим его на пяти основных лапках SDIO (на всех, кроме CS) (нажмите на картинку для увеличения).

 

image02_0500

 

Сгенерируем и откроем проект, подключим lcd.c, настроим программатор на авторезет.

 

 

Прошьем контроллер, чтобы проверить, правильно ли мы все подсоединили и работает ли у нас дисплей.

Из функции main() удалим лишнее по дисплею, оставив только инициализацию и очистку

  /* USER CODE BEGIN 2 */

        LCD_ini();

        LCD_Clear();

  /* USER CODE END 2 */

Строчную переменную тажке можно удалить

  /* USER CODE BEGIN 1 */

        char str[100];

  /* USER CODE END 1 */

Добавим несколько переменных в main.c

/* USER CODE BEGIN 0 */

FATFS SDFatFs;  /* File system object for SD card logical drive */

FIL MyFile;     /* File object */

extern char SD_Path[4];  /* SD logical drive path */

/* USER CODE END 0 */

Примонтируем раздел с карты

        LCD_Clear();

 if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)

  {

    Error_Handler();

  }

  else

  {

                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);

        }

  /* USER CODE END 2 */

Соберем проект, прошьем контроллер, проверим, что у нас все примонтировалось.

Откроем файл

  else

  {

                if(f_open(&MyFile, «my001.txt», FA_READ) != FR_OK)

                {

                        Error_Handler();

                }

                else

                {

                        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);

                              f_close(&MyFile);

                }

        }

  /* USER CODE END 2 */

Добавим ряд переменных в main()

  /* USER CODE BEGIN 1 */

  FRESULT res;                                          /* FatFs function common result code */

  uint32_t byteswritten, bytesread;                     /* File write/read counts */

  uint8_t wtext[] = «Hello from Stm32!!!»; /* File write buffer */

  uint8_t rtext[100];                                   /* File read buffer */

  /* USER CODE END 1 */

Попробуем прочитать текст из файла и отобразить его на нашем дисплее

                else

                {

         res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);

         if((bytesread == 0) || (res != FR_OK))

         {

            Error_Handler();

         }

         else

         {

            LCD_Clear();

            LCD_SetPos(0,0);

            rtext[bytesread]=0;

            LCD_String((char*)rtext);

            f_close(&MyFile);

         }

                }

Соберем проект, прошьем контроллир и посмотрим результат нашей работы на дисплее.

 

Теперь попробуем что-нибудь записать

Код, который предназанчен для чтения продублируем, один дубль закоментируем и еще вверху подставим комментарий

        //Read

//        if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)

//  {

//    Error_Handler();

//  }

//  else

//  {

//                if(f_open(&MyFile, «my001.txt», FA_READ) != FR_OK)

//                {

//                        Error_Handler();

//                }

//                else

//                {

//        res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);

//         if((bytesread == 0) || (res != FR_OK))

//         {

//            Error_Handler();

//         }

//         else

//         {

//            LCD_Clear();

//            LCD_SetPos(0,0);

//            rtext[bytesread]=0;

//            LCD_String((char*)rtext);

//            f_close(&MyFile);

//         }

//                }

//        }

 

А другой дубль будем исправлять на запись, кое-что также в нем сначала закоментировав, функцию f_close() перенесем ниже за другую скобку, чтобы файл у нас закрывался строго, также изменим имя файла и флаги открытия файла и зажжем в случае успеха светодиод

        //Write

        if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)

  {

    Error_Handler();

  }

  else

  {

                if(f_open(&MyFile, «mywrite.txt«, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)

                {

                        Error_Handler();

                }

                else

                {

//        res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);

//         if((bytesread == 0) || (res != FR_OK))

//         {

//            Error_Handler();

//         }

//         else

//         {

//            LCD_Clear();

//            LCD_SetPos(0,0);

//            rtext[bytesread]=0;

//            LCD_String((char*)rtext);

//         }

f_close(&MyFile);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);                }

}

Если светодиод зажегся, то вызовы функций дисплея удалим, а также раскомментируем и исправим следующие строки

                else

                {

                        res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);

                        if((byteswritten == 0) || (res != FR_OK))

                        {

                                Error_Handler();

                        }

                        else

                        {

                                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);

                        }

                        f_close(&MyFile);

Немного исправим текст в переменной wtext, чтобы мы не думали что это текст из другого файла

  uint8_t wtext[] = «Hello write from Stm32 to Micro SD!!!«; /* File write buffer */

Соберем проект, прошьем контроллер, отключим плату, извлечем флеш-карту из картодержателя, воткнем в картовод ПК и убедимся, что новый файл с содержимым у нас на карте появился.

 

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Отладочную плату можно приобрести здесь STM32F4-DISCOVERY

Удобный модуль Micro SD (SPI и SDIO) можно приобрести здесь Micro SD Модуль

Смотреть ВИДЕОУРОК

 

 

STM SDIO. FATFS

 

39 комментариев на “STM Урок 44. SDIO. FATFS
  1. Виталий:

    Здраствуйте!

    Как можно скопировать txt. файл с sd большого размера в sdram?

  2. Игорь:

    Здравствуйте,

    Не получается запись и чтение файла, при попытке записать файл МК зависает,

    Хотя монтирование диска происходит без ошибки. (STM32F103ZET6)

      /* USER CODE BEGIN 3 */

            if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11)) // ЗАПИСЬ
            {
            HAL_Delay(200);
            if(f_open(&MyFile,"data.txt",FA_CREATE_ALWAYS|FA_WRITE)!= FR_OK)
            {
           ЗДЕСЬ ОШИБКА     

    HAL_UART_Transmit_IT(&huart1, err, 5);    // 
                f_close(&MyFile);
                Error_Handler();
            }
            else
            {
                res=f_write(&MyFile,wtext,sizeof(wtext),(void*)&byteswritten);
                if((byteswritten==0)||(res!=FR_OK))
                {
                    HAL_UART_Transmit_IT(&huart1, err2, 5);    //отправить байт
                    Error_Handler();
                }
                else
                {
                    //HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_SET);
                }
                f_close(&MyFile);
            }
            } // end button

  3. Андрей:

    Не подскажите почему может выдавать ошибку FR_DISK_ERR

    фунуция f_open. Такую же ошибку выдает функция f_mount если поставить последний параметр 1 (монтировать немедленно). Правильность подключения проверил несколько раз все правильлно.

    И ещо вопрос по функции Error_Handler();. Что там должно быть у меня там пустой бесконечний цикл.

    • 1. Видимо не прошла инициализации. Тогда её лучше вызвать отдельно. Либо проект в процессе написания. Бывает такое в этом случае. Надо время от времени снимать питание с носителя. Помогает.

      2. Приблизительно то же самое.

      3. Должен быть бесконечный цикл. Сделано для того, чтобы дальнейший код не пытался выполняться при ошибочных ситуациях.

  4. Михаил:

    Здравствуйте! STM32F405 подключена по SDIO карта памяти два вопроса: 1) Куб генерирует код hsd.Init.BusWide = SDIO_BUS_WIDE_1B; хотя мы работаем с 4х битной шиной?? 2) При записи большого файла ( просто пишу 1 млн значений подряд ++) при делителе SDIO 15 и выше работает стабильно, а при меньших делителях вылетает в ошибку FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ Частотата шины 55 МГц. Влияет ли длина проводов или что то еще? подтягивающих резисторов нет, только внутренняя подтяжка.

    Спасибо.

  5. Igor:

    Здравствуйте! С удовольствием читаю и смотрю ваши уроки. В данном разделе работы с SDIO все получилось. А вот при попытке превратить связку STM32+SD(SDIO) в картридер (+USB в режиме Mass Stotage Class) получается только запись-чтение на SD карту. Форматирование SD через STM32 средствами Windows никак не проходит и есть вопросы по быстродействию работы с SD через USB. Не могли бы вы посвятить теме «Картридер на STM32» отдельный урок?

    Спасибо!

    • Да вроде был по SDIO FATFS уже урок. А вообще поаккуратней с FATFS. Версия куба не должна быть новей чем 4.22.1

      • Igor:

        Да, но в нем ничего нет про работу с SD картой через USB Mass Stotage Class (STM32 не хост). Одним словом режим картридера для считывания накопленных ранее данных в ST32+SD через USB.

  6. Здравствуйте! Все сделал как в описании, только f_open присваивается ошибка и на выходе с ног нету никаких подергиваний( Что может быть не так?

  7. Googl выдал:
    Внимание! Переход на этот веб-сайт может быть опасен для вашего компьютера.

    при переходе на «Программирование микроконтроллеров STM32. УРОК 37»
    я бы на Вашем месте проверил сайт на вирус и взлом!

  8. ssp:

    Так что же с новой FatFS? Неужели продолжения не будет? Вот и куб обновился, но этот глюк остался…

  9. ssp:

    У меня STM32F405, плату сам разводил. С помощью вашего урока N44 успешно запустил чтение-запись SD на старом кубе и старой фирмваре для этого чипа. Потом обновился до последней на сегодня версии и того и другого. Работать перестало. Заглянул в fatfs.c — увидел там измение идентификатора SD_Path на SDPath. Поменял соответственно в f_mount. Карта упорно не монтруется.
    Огромная к Вам просьба — сделайте еще один урок по новой версии.

  10. Гордеев Константин:

    Вышла новая версия STM32CubeMX version 4.24.0
    А так же новая версия STM32Cube FW_F4 V1.19.0
    С ними SD карта снова работает.
    Возможно, придётся пересоздать проект «с нуля».

    • Я приблизительно отвечал где-то то же самое. Для 4 версии контроллера поправили (для 1-й не проверял), а вот для 7-й (библиотека STM32Cube_FW_F7_V1.9.0) — пока нет. Но скоро всё поправят. Я передал в технический отдел.

  11. ssp:

    >Вышла новая версия STM32CubeMX version 4.24.0
    >А так же новая версия STM32Cube FW_F4 V1.19.0

    Да, с ними действительно работает. Чтобы заработало, нужно в FATFS Configuration на вкладке IPs instances выставить Use dma template -> Disabled. По-умолчанию эта штука разрешена и по-умолчанию с ней не работает.

  12. ssp:

    А все же хорошо бы еще один урок, только теперь с использованием SDIO DMA. Самому разобраться не получается, а нормальных примеров я не нашел…

  13. Михаил:

    ssp:, Спасибо за ответ! полдня из за этого гребанного DMA Убил. Автору спасибо за сайт, очень много полезной информации!!!

  14. Михаил:

    Добрый день очень полезный ресурс.
    Много чему здесь научился.

    Debug зависает именно здесь 4 разных карт перебробовал.
    Форматировал и 16 и 32 бит
    if(f_open(&MyFile,»mywrite.txt»,FA_CREATE_ALWAYS|FA_WRITE)!=FR_OK)
    версия куба 4.25.1

    зарание блогодарен.

  15. Владимир:

    Здравствуйте.
    Пытаюсь запустить FATFS на STM32L433, вылетает ошибка на f_open. Версия куба 4.25.1. Не подскажете, где взять более старые версии куба?

  16. volw:

    Здравствуйте! Хочу записывать логи с разных датчиков, для тестирования сделал вот такую функцию:

    void SDwriteLog(uint8_t *wtext, uint8_t sz)
    {
    f_mount(&SDFatFs, (TCHAR const*)SD_Path, 1);
    f_open(&MyFile, «myfile.txt», FA_WRITE);
    for (char i=0; i<3; i++)
    {
    res = f_write(&MyFile, wtext, sz, (void*)&byteswritten);
    if((byteswritten != sz) || (res != FR_OK))
    {
    //Делаем что-то если не записали в файл
    }
    else
    {
    //Все хорошо, файл записан
    }
    }
    f_close(&MyFile);
    f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0);
    }

    В цикле удается записать три строки, но если файл каждый раз открывать и закрывать в цикле, то строка получается только одна. Я так понимаю если при записи каждой строки открывать/закрывать файл то дописывать уже не может.
    Собственно вопрос — с каким аргументом нужно открыть файл чтобы появилась возможность дописывать строки не удаляя прежнюю информацию

    • Здравствуйте!
      Это от аргументов не зависит. Открываете файл, измеряете его размер и дописывайте куда хотите. Ставите указатель в любое место и пишите сколько угодно. Есть специальная для этого функция f_lseek.

      • volw:

        Спасибо!
        добавил две строчки:
        if(MyFile.fsize)
        f_lseek(&MyFile, MyFile.fsize); после открытия файла.
        Теперь продолжает писать файл даже после извлечения карты.
        А я считал что f_lseek только для чтения

  17. Вася Пупкин:

    Здравствуйте.
    Объясните пожалуйста почему Вы установили MAX_SS =4096?
    В справке по FATfs я нашел «Always set 512 for memory card and hard disk…».
    Может быть имелся ввиду размер кластера а не сектора?
    Вроде бы в спецификации SD размер сектора тоже указан 512.
    Проясните пожалуйста этот момент, а то я запутался.

  18. Вася Пупкин:

    Приведите пожалуйста пример носителя с таким размером блока, сам не смог таких найти.

  19. Anrey:

    Здравствуйте.
    Подскажите как записать дату создания файла, например 20 мая 2015 14:52?

  20. seyf:

    Здравствуйте.
    Пытаюсь запустить sd карту на stm32f411, сделал все по Вашему уроку, но данные на карту не записываются.
    Команда f_mount проходит, а команда f_open выкидывает в while.
    При проверке Logic-ом, видно что ck тактируется на частоте 400кГц, проходит 3 команды и все.

    • Здравствуйте!
      Посмотрите примеры для своего контроллера в репозитории, так как со времён урока изменилась HAL в отношении работы с SDIO, а также FATFS.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*