STM Урок 62. FMC SDRAM. Часть 2

 

 

 

 

Урок 62

 

Часть 2

 

FMC SDRAM

 

 

В прошлой части нашего занятия мы познакомились с микросхемой памяти SDRAM MT48LC4M32B2 от компании Micron.

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

Сегодня мы продолжим начатое дело.

Начнём мы данную часть с создания проекта.

Мы создадим новый проект в Cube MX, выберем контроллер (нажмите на картинку для увеличения размера)

 

image04_0500

 

Начнем настраивать проект.

Первым делом включим кварцевый резонатор

 

image05

 

Затем настроим Clock Configuration на 200 МГц следующим образом (нажмите на картинку для увеличения изображения)

 

image07_0500

 

Включим ножку PI1, управляющую зелёным светодиодом, на выход.

Писать мы будем программу, которая будет сначала писать определённые данные. начиная с определённого адреса в SDRAM, а затем читать их оттуда же в массив. А смотреть считанные данные будем через USART.

Я думаю, многие знают, но не все. В плате F746-DISCO интерфейсом USART можно пользоваться прямо через порт программирования ST-Link, не подключая при этом никаких дополнительных переходников. Самое главное — правильно его сконфигурировать в Cube MX.

Включим там USART1

 

image08

 

Посмотрим на картинке контроллера, какие же ножки нам автоматически подключил в качестве USART генератор Cube MX

 

image09

 

Эти ножки — PB7 в качестве RX и PB6 в качестве TX.

Проверим на схеме, так ли это

 

 

image10

 

Как мы видим, RX у нас правильный. а TX — нет. Поэтому переопределим его на PA9.

И такая вот ситуация сплошь и рядом. То же самое будет и при включении FMC и LTDC.

Ну, скорее всего, Cube MX и не обязан знать, на какие у нас контакты и что задействовано в схеме отладочной платы. Мы же выбрали не плату, а контроллер. Многие советуют выбирать плату, но мне это не нравится. Всё желтое и зелёное, свободных ножек нет вообще и, наоборот, начинаешь думаль, что же отключить. Поэтому лучше будем иногда поглядывать в схему.

Вообщем с USART разобрались

 

image11

 

Теперь разберёмся с самим контроллером.

Зайдём в Configuration и откроем там CORTEX M7. Включим первым делом кэш

 

image12

 

Далее регионы доступа

 

image13

 

Теперь FMC.

 

image14

 

Мы видим, что у нас включилось очень много ножек и очень много их согласно схеме также будет переопределено, поэтому, я напишу список, какие должы быть включены ножки для FMC и в каком качестве, а то мало ли, может к кого-то включатся вообще другие. Мы уже знаем какие ножки за что отвечают, поэтому нам уже проще будет понимать распиновку.

Также подсказкой будет служить таблица 10 в User Manual

 

image15

 

Из неё мы всё и соберём

 

Pin Pin Name Signal or Label
A5 PE1 FMC_NBL1
A6 PE0 FMC_NBL0
B7 PG15 FMC_SDNCAS
B12 PD0 FMC_D2
C12 PD1 FMC_D3
D2 PF0 FMC_A0
E2 PF1 FMC_A1
G2 PF2 FMC_A2
H2 PF3 FMC_A3
H14 PG8 FMC_SDCLK
J2 PF4 FMC_A4
J3 PH5 FMC_SDNWE
J4 PH3 FMC_SDNE0
K3 PF5 FMC_A5
K13 PD15 FMC_D1
K15 PD10 FMC_D15
L4 PC3 FMC_SDCKE0
L12 PD14 FMC_D0
L14 PD9 FMC_D14
L15 PD8 FMC_D13
M6 PF12 FMC_A6
M7 PG1 FMC_A11
M8 PF15 FMC_A9
N6 PF13 FMC_A7
N7 PG0 FMC_A10
N9 PE8 FMC_D5
N12 PG4 FMC_BA0
P6 PF14 FMC_A8
P8 PF11 FMC_SDNRAS
P9 PE9 FMC_D6
P10 PE11 FMC_D8
P11 PE14 FMC_D11
R8 PE7 FMC_D4
R9 PE10 FMC_D7
R10 PE12 FMC_D9
R11 PE15 FMC_D12
R12 PE13 FMC_D10

 

