STM32 и FSMC. Часть 1. Подключение и настройка дисплея.

Пришло время обсудить замечательную плюшку микроконтроллеров STM32 – а именно модуль FSMC. Это практически незаменимая вещь при работе с внешней памятью, либо, например, с графическим дисплеем. Собственно, с дисплеем то мы и будем играться, разбираясь с FSMC.

Но для начала, как обычно, немного теории. Итак, FSMC реализует параллельный интерфейс обмена данными между различными устройствами. Короче говоря — просто параллельная шина. Используя FSMC при работе с внешней памятью, мы получаем возможность включить внешнюю память в адресное пространство микроконтроллера.

Что это дает? А то, что обращение к внешней памяти значительно упрощается — необходимо просто обращаться к ОЗУ микроконтроллера по определенным заданным адресам. То есть все ритуальные танцы с временными диаграммами, таймингами и прочим модуль FSMC берет на себя. Мы просто пишем данные по адресу — а FSMC дергает линии данных, полностью осуществляя непосредственную работу с подключаемым устройством.

Схожим образом работает все это дело и при подключении дисплеев. Но все-таки тут все несколько иначе. Пусть у нас есть дисплей, у которого есть следующие выводы:

  • DB[17:0] – 18 линий для передачи данных (не забываем, что тут у нас параллельная передача данных, а не последовательная).
  • Также есть выводы для разрешения записи/чтения — туда мы должны выдавать строб-импульсы в определенной последовательности.
  • Кроме того, у дисплея есть выводы chip select’а, reset и т. д.

И всем этим хозяйством нужно рулить 🙂 Вот тут то нам и поможет FSMC. И не просто поможет, а всю работу возьмет на себя! Итак, пусть мы уже подключили дисплей как надо, написали программу для FSMC STM32. Как же нам обращаться с дисплеем то? А опять все очень просто. Точно также, как с внешней памятью, мы будем всего лишь пихать байты по определенному адресу. А FSMC будет в это время лихорадочно дергать линиями данных, следить за временными интервалами, передавать все остальные нужные дисплею сигналы. А чтобы разделить передачу данных и команд мы должны записывать байты по разным адресам. И тут же встает вопрос – а какие именно адреса, и чем они определяются.

У дисплея есть вывод для выбора — данные/команда. То есть по состоянию этого вывода дисплей решает, что именно сейчас к нему прилетит. А у FSMC есть шина адреса и шина данных. Так вот этот вывод дисплея подключается к какому-нибудь пину шины адреса. И если мы подключили его, например, к 16 выводу шины адреса, то записав какой-нибудь байт по любому(!) адресу с нулевым 16 битом мы подадим дисплею команду. Вот, смотрите, пример небольшой.

Пусть как уже решили подключен 16 бит шины адреса. Берем адрес из доступных FSMC – 0x60000000. Видим, что в этом значении 16 бит равен нулю, а значит, когда мы запишем значение по этому адресу, FSMC подаст дисплею сигнал на запись, также сообщит дисплею, что сейчас будет команда, ну и, конечно же, выдаст на шину сами данные. А если мы запишем значение по адресу 0х60010000 (16 бит — единица!) то FSMC все разрулит и передаст дисплею данные. Вот так все просто!

Кстати, очень важный момент. В 16-битном режиме работы FSMC 16 бит шины адреса соответствует 17-му биту адреса (то есть 0х60020000). Ну естественно, все остальные адреса также смещены на 1 бит в этом режиме.

По идее работа с дисплеем и с внешней памятью с точки зрения программиста выглядит одинаково, но на деле все не так. При работе с дисплеем никакая память никуда не «проецируется», мы условно пишем данные по адресам, но это всего лишь дает FSMC сигнал о том, что пора начинать действовать 🙂 Давайте переходить к делу.

Для работы с FSMC будем по традиции использовать Standard Peripheral Library. Там все аналогично любой другой периферии, разве что настроек побольше. Так что об этом не будем особо разговаривать — лучше на практике при написании программы посмотрим как и что там конфигурируется.

Итак, что у нас в плане железа… Испытывать FSMC я буду при помощи платы MiniSTM32 (про нее была уже статейка). Там уже установлен дисплей, так что никаких лишних телодвижений не потребуется. Вот как дисплей подключен:

