MyTetra Share
Делитесь знаниями!
LCD44780 (1602)
Время создания: 10.01.2018 13:01
Раздел: Electronics - Microcontrollers - STM32 - HAL

Никаких специальных настроек в кьюбе делать не требуется (хорошим тоно делать задержки на таймерах, но это на будущее). Конфигурируем 6 портов на выход (4 линии данных, E и RS).

Линию RW можно не подключать, т.к. спокойно обходимся без чтения инфы из дисплея. Линия V0 подключена через подстроечный резистор 20k, контрастность выставляется пробным путем (она разная в зависимости от количества строк отображения). Подсветка через резистор 2.3k.


//lcd44780.c


#ifndef __LCD44780_C__

#define __LCD44780_C__


#include "stm32f4xx_hal.h"

#include "lcd44780.h"



void lcdDelay(void)

{

for(uint8_t i = 0; i < 255; ++i)

{}

}


void lcdInit(void)

{

//----------------------------------

// Start init

//----------------------------------

HAL_Delay(1000);

LCD_RS_CLR;

lcdDatClrSetE();

lcdSendNibble(0x30); //8 bit mode ON

HAL_Delay(5);

lcdSendNibble(0x30); //8 bit mode ON

HAL_Delay(1);

lcdSendNibble(0x30); //8 bit mode ON

HAL_Delay(1);

lcdSendNibble(0x20); //4 bit mode ON

HAL_Delay(1);


lcdSendCmnd(0x28); //4 bit mode ON, 2 lines

lcdSendCmnd(0x08); //display OFF

lcdSendCmnd(0x01); //clear display

lcdSendCmnd(0x06); //incr cursor position


HAL_Delay(1);

lcdSendCmnd(0x0C); //display ON without cursor

// lcdSendCmnd(0x0F); //display ON with cursor

HAL_Delay(1);

lcdSendCmnd(0x01); //clear display

}


void lcdSendNibble(const uint8_t cmnd)

{

// lcdDatClrSetE();

LCD_DAT_CLR;

LCD_E_SET;

lcdDelay();

if(cmnd & (1<<7)) LCD_D7_SET;

if(cmnd & (1<<6)) LCD_D6_SET;

if(cmnd & (1<<5)) LCD_D5_SET;

if(cmnd & (1<<4)) LCD_D4_SET;

lcdDelay();

LCD_E_CLR;

lcdDelay();

}


void lcdSendCmnd(const uint8_t cmnd)

{

lcdSendNibble(cmnd);

lcdSendNibble(cmnd<<4);

HAL_Delay(5);

}


void lcdSendCode(const uint8_t data)

{

LCD_RS_SET;

lcdSendCmnd(data);

LCD_RS_CLR;

}


void lcdSendData(const uint8_t data)

{

LCD_RS_SET;

lcdSendCmnd(data + LCD_ZERO); //+0x30

LCD_RS_CLR;

}


void lcdDatClrSetE(void)

{

LCD_DAT_CLR;

LCD_E_SET;

HAL_Delay(2);

}

#endif


Инициализируем по даташите следующими короткими инструкциями (передаем только старший ниббл):

  • 0x30
  • 4.1ms+ delay
  • 0x30
  • 1ms delay
  • 0x30
  • 1ms dealy
  • 0x20


Далее идут полноценные инструкции по 8 бит без задержек:

  • 0x28
  • 0x08
  • 0x01
  • 0x06


Инициализация закончена, можно включать дисплей и передавать данные.


//lcd44780.h


#ifndef __LCD44780_H__

#define __LCD44780_H__


//---LCD------------------------------------

#define LCD_SYSPORT GPIOB

#define LCD_RS GPIO_PIN_9

#define LCD_E GPIO_PIN_8


#define LCD_DATPORT GPIOD

#define LCD_D7 GPIO_PIN_7

#define LCD_D6 GPIO_PIN_6

#define LCD_D5 GPIO_PIN_3 //!!! PIN 3 !!!, not 5

#define LCD_D4 GPIO_PIN_4


#define LCD_RS_SET HAL_GPIO_WritePin(LCD_SYSPORT, LCD_RS, GPIO_PIN_SET)

#define LCD_RS_CLR HAL_GPIO_WritePin(LCD_SYSPORT, LCD_RS, GPIO_PIN_RESET)

#define LCD_E_SET HAL_GPIO_WritePin(LCD_SYSPORT, LCD_E, GPIO_PIN_SET)

#define LCD_E_CLR HAL_GPIO_WritePin(LCD_SYSPORT, LCD_E, GPIO_PIN_RESET)


#define LCD_D7_SET HAL_GPIO_WritePin(LCD_DATPORT, LCD_D7, GPIO_PIN_SET)

#define LCD_D7_CLR HAL_GPIO_WritePin(LCD_DATPORT, LCD_D7, GPIO_PIN_RESET)

#define LCD_D6_SET HAL_GPIO_WritePin(LCD_DATPORT, LCD_D6, GPIO_PIN_SET)

#define LCD_D6_CLR HAL_GPIO_WritePin(LCD_DATPORT, LCD_D6, GPIO_PIN_RESET)

#define LCD_D5_SET HAL_GPIO_WritePin(LCD_DATPORT, LCD_D5, GPIO_PIN_SET)

#define LCD_D5_CLR HAL_GPIO_WritePin(LCD_DATPORT, LCD_D5, GPIO_PIN_RESET)

#define LCD_D4_SET HAL_GPIO_WritePin(LCD_DATPORT, LCD_D4, GPIO_PIN_SET)

#define LCD_D4_CLR HAL_GPIO_WritePin(LCD_DATPORT, LCD_D4, GPIO_PIN_RESET)

#define LCD_DAT_CLR HAL_GPIO_WritePin(LCD_DATPORT, LCD_D4|LCD_D5|LCD_D6|LCD_D7, GPIO_PIN_RESET)


//positions

#define LCD_HOME 0x02

#define LCD_MONTH_POS 0x83

#define LCD_YEAR_POS 0x86

#define LCD_SECOND_LINE 0xC0

#define LCD_MIN_POS 0xC3

#define LCD_SEC_POS 0xC6


//commands

#define LCD_ON 0x0C

#define LCD_OFF 0x08


//symbols

#define LCD_ZERO 0x30

#define LCD_DOTS 0x0A

#define LCD_POINT 0x2E


void lcdInit(void);

void lcdSendCmnd(const uint8_t cmnd);

void lcdSendNibble(const uint8_t cmnd);

void lcdSendCode(const uint8_t data);

void lcdSendData(const uint8_t data);

void lcdDatClrSetE(void);


#endif


//main.c


/* USER CODE BEGIN 2 */

lcdInit();

lcdSendCmnd(0x01);

lcdSendCmnd(0x02);

/* USER CODE END 2 */


/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */


/* USER CODE BEGIN 3 */

lcdSendCmnd(0x01); //clear screen

lcdSendCmnd(0x02); //cursor home

for(uint8_t i = 0; i < 33; ++i)

{

if(i == 17)

{lcdSendCmnd(LCD_SECOND_LINE);}

lcdSendData(i);

}

HAL_Delay(3000); //delay for 3 seconds

}

/* USER CODE END 3 */








 
MyTetra Share v.0.53
Яндекс индекс цитирования