Работа с контроллером LCD

Сегодня мы разберемся как работать с контроллером LCD в STM8L. Он встречается только в старших моделях серии, а точнее — в STM8L152 и STM8L162. Присутствует в МК на STM8L-Discovery вместе с неопознаной LCD стекляшкой.

В качестве примера будет программа, которая просто выводит на дисплей надпись и при нажатии на кнопку (user button — пин C1) переключает аппаратную мигалку дисплея.



Контроллер LCD берет на себя работу по генерации управлющих сигналов для стекляшки. Мы должны только настроить его и запихнуть в LCD RAM нужные данные, соответствующие пикселям (сегменты, точки, ect) на дисплее. Особо примечательным является тот факт, что контроллер может работать, когда МК находится в спящем (active-halt) режиме. Это используется в моем термометре, который большую часть времени спит и показывает данные на ЖК, потребляя при этом всего 7мкА.

В разных МК количество разрядов (COM) и сегментов (SEG) различается. Например тот камушек, что стоит в STM8L-Discovery может рулить четырьмя разрядами, по 28 сегментов на каждом. Ненужные сегменты или разряды можно отключать от контроллера LCD и юзать как обычные GPIO.

Посмотрим, как настроить контроллер на примере дисплея в STM8L-Discovery.

Для начала нужно подать на него тактирование. Контроллер LCD тактируется от двух источников — для работы с регистрами используется SYSCLK а для генерации управляющих сигналов — часы RTC/2.
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE); 
 CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);


Здесь мы подали тактовый сигнал на LCD и переключили RTC на внутренний RC генератор (LSI) без предделителя.

Теперь выберем, какие пины будут использоваться контроллером LCD. Для этого существуют регистры LCD_PM (Port mask). В различных моделях МК этих регистров от 3 до 6. При записи 1 в бит этого регистра, соответствующий сегмент будет использоваться ЖК-контроллером. Соответствие сегментов ножкам МК можно проверить в даташите на конкретный МК (страничка с распиновкой).
Я использую все сегменты, поэтому записываю 0xFF во все три регистра:

LCD->PM[0] = 0xFF; 
 LCD->PM[1] = 0xFF;
 LCD->PM[2] = 0xFF;


Теперь надо настроить частоту работы ЖК контроллера. Для этого служит регистр LCD_FRQ. Он поделен на две части — prescaller (старшая половина байта) и divider (младшая). Частота после делителя определяется такой формулой:



Через регистр LCD_CR1 можно настроить заполнение (duty ratio) — это количество общих (common) пинов, которые будут использоваться. Неиспользуемые пины можно юзать как GPIO. Максимальное количество общих пинов — 4 в medium density и 8 в high density устройствах.
Я буду использовать все 4 пина, поэтому выбираю заполнение = 1/4. Для этого в биты DUTY[1:0] запишу число 3. Частота обновления дисплея зависит от заполнения.



Контроллер ЖК содержит встроенную мигалку. Она поддерживает разные частоты и режимы мигания дисплея. Например можно настроить её так, чтобы мигал один пиксель или все пиксели, подключенные к одному сегменту. К сожалению выбрать какой именно пиксель будет мигать мы не можем. Это в любом случае будет SEG0 COM0 (нулевой сегмент на нулевом разряде). Либо, можно заставить мигать весь дисплей целиком.
Биты BLINKF[2:0] задают частоту мигания. Её реальное значение зависит от частоты на которой работает контроллер дисплея.



В моей программе мигалка настроена на мигание всем дисплеем с частотой 2 Гц.

В регистре CR2 есть биты PON[2:0]. Их значение показывает, на какой период времени контроллер будет включать низкоомный драйвер.

Бит HD включает низкоомный драйвер (300кОм) на все время работы для руления дисплеями с большим внутренним сопротивлением.

У меня низкоомный драйвер работает постоянно. О потреблении в тестовой программе все-равно можно не заботиться.

Биты СС[3:0] отвечают за контрастность изображения. Очевидно, что при большей контрастности ток потребления тоже увеличится. В моей программе контраст установлен на предпоследнем значении, т.е. почти самый высокий.