Подключение дисплея к STM32 по интерфейсу FSMC.

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

Итак, что же будем делать-то в качестве примера… Давайте разберемся как окрашивать дисплей в определенный цвет. Сначала зальем экран красным, потом зеленым и потом синим (RGB). Короче получить мы должны мигающий дисплей, на котором три цвета сменяют друг друга.

Данные будем передавать в 16-битном режиме.

Передача данных цвета по FSMC.
  • Красному цвету соответствует – 111111 000000 000000.
  • Зеленому – 000000 111111 000000.
  • Синему – 000000 000000 111111.

Как мы тут видим на 18 бит цвета приходятся 16 бит данных, в итоге получаем следующее:

  • Для красного – 0xF800.
  • Для зеленого – 0x07E0.
  • Для синего – 0x001F.

Все очень просто, давайте напишем программу. Сразу скажу, шаманская инициализация дисплея взята из кошмарных китайских примеров программ, которые шли вместе с платой 🙂

/***************************************************************************************/
#include "stm32f10x_gpio.h"
#include "stm32f10x_fsmc.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x.h"


/***************************************************************************************/
// Определяем адреса, по которым будем записывать данные
// Для записи данных
#define LCD_DATA                                                 ((uint32_t)0x60020000)

// Для записи команд
#define LCD_REG                                                  ((uint32_t)0x60000000)


/***************************************************************************************/
// Простенькая функция задержки
// Для того, чтобы не нагружать пример здесь задержка сделана просто циклом,
// но в "боевых" проектах, конечно же, всегда нужно использовать для этого таймеры
void delay(uint32_t delayTime)
{
	uint32_t i;
	for(i = 0; i < delayTime; i++);
}


/***************************************************************************************/
// Так мы будем писать команды в регистры LCD
void writeLCDCommand(unsigned int reg,unsigned int value)
{
	*(uint16_t *) (LCD_REG) = reg;
	*(uint16_t *) (LCD_DATA) = value;
}


/***************************************************************************************/
// А так данные
void writeLCDData(unsigned int data)
{
	*(uint16_t *) (LCD_DATA)= data;
}


/***************************************************************************************/
void initAll()
{
	FSMC_NORSRAMInitTypeDef fsmc;
	FSMC_NORSRAMTimingInitTypeDef fsmcTiming;
	GPIO_InitTypeDef gpio;

	// Включаем тактирование портов
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE , ENABLE);
	// И тактирование FSMC
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

	// Инициализация пинов, задейстованных в общении по FSMC
	gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15; 
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &gpio);

	gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOE, &gpio);

	gpio.GPIO_Mode = GPIO_Mode_Out_PP;
	gpio.GPIO_Pin = GPIO_Pin_6;
	GPIO_Init(GPIOD, &gpio);

	// Здесь у нас Reset
	gpio.GPIO_Pin = GPIO_Pin_1;
	GPIO_Init(GPIOE, &gpio);

	// CS 
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOD, &gpio);

	// RS 
	gpio.GPIO_Pin = GPIO_Pin_11;
	GPIO_Init(GPIOD, &gpio);

	// CS -> 1
	// Reset -> 0
	// RD -> 1
	// RW -> 1

	GPIO_SetBits(GPIOD, GPIO_Pin_7);
	GPIO_ResetBits(GPIOE, GPIO_Pin_1);
	GPIO_SetBits(GPIOD, GPIO_Pin_4);
	GPIO_SetBits(GPIOD, GPIO_Pin_5);
 
	// Настройка FSMC
	fsmcTiming.FSMC_AddressSetupTime = 0x02;
	fsmcTiming.FSMC_AddressHoldTime = 0x00;
	fsmcTiming.FSMC_DataSetupTime = 0x05;
	fsmcTiming.FSMC_BusTurnAroundDuration = 0x00;
	fsmcTiming.FSMC_CLKDivision = 0x00;
	fsmcTiming.FSMC_DataLatency = 0x00;
	fsmcTiming.FSMC_AccessMode = FSMC_AccessMode_B;

	fsmc.FSMC_Bank = FSMC_Bank1_NORSRAM1;
	fsmc.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
	fsmc.FSMC_MemoryType = FSMC_MemoryType_NOR;
	fsmc.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
	fsmc.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
	fsmc.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	fsmc.FSMC_WrapMode = FSMC_WrapMode_Disable;
	fsmc.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	fsmc.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
	fsmc.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
	fsmc.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
	fsmc.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
	fsmc.FSMC_ReadWriteTimingStruct = &fsmcTiming;
	fsmc.FSMC_WriteTimingStruct = &fsmcTiming;

	FSMC_NORSRAMInit(&fsmc);
	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}


