Автор: admin, 11 февраля, 2025
MDR32 Miluino и МЭЛТ МТ-16S2S
Краткое описание

Инициализация знакосинтезирующего дисплея 1602 от фирмы МЭЛТ по SPI (SSP) с помощью микроконтроллера Миландр К1986ВЕ92хх

Часть 1

Описание работы дисплея МЭЛТ МТ-16S2S.

Согласно технической документации на дисплей (режим доступа https://www.melt.com.ru/docs/MT-16S2S.pdf?ysclid=m708djocbj209679056) данная серия жидкокристаллических индикаторов обладает встроенным контроллеровм управления ST7070, содержит два вида памяти, память кодов отображаемых символов и пользовательского знакогенератора. Особенностью памяти кодов отображаемых символов является то, что она двухстраничная, и символы латинского и кириллического алфавита разнесены в разные страницы, что конечно может создать ряд неудобств при программировании мультиязычного режима на дисплее. 

Дисплей, согласно документации имеется возможность инициализации как по параллельной 4-х/8-ми разрядной шине данных, так и по последовательному однонаправленному синхронному интерфейсу SPI. 

 Статья как подключить данный дисплей к микроконтроллеру имеется на ресурсе habr.com (режим доступа https://habr.com/ru/articles/397977/), все желающие могут с ней ознакомится. Однако, в настоящей статье мы разберем детали, которые не были освящены в вышеупомянутых информационных ресурсах.

Схема подключения ЖК-индикатора МЭЛТ МТ-16S2S по SPI приведена на рисунке 1.

Рисунок 1. - Схема подключения ЖК-индикатора

Опишем последовательность инциализации:

  • XRES устанавливаем в Н уровень.
  • Ждем не менее 40 мс.
  • Устанавливаем в Н уровень CS
  • Производим инциализацию SPI на стороне микроконтроллера.
  • Готовим к инициализации дисплей по SPI. (CS (H), приемник выключен CS (L) приемник готов)
  • Передаем команду 0х38 // функция установки 0b00111000 согласно рисунку 10 официальной документации на дисплей, раздел "Последовательный интерфейс".
  • Производим очистку дисплея передав данные 0х01
  • Перемещаем курсор в начало командой 0х02
  • Производим включение дисплея
  • Завершаем настройки командой 0х38

Далее формируем блок передачи символов.

Часть 2

Программный код на языке Си для настройки функции инициализации дисплея по SPI

Рассмотрим код для формирования команды передачи данных на дисплей с микроконтроллера К1986ВЕ92FI, основная отладочная плата микроконтроллера будет использована MDR32 MILUINO для К1986ВЕ92FI ДФТВ.434519.003 в качестве платы дисплея используем MILUINO SHIELD LCD_16x2_MELT ДФТВ.467988.004.

 

Код инициализации SSP интерфейса на языке С:

#include "MDR32Fx.h"                    // Device header
#include "MDR32F9Qx_rst_clk.h"          // Keil::Drivers:RST_CLK
#include "MDR32F9Qx_port.h"             // Keil::Drivers:PORT
#include "MDR32F9Qx_ssp.h"              // Keil::Drivers:SSP

#define CS_Port                MDR_PORTF
#define CS_Bit                 PORT_Pin_2

#define SPI1_SCK_Pin      PORT_Pin_1
#define SPI1_MISO_Pin     PORT_Pin_3
#define SPI1_MOSI_Pin     PORT_Pin_0
#define SPI1_HFSS_Pin     PORT_Pin_2

void SSP1_Init(void)
{
    RST_CLK_PCLKcmd((RST_CLK_PCLK_RST_CLK | RST_CLK_PCLK_SSP1 | RST_CLK_PCLK_PORTF), ENABLE);
    
    SSP_InitTypeDef sSSP;
    PORT_InitTypeDef PORT_InitStructure;
    
    /* Конфигурируем пины SSP1: FSS, CLK, RXD, TXD */
 
    PORT_InitStructure.PORT_Pin   = SPI1_MISO_Pin;
    PORT_InitStructure.PORT_OE    = PORT_OE_IN;
    PORT_InitStructure.PORT_FUNC  = PORT_FUNC_ALTER;
    PORT_InitStructure.PORT_MODE  = PORT_MODE_DIGITAL;
    PORT_InitStructure.PORT_SPEED = PORT_SPEED_FAST;
    PORT_Init(MDR_PORTF, &PORT_InitStructure);

    PORT_InitStructure.PORT_Pin   = (SPI1_MOSI_Pin | SPI1_SCK_Pin); // FSS - SOFT
    PORT_InitStructure.PORT_OE    = PORT_OE_OUT;
    PORT_Init(MDR_PORTF, &PORT_InitStructure);
      
    SSP_DeInit(MDR_SSP1);
    SSP_BRGInit(MDR_SSP1, SSP_HCLKdiv16);
  
    /* Конфигурация SSP1 в режиме MASTER 8-битный режим */
 
    SSP_StructInit (&sSSP);

    sSSP.SSP_SCR        = 0x10;
    sSSP.SSP_CPSDVSR    = 8;
    sSSP.SSP_Mode       = SSP_ModeMaster;
    sSSP.SSP_WordLength = SSP_WordLength8b;
    sSSP.SSP_SPH        = SSP_SPH_2Edge;
    sSSP.SSP_SPO        = SSP_SPO_High;
    sSSP.SSP_FRF        = SSP_FRF_SPI_Motorola;
    sSSP.SSP_HardwareFlowControl = SSP_HardwareFlowControl_SSE;
    SSP_Init (MDR_SSP1, &sSSP);

    /* Запускаем SSP1 */
    SSP_Cmd(MDR_SSP1, ENABLE);    
}

Функции передачи и приема данных выглядит так:

uint16_t ReceiveTransmitSPI(uint8_t data)
{
   while (SSP_GetFlagStatus(MDR_SSP1, SSP_FLAG_TFE) == RESET) {}
   /* Передача данных по SPI1 */
   SSP_SendData(MDR_SSP1, data);
   /* Ждем пока SPI1 примет данные */
   while (SSP_GetFlagStatus(MDR_SSP1, SSP_FLAG_RNE) == RESET) {}
   /* Считываем принятые данные по SPI1 */
   return SSP_ReceiveData(MDR_SSP1);
}

Функция инициализации ЖКИ МЭЛТ МТ-16S2S

#define LCD_cmd_CUR_OFF		0x8000
#define LCD_cmd_CUR_ON		0x4000

#define LCD_cmd_DISP_OFF	0x2000
#define LCD_cmd_DISP_ON		0x1000

#define LCD_cmd_SetPage_0	0x0800
#define LCD_cmd_SetPage_1	0x0400

#define LCD_cmd_CUR_SHIFT	0x0200
#define LCD_cmd_DISP_SHIFT	0x0100

#define LCD_cmd_SHIFT_LEFT	0x0080
#define LCD_cmd_SHIFT_RIGHT	0x0040

#define LCD_cmd_Home		0x0002
#define LCD_cmd_ClrScr		0x0001

#define FIRST_LINE		0x0000
#define SECOND_LINE		0x0001

void LCD_Cmd(uint16_t cmd)
	{
		uint8_t toSend ;
		toSend = 0x08;
		CS_RESET;
		DELAY_US(90);
		ReceiveTransmitSPI(0x38); 
		DELAY_US(90); 
		//Очистка дисплея
		if ((cmd & LCD_cmd_ClrScr) > 0)
			{
				ReceiveTransmitSPI(0x01);
				DELAY_US(90); 
			}
		//Курсор в начало
		if ((cmd&LCD_cmd_Home) > 0)
			{
				ReceiveTransmitSPI(0x02);
				DELAY_US(90); 
			}
		// Включение
		if (cmd > 0x3ff)
			{ 
				toSend = toSend+((cmd & LCD_cmd_CUR_ON) >> 13) +     // курсор
				((cmd & LCD_cmd_DISP_ON) >> 10) +           // дисплей
				((cmd & LCD_cmd_SetPage_1) >> 10);         // кодовая страница 1                           
				ReceiveTransmitSPI(toSend);
				DELAY_US(90);
			}
	 
		cmd = cmd & 0x3ff;
		toSend = 0x10;
		// Сдвиг
		if (cmd > 0x3f)
			{  
				toSend += ((cmd & LCD_cmd_DISP_SHIFT) >> 5)+        // Сдвиг дисплея
				((cmd & LCD_cmd_SHIFT_RIGHT) >> 4);       // вправо 
				ReceiveTransmitSPI(toSend); 
				DELAY_US(90);
			};
		ReceiveTransmitSPI(0x38); 
		DELAY_US(90);
		CS_SET; 
}

Функция вывода текста на экран

void LCD_print_text(uint8_t line, char* text, uint8_t cell)
{
		uint8_t nBytes;
		if (!text) return;
			nBytes  = strlen(text);
		if (nBytes>80) return;
		
		CS_RESET;
		DELAY_US(90);

		if(line == FIRST_LINE)
		{
			ReceiveTransmitSPI(0x80 + cell);
		}
		else if (line == SECOND_LINE)
		{
			ReceiveTransmitSPI(0xC0 + cell);
		}
		DELAY_US(90);
		ReceiveTransmitSPI(0x3c); 
		DELAY_US(90);
		ReceiveTransmitSPI(0x80 + nBytes - 1); 
		DELAY_US(90);
		
		for(uint8_t j=0; j < nBytes; j++)
			{
				ReceiveTransmitSPI(text[j]); 
				DELAY_US(90); 
			};
		ReceiveTransmitSPI(0x38); 
		DELAY_US(90);
		CS_SET;
}

Таким образом мы настроили все функции передачи текстовых данных на латинице на знакосинтезирующий дисплей МЭЛТ от микроконтроллера фирмы Миландр

Дополнительные файлы