STM Урок 58. System Workbench. LCD. SDIO. Часть 2



Урок 58

 

Часть 2

 

System Workbench. System Workbench. LCD. SDIO

 

В предыдущей части урока мы познакомились с организацией памяти SDRAM на плате Discovery и подключили библиотеки, включая SDIO, FATFS, также подготовили проект и примонтировали файловую систему FAT.

Теперь собственно начнем писать функцию, которая будет переписывать содержимое файла в нужное место памяти SDRAM

 

/* USER CODE BEGIN 0 */

uint32_t OpenBMP(uint8_t *ptr, const char* fname)

{

  uint32_t ind = 0, sz = 0, i1 = 0, ind1 = 0;

  static uint32_t bmp_addr;

  if(f_open(&MyFile, fname, FA_READ) != FR_OK)

  {

    BSP_LCD_Clear(LCD_COLOR_RED);

  }

  else

  {

  }

  return 0;

}

/* USER CODE END 0 */

 

Здесь, я думаю всё понятно, так как с SD мы уже работали в стандартном проекте, тут ничего не изменилось.

Вызовем функцию в бесконечном цикле задачи по умолчанию

 

/* Infinite loop */

for(;;)

{

  OpenBMP((uint8_t *)bmp1,«image01.bmp«);

  osDelay(100);

}

/* USER CODE END 5 */

 

Можно собрать проект и убедиться, что дисплей у нас не покраснеет.

Добавим библиотеку в файл main.c

 

/* USER CODE BEGIN Includes */

#include <stdlib.h>

#include <string.h>

 

 

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

 

    BSP_LCD_Clear(LCD_COLOR_RED);

  }

  else

  {

    if (f_read (&MyFile, sect, 30, (UINT *)bytesread) != FR_OK)

    {

      Error_Handler();

    }

    else

   {

      bmp_addr = (uint32_t)sect;

      sz = *(uint16_t *) (bmp_addr + 2);

      sz |= (*(uint16_t *) (bmp_addr + 4)) << 16;

      /* Get bitmap data address offset */

      ind = *(uint16_t *) (bmp_addr + 10);

      ind |= (*(uint16_t *) (bmp_addr + 12)) << 16;

      f_close (&MyFile);

    }

 

Продолжаем писать дальше.

Файл нужно будет открыть заново (хотя это и необязательно), а потом не забыть закрыть.

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

 

      f_close (&MyFile);

      f_open (&MyFile, fname, FA_READ);

      ind=0;

      do

      {

        if (sz < 512)

        {

          i1 = sz;

        }

        else

        {

          i1 = 512;

        }

        sz -= i1;

      }

      while (sz > 0);

      f_close (&MyFile);

 

Теперь будем читать постепенно секторы с SD-карты (не обязательно по 512, я пробовал по 8192 — работает ещё быстрее)

 

  sz -= i1;

  f_lseek(&MyFile,ind1);

  f_read (&MyFile, sect, i1, (UINT *)&bytesread);

  memcpy((void*)(bmp1+ind1), (void*)sect, i1);

  ind1+=i1;

}

 

Также не забываем обнулить счётчик

 

    f_close (&MyFile);

  }

  ind1=0;

}

 

Теперь в задаче по умолчанию вызовем функцию библиотеки BSP для отрисовки изображения из памяти SDRAM на экран дисплея

 

OpenBMP((uint8_t *)bmp1,«image01.bmp«);

BSP_LCD_DrawBitmap(0,0,(uint8_t *)bmp1);

osDelay(100);

 

 

Но прежде чем собирать проект, запускать его и любоваться картинкой, необходимо отключить оптимизацию, иначе никаких картинок мы не увидим. В свойствах проекта в C/C++ Build -> Settings -> Tool Settings -> MCU GCC Compiler -> Optimization установим следующий параметр Optimization level

 

image05

 

Теперь можно собрать проект и запустить его на выполнение. Картинка должна появиться на экране

 

image00

 