/***************************************************************************************/
void initLCD()
{
	// Глобальный Reset дисплея
	GPIO_ResetBits(GPIOE, GPIO_Pin_1);
	delay(0x0FFFFF);
	GPIO_SetBits(GPIOE, GPIO_Pin_1);
	delay(0x0FFFFF);
 
	// Пляски с бубном от китайских товарищей
	writeLCDCommand(0x0000,0x0001);
	delay(10);

	writeLCDCommand(0x0015,0x0030);
	writeLCDCommand(0x0011,0x0040);
	writeLCDCommand(0x0010,0x1628);
	writeLCDCommand(0x0012,0x0000);
	writeLCDCommand(0x0013,0x104d);
	delay(10);
	writeLCDCommand(0x0012,0x0010);
	delay(10);
	writeLCDCommand(0x0010,0x2620);
	writeLCDCommand(0x0013,0x344d);
	delay(10);

	writeLCDCommand(0x0001,0x0100);
	writeLCDCommand(0x0002,0x0300);
	writeLCDCommand(0x0003,0x1030);
	writeLCDCommand(0x0008,0x0604);
	writeLCDCommand(0x0009,0x0000);
	writeLCDCommand(0x000A,0x0008);

	writeLCDCommand(0x0041,0x0002);
	writeLCDCommand(0x0060,0x2700);
	writeLCDCommand(0x0061,0x0001);
	writeLCDCommand(0x0090,0x0182);
	writeLCDCommand(0x0093,0x0001);
	writeLCDCommand(0x00a3,0x0010);
	delay(10);

	// Настройки гаммы
	writeLCDCommand(0x30,0x0000);
	writeLCDCommand(0x31,0x0502);
	writeLCDCommand(0x32,0x0307);
	writeLCDCommand(0x33,0x0305);
	writeLCDCommand(0x34,0x0004);
	writeLCDCommand(0x35,0x0402);
	writeLCDCommand(0x36,0x0707);
	writeLCDCommand(0x37,0x0503);
	writeLCDCommand(0x38,0x1505);
	writeLCDCommand(0x39,0x1505);
	delay(10);

	// Включение дисплея
	writeLCDCommand(0x0007,0x0001);
	delay(10);
	writeLCDCommand(0x0007,0x0021);
	writeLCDCommand(0x0007,0x0023);
	delay(10);
	writeLCDCommand(0x0007,0x0033);
	delay(10);
	writeLCDCommand(0x0007,0x0133);
}


/***************************************************************************************/
int main()
{
	initAll();
	initLCD(); 
 
	while(1)
	{
		int i;

		// Начальный и конечный адреса по горизонтали
		writeLCDCommand(0x0050, 0);
		writeLCDCommand(0x0051, 239);
		
		// Начальный и конечный адреса по вертикали
		writeLCDCommand(0x0052, 0);
		writeLCDCommand(0x0053, 319); 
 
		writeLCDCommand(32, 0);
		writeLCDCommand(33, 0);
		*(uint16_t *) (LCD_REG) = 34;

		// Красный
		for (i = 0; i < 76800; i++)
		{
			writeLCDData(0xF800);
		}		
		delay(0x0FFFFF);
		
		// Зеленый
		for (i = 0; i < 76800; i++)
		{
			writeLCDData(0x07E0);
		}		
		delay(0x0FFFFF);

		//Синий
		for (i = 0; i < 76800; i++)
		{
			writeLCDData(0x001F);
		}
		delay(0x0FFFFF);
	}
}


/***************************************************************************************/

Магическое число 76800 – количество точек дисплея (320 * 240) . Все остальное вроде бы понятно, с настройками FSMC тоже ясно, как всегда в SPL все поля структуры названы логично и адекватно их функции.

После прошивки программы в контроллер дисплей начинает исправно подмигивать. Чего, собственно, и добивались, так что на этом все, скоро попробуем залить в дисплей какое-нибудь изображение!