Вот по такой схеме и переопределяем контакты.

 

 

Теперь настроим наш FMC на вкладке Configuration

 

image16

 

Здесь всё согласно документации. Мы прибавили латентность на шину включении адресации колонки, добавили ещё один такт на команды, включили BRUST (режим пакетной передачи данных) на чтение, а также настроили тайминги.

Настроим проект, назвав его FMC_SDRAM, выбрав Keil 5 в качестве среды, а также увеличим в 10 раз стек и кучу

 

image17

 

Вообщем-то с Cube MX пока всё.

Сгенерируем проект, откроем его в Keil, настроив программатор на авторезет.

Сначала напишем несложный тест в main() в бесконечном цикле, чтобы проверить зеленый светодиод

 

    /* USER CODE BEGIN 3 */

    HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_RESET);

    HAL_Delay(500);

    HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_SET);

    HAL_Delay(500);

  }

  /* USER CODE END 3 */

 

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

Теперь проверим USART

Подключим файл в main.c

 

/* USER CODE BEGIN Includes */

#include "string.h"

 

В main() создадим небольшой строковый буфер

 

  /* USER CODE BEGIN 1 */

 char str1[20]={0};

  /* USER CODE END 1 */

 

Добавим код в бесконечный цикл

 

  HAL_Delay(500);  }

  sprintf(str1,"Ok!rn");


  HAL_UART_Transmit(&huart1, (uint8_t*)str1,strlen(str1),0x1000);

 

Запустим терминальную программу, настроим её на 115200 с одним стоповым битом и нажмем Connect.

Затем соберем код, прошьём контроллер и посмотрим в терминал

 

image19

 

Всё нормально отправляестя.

Теперь займёмся памятью SDRAM.

Частично память у нас уже была инициализирована в Cube MX.

Продолжим инициализацию дальше.

Создадим два файла MT48LC4M32B2.c и MT48LC4M32B2.h обычным способом

 

Заголовочный файл подключим к main.c и к MT48LC4M32B2.c

 

/* USER CODE BEGIN Includes */

#include "MT48LC4M32B2.h"

#include "string.h"

 

#include "MT48LC4M32B2.h"

 

В данный заголовочный файл добавим макросы для конфигурирования и обращения к памяти SDRAM, взяв их из примера, ну и также подключим туда библиотеку HAL.

В результате файл будет таким

 

#ifndef __MT48LC4M32B2_H

#define __MT48LC4M32B2_H

//————————————————

#include "stm32f7xx_hal.h"

//————————————————

#define SDRAM_TIMEOUT     ((uint32_t)0xFFFF)

#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)

#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)

#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)

#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)

#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)

#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)

#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)

#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)

#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)

#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)

#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)

//————————————————


#endif /* __MT48LC4M32B2_H */

 

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

 

image16

 

Светодиод у нас мигает как положено раз в секунду.

Дальнейшую работу с проектом мы отложим до следующей части нашего занятия

 

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

 

Техническая документация на микросхему SDRAM MT48LC4M32B2

 

 

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

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM32 FMC SDRAM

8 комментариев на “STM Урок 62. FMC SDRAM. Часть 2
  1. Георгий:

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

      

  2. Денис:

    Необходимо исправить в таблице PF9 на PF0 (см. Pin № D2)

  3. Игорь:

    Спасибо автору за статью, но не мог бы автор более подробно расписать настройку таймингов SDRAM? Откуда берутся магические цифры 2 6 4 6 2 2 2? Ясно, что из даташита, но из какой таблицы и как эти параметры там могут обзыватся? Заранее спасибо за ответ.

    • В принципе, в технической документации на любую память все эти тайминги есть. Я просто физически не смогу разжевать каждую циферку, уж простите великодушно. Поэтому, думаю, всё это несложно освоить самостоятельно.

  4. Вадя:

    Разве BURST_LENGTH_8 не должен быть 3, а не 4?

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

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

*