Бит VSEL отвечает за выбор источника напряжения для LCD. Я оставил внутренний.

Включается вся эта шарманка установкой бита LCDEN в регистре CR3.

Там-же лежат биты отвечающие за настройку прерывания. Оно возникает перед отрисовкой нового кадра. Честно говоря не знаю, как можно использовать прерывание от LCD, поэтому про него не пишу.

Биты DEAD[2:0] отвечают за настройку deadtime. Если дедтайм отключен (все биты = 0), то при большом угле обзора будут заметны «лишние сегменты». С другой стороны, установка слишком большого значения приводит к уменьшению контрастности. В моей тестовой программе deadtime = 2.

Далее идет LCD RAM, каждый бит которой соответствует определенному пикселю на дисплее. Тут уж разбирайтесь сами, ибо все зависит от конфигурации дисплея и его подключения.

Сама демонстрационная программа выглядит вот так:

#include "stm8L15x.h"
#include "stm8L15x_clk.h"
#include "stm8L15x_gpio.h"

const uint8_t lcd_ram[6] = {0xFF, 0xAF, 0xEB, 0x70, 0x1F, 0x0C};
uint8_t counter;

void main( void )
{
  
 GPIOC->CR1 |= GPIO_Pin_1; //Подтяжку на кнопку
  
 CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); //Выключаем предделитель. Теперь МК работает на частоте 16МГц.
 CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE); //Подаем тактовый сигнал на LCD.
 CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE); //Подаем такт на RTC
 CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1); //Убираем прескллер RTC
 
 LCD->CR1 = (3<<1) + (5<<3); //Duty = 1/4, Blink Freq = LCDclk/256
 LCD->CR2 = (6<<1) | LCD_CR2_HD; //Контрастность = 6 (из 7), низкоомный драйвер.
 LCD->FRQ = (2<<4); //LCDclk = 32768/2/(2^1*16) = 512Hz
 //Задействованы все сегменты:
 LCD->PM[0] = 0xFF; 
 LCD->PM[1] = 0xFF;
 LCD->PM[2] = 0xFF;
 LCD->CR3 |= LCD_CR3_LCDEN | 2; //ВКЛ и deadtime = 2 

 //Перегоняем массив в LCD RAM
 for (counter=0; counter<6; counter++) LCD->RAM[counter] = lcd_ram[counter]; 
   
   
  
 while(1)
 {
  while ((GPIOC->IDR & GPIO_Pin_1) != 0); //Ждем, пока нажмут кнопку
   LCD->CR1 ^= 0xC0; //Инвертируем биты, отвечающие за мигалку
  while ((GPIOC->IDR & GPIO_Pin_1) == 0); //Теперь ждем, пока кнопку отпустят
 };  
}


В архиве лежит проект для IAR.
ВНИМАНИЕ!!! Перед компиляцией проекта надо зайти в его настройки, пункт С/С++ Compiler -> Preprocessor и там поменять пути поиска подключаемых файлов, на те, где у вас папки inc и src в проекте.

Аппноут от ST про работу с контроллером LCD.

  • +16
  • 31 июля 2011, 23:13
  • dcoder
  • 1
Файлы в топике: LCD.zip

Комментарии (77)

RSS свернуть / развернуть
Здорово, спасибо за статью и пример.

7 мкА — это реальное получившееся потребление? Очень хорошо! Дисплей с контроллером у меня потреблял около 20. Несколько лет от одной дисковой батарейки.
Где бы еще найти подходящих дисплеев по нормальной цене.
0
  • avatar
  • ACE
  • 31 июля 2011, 23:41
Да, от 6 до 8 мкА при разных настройках контраста. МК был в спящем (active-halt) режиме. Кроме дисплея работали RTC — они будили МК раз в несколько сек.

Немного про то, где достать дисплеи обсуждалось в комментах вот тут.
0
Спасибо за статью.

