About STM32

ЖКИ stm32

Не так давно я рассказывал о знакогенерирующих индикаторах на основе контроллера HD44780, настало время использовать их на практике.

Как уже говорилось, для моих опытов был выбран ЖКИ Winstar WH0802, который способен отображать 2 строки по 8 символов.

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

Перед тем, как приступить к непосредственному написанию кода необходимо подключить дисплей к stm32. Я сделал это так:
линиия данных ( D4-D7 ) подключена к порту С на пины 0-3 соответственно.
команды подключены к порту А, где RS - 0 пин, E - 1 пин.

О том, как подключен дисплей я указал дефайнами в начале программы:

#define LCD_DATA_PORT GPIOC->ODR
#define LCD_COM_PORT GPIOA->ODR
#define LCD_D4 (1<<0)
#define LCD_D5 (1<<1)
#define LCD_D6 (1<<2)
#define LCD_D7 (1<<3)
#define LCD_E (1<<0)
#define LCD_RS (1<<1)

Для того, чтобы управлять ЖКИ необходимо написать 2 небольшие функции: послыка данных и посылка команды. Главное отличие этих функции - это состояние выводы RS во время формирования данных. Смотрим:

void lcd_com(unsigned char data)
{
LCD_COM_PORT&=~LCD_RS;//опускаем в ноль вывод RS
LCD_DATA_PORT&=~(LCD_D4|LCD_D5|LCD_D6|LCD_D7); //очищаем линию данных
//выставляем сигналы левой половины команды
if ((data&(1<<7))!=0) LCD_DATA_PORT|=LCD_D7;
if ((data&(1<<6))!=0) LCD_DATA_PORT|=LCD_D6;
if ((data&(1<<5))!=0) LCD_DATA_PORT|=LCD_D5;
if ((data&(1<<4))!=0) LCD_DATA_PORT|=LCD_D4;
//подаем стробирующий сигнал
LCD_COM_PORT|=LCD_E;
delay_us(2);
LCD_COM_PORT&=~LCD_E;
delay_us(10);
//повторяем операцию для правой половины команды
LCD_COM_PORT&=~LCD_RS;
LCD_DATA_PORT&=~(LCD_D4|LCD_D5|LCD_D6|LCD_D7);
if ((data&(1<<3))!=0) LCD_DATA_PORT|=LCD_D7;
if ((data&(1<<2))!=0) LCD_DATA_PORT|=LCD_D6;
if ((data&(1<<1))!=0) LCD_DATA_PORT|=LCD_D5;
if ((data&(1<<0))!=0) LCD_DATA_PORT|=LCD_D4;
LCD_COM_PORT|=LCD_E;
delay_us(2);
LCD_COM_PORT&=~LCD_E;
if (data==1) delay_ms(2); else delay_us(45);
}

void lcd_dat(unsigned char data)
{
//все точно так же как и для команды, только вывод RS устанавливаем в высокое состояние
LCD_COM_PORT|=LCD_RS;
LCD_DATA_PORT&=~(LCD_D4|LCD_D5|LCD_D6|LCD_D7);
if ((data&(1<<7))!=0) LCD_DATA_PORT|=LCD_D7;
if ((data&(1<<6))!=0) LCD_DATA_PORT|=LCD_D6;
if ((data&(1<<5))!=0) LCD_DATA_PORT|=LCD_D5;
if ((data&(1<<4))!=0) LCD_DATA_PORT|=LCD_D4;
LCD_COM_PORT|=LCD_E;
delay_us(2);
LCD_COM_PORT&=~LCD_E;
delay_us(10);
LCD_COM_PORT|=LCD_RS;
LCD_COM_PORT|=LCD_E;
LCD_DATA_PORT&=~(LCD_D4|LCD_D5|LCD_D6|LCD_D7);
if ((data&(1<<3))!=0) LCD_DATA_PORT|=LCD_D7;
if ((data&(1<<2))!=0) LCD_DATA_PORT|=LCD_D6;
if ((data&(1<<1))!=0) LCD_DATA_PORT|=LCD_D5;
if ((data&(1<<0))!=0) LCD_DATA_PORT|=LCD_D4;
LCD_COM_PORT|=LCD_E;
delay_us(2);
LCD_COM_PORT&=~LCD_E;
delay_us(40);
}

Следующий этап - инициализация. Алгоритм тупо выковыриваем из даташита на стр. 17. После вникания в суть происходящего пишем примерно следующий код:

void lcd_init()
{
delay_ms(40); //pauza po datashitu
lcd_com(40); //inicializacia
lcd_com(40);
lcd_com(12);
lcd_com(1);
delay_ms(2);
lcd_com(6);
}

Все! теперь можно печатать букавки!Выставив адрес для печати командой 0x80 и передав код символа из таблицы кодировки, например:

lcd_com(0x81);
lcd_dat('a');
lcd_dat('b');
lcd_dat('o');
lcd_dat('u');
lcd_dat('t');
lcd_com(0xC1);
lcd_dat('s');
lcd_dat('t');
lcd_dat('m');
lcd_dat('3');
lcd_dat('2');

И последнее. В этих ЖКИ есть возможность запрограммировать 8 своих символов. Размер программируемого символа совпадает с размером стандартного: высота 8 пикселей, ширина - 5 пикселей (при этом стараются делать символы высотой 7 пикселей, чтобы оставался межсимвольный интервел и символы не сливались между собой). Делается это посылкой команды 0x40 с последующей выдачей 8 байт данных символа. Например, для символа градус:

Байты которые надо выдать после команды записи символа 0x40: 7,5,7,0,0,0,0,0, где первое число (в данном случае 7) - код верхней строки и означает: 0b00000111 т.е. 1 - пиксель закрашен, 0 - пиксель не закрашен. Вторая цифра - код второй строки и т.д.
Код кдля записи этого символа в ЖКИ:

unsigned char i,s[8]={7,5,7,0,0,0,0,0};//i - переменная-счетчик, s - массив с кодом символа
lcd_com(0x40);//отправляем команду на запись символа
for (i=0;i<8;i++)//в цикле выдаем 8 байт данных массива s
lcd_dat(s[i]);


Проект в Keil lcd.rar.

 
Хостинг от uCoz