Поделиться!

Подписаться
Уведомление о
guest
71 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
Андрей
Андрей
7 лет назад

Имеется похожая плата с таким же процессором. При сборке примера из статьи Keil выдает ошибки:
.\Obj\lcd_01.axf: Error: L6218E: Undefined symbol FSMC_NORSRAMCmd (referred from main.o).
.\Obj\lcd_01.axf: Error: L6218E: Undefined symbol FSMC_NORSRAMInit (referred from main.o).
В чем может быть дело?

Андрей
Андрей
Reply to  Aveal
7 лет назад

Пример скомпилился, но дисплей к сожалению молчит. Сверю повнимательнее соответствие подключения. Хотя на Вашей схеме странности имеются…

MS24
MS24
6 лет назад

А какой контроллер у вас стоит на дисплее? у меня вот такая плата http://emproj.com/Alientek
Никак не могу понять какой там контроллер и где мне смотреть настройки для FSMC.

rus
rus
6 лет назад

А можно файлы проэкта получить?
Не могу понять, что за ошибки компиляции выдает компилятор
linking…
sdio.axf: Error: L6200E: Symbol __ARM_use_no_argv multiply defined (by sdio.o and main.o).
sdio.axf: Error: L6200E: Symbol __ARM_use_no_argv multiply defined (by sdcard.o and main.o).
sdio.axf: Error: L6200E: Symbol main multiply defined (by sdio.o and main.o).
sdio.axf: Error: L6200E: Symbol main multiply defined (by sdcard.o and main.o).
sdio.axf: Error: L6200E: Symbol writeBuffer multiply defined (by sdcard.o and sdio.o).
sdio.axf: Error: L6200E: Symbol readBuffer multiply defined (by sdcard.o and sdio.o).
sdio.axf: Error: L6200E: Symbol SDCardInfo multiply defined (by sdcard.o and sdio.o).
Target not created

Victor
Victor
6 лет назад

Здравствуйте!
на строку
FSMC_NORSRAMInitTypeDef fsmc;
Ругается…
test.c(24): error: #268: declaration may not appear after executable statement in block

Victor
Victor
6 лет назад

Еще ругается…
test.c(32): error: #20: identifier “RCC_AHBPeriph_FSMC” is undefined

Сергей
Сергей
6 лет назад

Хочу выразить огромную благодарность автору статьи. Для обучения – супер материал! У меня дисплейчик на контроллере ili9325, достаточно было поменять конфиг и таки заморгало разными цветами)

PSYcho
PSYcho
Reply to  Сергей
3 лет назад

Можете помочь с инициализацией ili9325? Есть рабочий пример?
Спасибо.

Heavy
Heavy
6 лет назад

Что-то я не понял. Как работает функции writeLCDCommand и writeLCDData ? Как данные из LCD_REG и LCD_DATA уходят в FSMC контроллер? Где связка?

Сергей
Сергей
6 лет назад

Попробовал запустить.
Зависает на строчке
*(uint16_t *) (LCD_DATA) = value;
на самой первой строчке инициализации. без нее проходит. При пошаговой отладке проходит по функци инициализации FSMC но регистры остаются пустыми (

Сергей
Сергей
6 лет назад
Сергей
Сергей
6 лет назад

Любобытно, но заработало послн того, как добавил строчку
fsmc.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
В инициализацию fsmc

Михаил
Михаил
6 лет назад

Код работает до отключения питания. Если выключить-включить, то загорается просто белый дисплей, а программатор перестает видеть чип.
Error: Flash driver function execute error
Пока не замкнешь BOOT0 на VCC, программатор не хочет стирать чип. Это проблема именно моего контроллера или она встречается у всех?
Плата такая же точно.

Михаил
Михаил
6 лет назад

Так это только в случае именно этого кода. Все остальные примеры и коды работают замечательно. Может ли быть битый флэш у микроконтроллера?

Михаил
Михаил
6 лет назад

Хм. Как ни странно, но заработало все после добавления этой строчки
fsmc.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
Волшебная строка какая-то)

Михаил
Михаил
6 лет назад

Интересно, а можно ли заменить этот контроллер на аналогичный только из 4й серии? Перепаять в плате например на stm32f429/439