P.S.: при чтении нехватало несколько ьпблиц даташитов по описываемым регистрам «что бы всё в одном окне».
0
Пожелание принял, запилим.
0
Вопросец:
Я смотрю, народ плюсует. Значит подобные коротенькие статьи по работе с периферией в STM8 нужны?
0
Мне тут наиболее интересны 2 аспекта: низкое энергопотребление и то, что нельзя или не так эффективно реализовать на AVR'ках. Помимо прямого управления LCD у STM интересен ещё, к примеру, DAC.
0
Низкое потрбление это несомненный вин всей L серии. О способах снижения потребления напишу в близжайшее время.

Довольна большая часть периферии у стм8 отличается от авр. По функционалу или настройкам. поэтому писать думаю надо про все. Статьи про периферию будут короткими с простыми примерами — типа этой.

И еще, по ходу дела буду вбрасывать статьи про готовые устройства на STM8.

Вот такие планы.

DAC, кстати уже был описан тут.
0
Про готовые устройства поподробнее, пожалуйста.
0
На данный момент доделываю RH&T измеритель на STM8L с sht21 в качестве датчика, индикацией на LCD и сверхмалым потреблением.

Еще ради лулзов хочу собрать эмулятор ключиков от домофона с питанием от линии и ЖК экранчиком. Потом можно тоже самое, но для EM-Marin (RFID).

Еще хочу возродить свои светодиодные часики, поставив в них STM8L151.
0
А в чём состоит превосходство(а) STM над AVR? Если где-то уже писали, то тыкните носом в статью, мог пропустить.
Заранее спасибо.
0
При той-же стоимости периферия в стм8 богаче, чем в АВР. И наоборот — при одинаковой периферии контроллер стм8 будет стоить сильно дешевле чем АВР.

Например имея в кармане 50р можно купить:
STM8L152K6T6
32K Flash, 2K RAM, 1K EE, 1.8-3.6V, 16MHz, 29 GPIO, ADC 12bit (21 канал), DAC 12bit, PWM, RTC, UART, SPI, I2C, LCD

Или mega48pa-au
4K Flash, 512 RAM, 256 EE, 1.8-5.5V, 20 MHz, ADC 10bit (6 каналов), UART, SPI, I2C
0
А в интернетах не подскажете где найти подешевле? У нас в областном центре (а туда ведь надо ещё доехать) AVR нашёл только в одном магазине, но цены в 2-3 раза больше чем в Москве. А уж про STM я и не заикаюсь.
0
Вот хороший, годный магазин chipnn.ru/
+3
Спасибо что напомнили! Они как раз с августа снова начаинают работать. Я уж думал месяц не утерплю, в конце июня составил список покупок, но потом на сайте узнал, что они не работают до августа.
0
Если покупать сразу много, то дешевле будет на http://icdarom.ru
+1
Спасибо, буду изучать.
0
В чип-нн кстати, недавно кучу новых вкусняшек привезли. Некоторые я тут отметил.
0
STM нету в DIP корпусах (что и понятно). Для моих кривых рук на данной стадии развития QFP корпуса недоступны. Надо сначала ЛУТом овладеть в полной мере, хотя я могу и навесным монтажом всё сделать, но это будет адово. =)
0
Я себе купил плату STM8L-Discovery. Она-же может работать как программатор/отладчик для внешних МК.

Можно купить и проводить эксперименты на ней — паять мелочь не нада :)
0
А где Вы брали отладочную плату?
0
Там же в ЧипНН есть, в разделе «Программаторы».
+2
Спасибо, сейчас посмотрю.
0
… у msp низкое потребление главная фишка, да и встроеный ЛСД драйвер имеется, ЦАП… это я так, для разнообразия
0
msp это конечно хорошо.
Кстати, вот тут техассцы доказывают, что msp430 самые-самые.

Но по крайней мере на той плате, которая продается в чип-нн (launch pad) какие-то дубовые МК стоят. Да и не понятно, где сами msp430 покупать.
0
За информацию спасибо, буду иметь ввиду. Но для меня это большей части хобби, много времени уделять не получается, так что лучше оставаться в мейнстриме. С STM'ками в этом плане будет попроще, я думаю.
0
Кстати, у техассцев есть МК, которые могут работать при напряжении 0.9В. ti.com/lowvoltagewiki

В этой серии целых три МК, из них выпускается целый один.