Можно подключить остальные картинки, пусть появляются по очереди

 

  osDelay(100);

  OpenBMP((uint8_t *)bmp1,«image02.bmp«);

  BSP_LCD_Clear(LCD_COLOR_BLACK);

  BSP_LCD_DrawBitmap(0,0,(uint8_t *)bmp1);

  osDelay(100);

  OpenBMP((uint8_t *)bmp1,«image03.bmp«);

  BSP_LCD_DrawBitmap(0,0,(uint8_t *)bmp1);

  osDelay(100);

  OpenBMP((uint8_t *)bmp1,«image04.bmp«);

  BSP_LCD_DrawBitmap(0,0,(uint8_t *)bmp1);

  osDelay(100);

}

/* USER CODE END 5 */

 

Соберем проект и посмотрим ещё раз на все 4 картинки

 

image01 image02 image03

 

На этом можно было бы закончить урок, но надо же нам как-то увидеть нотку многозадачности.

Давайте время от времени будем рисовать в углу прямоугольник неопределённого цвета. Для этого во вторую задачу добавим следующий код

 

void StartTask02(void const * argument)

{

  /* USER CODE BEGIN StartTask02 */

  /* Infinite loop */

  for(;;)

  {

    BSP_LCD_SetTextColor((uint32_t)(LCD_COLOR_TRANSPARENT|((rand()%256)<<16)|((rand()%256)<<8)|(rand()%256)));

    BSP_LCD_FillRect(384,136,96,136);

    osDelay(10000);

  }

  /* USER CODE END StartTask02 */

}

 

Соберем проект и прошьём контроллер. Прямоугольник иногда появляется

 

image04

 

Также теперь можно поиграть с размером сектора.

Сначала заменим в трех местах значение 512 на 4096

 

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

uint8_t sect[4096];

 

 

    do

    {

      if (sz < 4096)

      {

        i1 = sz;

      }

      else

      {

        i1 = 4096;

      }

 

После этого мы с вами увидим значительное увеличение скорости перебороски изображения с карты в память SDRAM. Прежде чем вернуть всё на место, попробуем увеличить до 8192 и тогда мы заметим ещё прирост производительности считывания файла.

Ну теперь можно вернуть всё на место, а можно и так оставить.

Считаю, что цель нашего занятия сегодня достигнута. Мы подключили шину SDIO, причём автономно, без применения библиотеки BSP. Сейчас данная библиотека у нас используется только для работы с дисплеем.

Также советую посмотреть видеоурок особенно тем у кого нет такой платы, чтобы увидеть всё воочию.

 

 

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

 

Исходный код

 

 

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

 

 

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

 

STM32 System Workbench. LCD. SDIO

3 комментария на “STM Урок 58. System Workbench. LCD. SDIO. Часть 2
  1. vasa:

    Добрый день!
    Интересует такой вопрос. А как посчитать: сколько памяти отвести под задачу для записи на карту памяти по SDIO? У Вас отведено 1280. Однако это достаточно много, так как FreeRTOS requires to allocate in the heap for that user task:
    number of bytes = TCB size + (4 * task stack size), то есть аж 5240.

    Использую плату STM32F4Discovery. По умолчанию в CubeMX стоит TOTAL_HEAP_SIZE=15360. Таким образом, памяти остается маловато на другие задачи (всего 9488 Bytes). И сколько можно отвести вообще? Всю RAM? 

    Спасибо!

     

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

      Я не считал, сколько именно нужно. Последовал совету коллеги и увеличил в 10 раз, приписав 0. Поэтому подсказать не могу, так как нужно от и до знать алгоритм работы ОС.

  2. Carsten:

    Привет и приятный день, в первую очередь большой комплимент для этой домашней страницы с большим количеством интересных уроков о STM32. Я пришел на урок 58, и все предыдущие уроки были понятны и работали. У меня есть вопрос о уроке 58, с которым у меня возникают проблемы. Я могу понять, какая программа создана, но она не работает над обнаружением STM32F746. По-видимому, новые версии драйверов CubeMX версии 4.27 и F7V1.12 создают другой код. Вы также столкнулись с этими проблемами? По-видимому, программа зависает в f_open до таймаута.
    У вас есть подсказка для меня, как получить пример с более новыми версиями или подходом, который был изменен? (SD-карта работает без FREERTOS)
    Заранее спасибо!
    С наилучшими пожеланиями
    Карстен Шульц

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

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

*