Михаил
Михаил
6 лет назад

А вы не подскажете, как работать со шрифтами с данным дисплеем? Например с hd44780 можно было просто выводить текст командой lcd_out. а тут я не пойму порядок обращения к массиву шрифтов и вывода его на экран. Шрифты взяты от ST

Дмитрий
Дмитрий
6 лет назад

А можно подключить 2 устройства (скажем, память и дисплей, как с I2C) к одному контроллеру или тут 1 контроллер — одно устройство?

Denis
Denis
6 лет назад

Работаю в Keil с nor памятью в асинхронном мультиплексном режиме, настройки выставлял по мануалу, чтение проходит, но при записи уходит в прерывание HardFault_Handler, с чем это может быть связано?

masta
masta
5 лет назад

Добрый день, что означает данная строчка?
Это указатель типа, а что означает первая звездочка?
*(uint16_t *) (LCD_REG) = reg;

masta
masta
5 лет назад

То что LCD_REG – адрес понятно.
Почему две звездочки – вопрос?
Так было бы понятно
uint16_t * (LCD_REG) = reg;

masta
masta
5 лет назад

Разобрался!!!

Денис
Денис
5 лет назад

Добрый день!!! Подскажи пожалуйста что означает строчка
writeLCDCommand(32, 0);
writeLCDCommand(33, 0);
*(uint16_t *) (LCD_REG) = 34;
Интересует магическое число 34. В других местах тоже видел но чуть по другому LCD_REG_34. И еще в функции writeLCDCommand(32, 0); что за числа 32, 33. Как я понял эта первое число в функции должно быть код определенной команды и второе значение (например при инициализации writeLCDCommand(0x0012,0x0010);) а здесь получается другие числа?

HexChanger
HexChanger
5 лет назад

У меня все сразу скомпилировалось, но отображается некорректно: картинка еле-еле смахивает на оригинальную и все строки разлетелись по сторонам., т.е. показывает, но хрен знает что. Второй день думаю что там может быть не так? У меня контроллер STM32f103ZE, дисплей TFT LCD Ilitec 320х240. Причем я пробовал при разных цветовых палитрах, и поворачивал картинку перед преобразованием в массив – все равно показывает одну и ту же муть.

HexChanger
HexChanger
5 лет назад

У меня на дисплее шрифты работают нормально: и позиционирует, и окрашивает в любой цвет, правда алфавит только английский (с цифрами и знаками препинания), могу скинуть файлы

HexChanger
HexChanger
5 лет назад

У меня тоже подозрение что сам массив получается какой-то левый от той программы(Segger Bitmap converter for emWin, качнул с их сайта последнюю версию), причем у меня это мутное изображение еще и повторяется на дисплее, я так понял там 1000 причин может быть

HexChanger
HexChanger
5 лет назад

Попробовал, у меня со всеми изображениями так, но я зашел на сайт Segger-а и там было написано что есть формат DIB (device independed format) и он как раз для того чтобы картинка отображалась корректно на всех дисплеях. Еще может быть (но маловероятно), что дело в компиляторе, например у меня GCC кокосовский. Обычно я делал так: открывал сгенерированный файл, брал из него только сам массив и у себя в коде пробегал в цикле этот массив функцией записи в GRAM (естественно после инициализации lcd) . Отпишу если все таки получится, у меня от этого только интерес вырос)

HexChanger
HexChanger
5 лет назад

Aveal, я разобрался с дисплеем, хочу поделиться мыслями: в моем случае изображение было неправильным по 2 причинам:
Во-первых, у меня LCD работает на других настройках RGB палитры нежели в примере, т.е. при прорисовке изображения у меня даже цвета были не те (у меня палитра “565 red and blue swaped”).
Во-вторых, я пытался отобразить изображения произвольного размера (как правило меньшего) и из-за этого у меня разъезжались строки в разные стороны и было похоже буд-то у меня изображение плодится по оси Х (по оси Y все рисуется нормально) . Как я понял надо перед отрисовкой задать адресный диапазон для GRAM, в рамках которого я должен пробегать циклом, чего я не делал, а сразу пошел бегать в цикле. И получалось что по оси X (0..240) у меня растягивалось изображение во всю ширь экрана – вот откуда разъехавшиеся полосы. Но как задавать область прорисовки я пока думаю….