Вот это действительно интересно.
0
Безусловно нужны.
0
Значит будут.
0
да да да… нужны
0
Сам я стм8 не щупал, только подумываю в их направление, потому тема интерестна. Приведённый способ изложения удобен для поиска при изучении: Надо запустить АЦП — нашли статью, надо дисплей — нашли статью. Кроме того 2 варианта сразу: быстрый запуск (ака вот вам пример), и настройка под себя (ака описание всех регистров).
То что статья не больших размеров тоже в плюс — не перегружаетса мозг обилием информации, но при этом статья остаётся понятной.
Вообщем мне нравится как написано, понимаю что написано, вот и плюсую.
+3
Подобные статьи очень нужны!
На данный момент очень интересуют примеры работы с устройствами I2C. Самостоятельно не получется пока осилить.
0
У меня сейчас есть готовый код для работы с i2c.
Это термометр на 8л-дискавери + sht21. Там правда все сделано на стандартной библиотеке, и i2c не хочет работать на частоте выше 1кгц (не пойму, почему).

Могу выложить его сегодня.
0
Выложите, если не трудно. Для начального изучения на стандартной библиотеке даже лучше будет. SHT21 тоже недавно получил. Заодно и опробую.
0
-10
facepalm.jpg
Если Вы троллите, то топорно. Если нет, то аргументируйте свой пост.
0
Надо будет завтра тоже небольшую статейку сделать с готовыми шаблонами проектов iar с использованием периферийных библиотек.
0
  • avatar
  • PRC
  • 01 августа 2011, 03:21
мммм, готовые шаблоны iar часом не идут вместе с периферийной библиотекой? :)
0
Идут, но у меня они не заработали:)
0
О, вот тоже сегодня весь день с IAR парюсь, не могу ничего сделать.
0
Возьми переделанный шаблон — http://narod.ru/disk/20871803001/STM8L%20Template.rar.html. Куда распаковывать есть в архиве. Там правда для х64 систем, в обычных нужно использовать простой Program Files.
И он для версии иара 1.3.
0
Спасибо.
0
Часом не на конкурс целишься? А то допилил бы до марафета и уже открыл счет :)
0
Уже ведь.
0
Есть такая тема, ага. Думал сначала немного дополнить пост.
0
интересно, дисплей подключается к мк по сегментам, так что теоретически к МК можно прикрутить обычные светодиодные семисегментники и рулить ими через драйвер
0
Ага. Особенно если вспомнить про разницу в управлении дисплеями. Например то, что ЖК управляется строго переменкой и потребляет микроамперы, если не меньше.
0
Я там писал, что низкомный драйвер ЖК имеет сопротивление 300к. Думаешь этого хватит, чтобы зажечь светодиоды? :)
0
Отлично! Копи-паст в космик — компиляция — прошивка — ВСЕ пашет :)
0
  • avatar
  • ZiB
  • 01 августа 2011, 16:45
Отлично! Копи-паст в космик — компиляция — прошивка — ВСЕ пашет :)
Вот, только одного не понял за чем часы? где это описано?
Вроде в доке указано что (раздел 9.9)
Модуль ЖКИ использует два источника тактовых сигналов
1) сигнал RTCCLK с делением на два. при чем часы можно и не включать
2) сигнал LCDCLK для доступа (чтения-записи) регистрам ЖКИ
0
  • avatar
  • ZiB
  • 01 августа 2011, 16:55
Да, действительно. Значит, я не правильно понял мануал.
Отключил часы — все работает.
0
Перевел на язык стандартной либы:

CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);

LCD_Init(LCD_Prescaler_2, LCD_Divider_16, LCD_Duty_1_4, LCD_Bias_1_4,
LCD_VoltageSource_Internal);
LCD_ContrastConfig(LCD_Contrast_Level_6);

LCD_PortMaskConfig(LCD_PortMaskRegister_0, 0xFF);
LCD_PortMaskConfig(LCD_PortMaskRegister_1, 0xFF);
LCD_PortMaskConfig(LCD_PortMaskRegister_2, 0xFF);
LCD_DeadTimeConfig(LCD_DeadTime_2);

LCD_HighDriveCmd(ENABLE);
LCD_Cmd(ENABLE);
0
  • avatar
  • ZiB
  • 01 августа 2011, 17:10
Кстати, насколько жирнее получилось со стандартной либой?
0
на 220 байт жирнее :)
0
Ну это не критично — там 32к памяти :)
Я-же специально хотел показать работу через регистры.
0
Да, не все нормально. Все равно либу ни кто не юзает как я понял.
0
Ну почему? У меня в коде термометра (дискавери+sht21) эта либа встречается на каждом шагу.
0
Да и я её последнее время часто использю, только в прерываниях стараюсь не юзать. Поэтому пожалуй инициализировать периферию удобно.
0
Ладно пойду поем, да наверное прикручу ИК-приемник к плате и побалуюсь с контрастом дисплея :)
0
было бы меньше если бы очищал вначале биты потом устанавливал
0
кстати а в иаре твой проект сколько вышел по размеру?
0
408 bytes of readonly code memory
142 bytes of readonly data memory
269 bytes of readwrite data memory
Как-то так
0
ээ… прокосячил, вставил в готовый проект, забыл убрать обработчики прерываний :(
без них флехи 522, 28 байт в минусе не плохо.
0
start 00008000 end 00008080 length 128 segment .const
start 00008080 end 00008086 length 6 segment .const
start 00008086 end 00008089 length 3 segment .init
start 00008089 end 0000820b length 386 segment .text
0
кстати а в иаре твой проект сколько вышел по размеру?
космик его оформил в 766 байт флехи
0
Извиняюсь за оффтоп.
Кто может посоветовать про управление LCD. Хочу подключить экран от калькулятора к обычной AVR'ке без LCD контроллера. А знаний не хватает.
0
Там будут проблемы с подключением контактов индикатора к МК.
0
LCD управляются напряжением. Но поскольку постоянку они не терпят (жидкие кристаллы разрушаются электролизом) — напряжение туда нужно подавать переменное с частотой порядка полусотни герц. Т.е. 10мс держишь на общем 0, на зажженых сегментах — 1, на незажженых — 0. В следущие 10мс все уровни инвертируешь — 1 на общем, 0 на сегментах.
Правда, могут быть косяки с контрастом, он зависит от амплитуды управляющего сигнала, а с МК его не особо порегулируешь, разве что вместе с питанием МК (не ставить же туда тучу преобразователей уровня, проще тогда уж контроллер стекляшки).
0
Спасибо! Теперь всё понял.
0
Немного подредактировал и вбросил на конкурс.
0
Недавно начал разбираться с stm8. а на счет hd44780, как? Что то не получается его подключить. Ни у кого не было опыта?
0
А под IAR ом ничего нет, а то что то мне cosmics не приглянулся, да и не компилится проект, а в чем причина, по незнанию этого компилятора, не понятно
0
Библиотечку бы неплохо сделать, типа printf
с таблицей декодирования рус/лат символов)
0
В разных МК количество разрядов (COM) и сегментов (SEG) различается.
Подчеркнутое меня поначалу очень сильно сбило с толку при попытке раскурить жк дисплей на stm32ldiscovery.
В том же аппноуте об этом хорошо сказано:
Common (COM[i]): electrical connection terminal connected to several LCD segments
(denotes how many LCD segments (pixels) are connected to a segment line)
В общем подключение лучше рассматривать как матрицу отдельных сегментов.
0
вышел компилятор под linux SDCC с поддержкой STM8. целый день ковырял и все таки по этому туториалу запустил пошло поехало. для вывода букв и вообще симоволов бы где то почитать. а так вообще занятно интересно пишете. спасибо. тема актуальна. для меня по крайней мере.
0
Перед компиляцией проекта надо зайти в его настройки, пункт С/С++ Compiler -> Preprocessor и там поменять пути поиска подключаемых файлов, на те, где у вас папки inc и src в проекте.
Для IAR'а можно юзать относительные пути такой строчкой
$PROJ_DIR$
Например:
$PROJ_DIR$\inc
0
Да в любой или почти любой IDE так можно, только макросы по разному называются.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.