masta
masta
5 лет назад

Добрый день почему здесь не указывается режим и частота
// Здесь у нас Reset
gpio.GPIO_Pin = GPIO_Pin_1 ;
GPIO_Init(GPIOE, &gpio);

masta
masta
5 лет назад

Спасибо!!!

Jet-Fly
Jet-Fly
5 лет назад

Здравствуйте, Aveal! Скажите, возможно ли без особых сложностей подключить к STM32 ЖК панель с разрешением 1366×768 с интерфейсом LVDS?

WiseLord
WiseLord
5 лет назад

Из кода видно, что для отправки данных в параллельный порт дисплея используются: биты 0, 1, 4, 5, 6, 8, 9, 10, 14, 15 порта D и биты 7, 8, 9, 10, 11, 12, 13, 14, 15 порта E.

Каким волшебным образом эти биты выстраиваются в правильный порядок для отправки в параллельный порт дисплея? Куда, например, мапится на порт дисплея бит 14 порта D, а куда – бит 14 порта E?

Если мне, например, нужно использовать другие биты портов – где это перенастраивается?

WiseLord
WiseLord
Reply to  Aveal
5 лет назад

То есть, как я понял, это жёстко задано.
И если у меня плата с STM32 и плата с экраном стыкуются так, что (16 бит интерфейс) D0-D7 дисплея идут на PORTC(0..7), а D8..D15 – на PORTB(0..7) – то мне воспользоваться FSMC не судьба?

http://www.ebay.com/itm/-/400594146303 – вот такое чудо у меня из Китая.

Анатолий
Анатолий
4 лет назад

Добрый день!
Как всё это дело заставить работать на 8-битной шине?
Заранее спасибо!

Анатолий
Анатолий
4 лет назад

А как данные слать? Так же по 16бит, а FSMC будет сама их на пачки по 8 бит делить?

19den91
19den91
4 лет назад

кто подскажет как работает выбор чип селекта в FSMC, настраиваю на первый банк в режиме NOR

Marat
Marat
4 лет назад

Добрый день.
Непонятна работа функции, которая отправляет команду..
void writeLCDCommand(unsigned int reg,unsigned int value)
{
*(uint16_t *) (LCD_REG) = reg;
*(uint16_t *) (LCD_DATA) = value;
}

Что пишется в LCD_REG, а что в LCD_DATA?

Marat
Marat
4 лет назад

Спасибо.
У меня к STM подключен двухстрочный ЖК МЭЛТ, чтобы его инициализировать, надо отправить несколько команд.
Правильно понимаю, что команды можно отправить так:

*(uint16_t *) (LCD_REG) = 0x30;

LCD_REG определен как ((uint32_t)0x60000000)).

Alfis
Alfis
1 год назад

Программирую на STM32F407
Как правильно подключить pin FSMC и дисплея
pin FSMC есть выводы:
NOE, NE1, NWE и LCD Register Select пусть будет A16 ->PD11
Дисплей имеет:
1 CS1 L Select Segment 1 ~ Segment 64
2 CS2 L Select Segment 65 ~ Segment128
3 Vss 0V Ground
4 VDD 5.0V Supply voltage for logic
5 VO (Variable) Operating voltage for LCD
6 D/I H/L H: Data , L: Instruction
7 R/W H/L H: Read(MPU Module) , L :Write(MPU→ Module)
8 E H Enable signal
9 DB0 H/L Data bus line
10 DB1 H/L Data bus line
11 DB2 H/L Data bus line
12 DB3 H/L Data bus line
13 DB4 H/L Data bus line
14 DB5 H/L Data bus line
15 DB6 H/L Data bus line
16 DB7 H/L Data bus line
17 RST L Reset the LCM
18 VEE Negative Voltage Output
19 A Power supply for B/L(+)
20 K Power supply for B/L(-)

К каким пинам FSMC подключать E, RW, D/I(RS) и RST?
Или E, RW, D/I(RS) и RST дергать в программе, а NOE, NE1, NWE и A16 ->PD11 (LCD Register Select) к дисплею не подключаются?

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Июнь 2020
Пн Вт Ср Чт Пт Сб Вс
« Май    
1234567
891011121314
15161718192021
22232425262728
2930  

© 2013-2020 MicroTechnics.ru