PIC мк. Эксперимент №6. Подключение LCD дисплея.

Задача: Управление графическим дисплеем

Исходный материал: PIC16f628a, LCD 2×16, breadboard

Схема подключения дисплея (кварц не подключен, но предполагается, что он есть):

Следующий шаг – написание функций управления дисплеем. Я просто взял файлы из директории samples папки компилятора и переделал под себя.

Файл lcd.c


/*
 *    LCD interface example
 *    Uses routines from delay.c
 *    This code will interface to a standard LCD controller
 *    like the Hitachi HD44780. It uses it in 4 bit mode, with
 *    the hardware connected as follows (the standard 14 pin
 *    LCD connector is used):
 *
 *    PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
 *    PORTA bit 3 is connected to the LCD RS input (register select)
 *    PORTA bit 1 is connected to the LCD EN bit (enable)
 *
 *    To use these routines, set up the port I/O (TRISA, TRISD) then
 *    call lcd_init(), then other routines as required.
 *
 */

#ifndef _XTAL_FREQ
 // Unless specified elsewhere, 4MHz system frequency is assumed
 #define _XTAL_FREQ 4000000
#endif

#include    <htc.h>
#include    "lcd.h"

#define    LCD_RS RA1
#define    LCD_RW RA2
#define LCD_EN RA3

#define LCD_DATA    PORTB

#define    LCD_STROBE()    ((LCD_EN = 1),(LCD_EN=0))

/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
 __delay_us(40);
 LCD_DATA = ( ( c >> 4 ) & 0x0F );
 LCD_STROBE();
 LCD_DATA = ( c & 0x0F );
 LCD_STROBE();
}

/*
 *     Clear and home the LCD
 */

void
lcd_clear(void)
{
 LCD_RS = 0;
 lcd_write(0x1);
 __delay_ms(2);
}

/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
 LCD_RS = 1;    // write characters
 while(*s)
 lcd_write(*s++);
}

/* write one character to the LCD */

void
lcd_putch(char c)
{
 LCD_RS = 1;    // write characters
 lcd_write( c );
}

/*
 * Go to the specified position
 */

void
lcd_goto(unsigned char pos)
{
 LCD_RS = 0;
 lcd_write(0x80+pos);
}

/* initialise the LCD - put into 4 bit mode */
void
lcd_init()
{
 char init_value;

 CMCON  = 0x07;    // Disable analog pins on PORTA

 init_value = 0x3;
 TRISA=0;
 TRISB=0;
 LCD_RS = 0;
 LCD_EN = 0;
 LCD_RW = 0;

 __delay_ms(15);    // wait 15mSec after power applied,
 LCD_DATA     = init_value;
 LCD_STROBE();
 __delay_ms(5);
 LCD_STROBE();
 __delay_us(200);
 LCD_STROBE();
 __delay_us(200);
 LCD_DATA = 2;    // Four bit mode
 LCD_STROBE();

 lcd_write(0x28); // Set interface length
 lcd_write(0xF); // Display On, Cursor On, Cursor Blink
 lcd_clear();    // Clear screen
 lcd_write(0x6); // Set entry Mode
}

и файл lcd.h


/*
 *    LCD interface header file
 *    See lcd.c for more info
 */

/* write a byte to the LCD in 4 bit mode */

extern void lcd_write(unsigned char);

/* Clear and home the LCD */

extern void lcd_clear(void);

/* write a string of characters to the LCD */

extern void lcd_puts(const char * s);

/* Go to the specified position */

extern void lcd_goto(unsigned char pos);

/* intialize the LCD - call before anything else */

extern void lcd_init(void);

extern void lcd_putch(char);

/*    Set the cursor position */

#define    lcd_cursor(x)    lcd_write(((x)&0x7F)|0x80)

Ну и, наконец, тестовая программа


#include <htc.h>
#include "lcd.h"
#define _XTAL_FREQ 4000000

__CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS & HS);

void main() {
lcd_init();
 lcd_goto(0);    // select first line
 lcd_puts("PIC manual");
 lcd_goto(0x40);    // Select second line
 lcd_puts("SARGE.PP.UA");

 for(;;);

}

Результат:

Исходники здесь

UPD: Новую версию кода, адаптированную под любой пин порта можно посмотреть здесь.

PIC мк. Эксперимент №6. Подключение LCD дисплея.: 93 комментария

  1. А в мейне и заголовочных файлах то поменяли хоть частоту на 20 МГц?

    А что значит 6 АЦП? 6 отдельных модулей ацп чтоли? Насколько я знаю в pic16f877, который вы привели просто 8 входов на один модуль ацп, то есть в один момент времени вы можете обрабатывать напряжение на одном пине.

    По выбору мк есть удобный тул на сайте, вроде как maps называется, подбираете нужный мк по параметрам, а дальше уже сравниваете по ценам.

    Ответить

    Вася Ответил:

    ну я кристалл выбрал в mplab.
    а частоту в протеусе записал

    Ответить

    sarge Ответил:

    В коде в нескольких местах есть макрос #define _XTAL_FREQ где стоит 4МГц, чтобы работать на другой частоте нужно поместить ее туда.

    Ответить

  2. Здравствуйте. А не подскажите сколько мкс надо для антидребезга не фиксируемой кнопки? Сколько надо, чтобы нормально реагировало….
    Можно ведь вместо __delay_ms() для этого использовать какой-либо таймер?
    (а то у меня почему-то начинает ругаться компилятор когда я ставлю значение больше 30…. 20МГц)

    Ответить

    sarge Ответил:

    Милисекунд 20 наверное (не микросекунд), вообще опытным путем надо выяснять.

    Конечно можно, любым способом делаете задержку.

    Ответить

  3. Если мне надо 300 мс (видимо если мили, то 0,3с), то какой таймер лучше подойдет?
    TMR2 я слышал можно настроить на определенный счет с помощью специального регистра. Но это у Вас не написано….
    Пробовал:
    PR2=50 //тут задается до скольких вести счет.
    T2CON=0b00000100
    Только не сработало….

    Ответить

    sarge Ответил:

    Что значит не написано – http://diymicro.ru/pic-mk-eksperiment-9-ispolzovanie-modulya-tajmera-tmr2.html
    Что у меня написано, а что нет можно посмотреть по ссылке вверху PIC Лаборатория.

    Смотрите внимательно, читайте даташит, там есть все и формулы и примеры расчетов. А какой подойдет – всякие могут подойти, зависит от частоты кварца и от того готовы ли вы использовать сторонние переменные.

    Ответить

  4. Здравствуйте. Имеется ЖК-дисплей этот: http://www.chipdip.ru/product/dv-20200s2rb-h-r/ (даташиты прикреплены по ссылке после характеристики) + МК использую pic16f688
    Подключил значит я дисплей, кручу резистор (для VEE на 10кОм) и появляется какая-то линия из прямоугольников когда напряжение на VEE достигает порядка 0.1В, а при увеличении напряжения –> исчезает.
    Но самое главное то, что у меня не выводится еще нужный текст то на ЖК… Все проверял…
    Значит сделал так: 1 вывод – земля, 2 – порядка 4.9В, 3 – 0.1В, 4 – к МК, 5 – заземлил (т.е. надо на чтение, хотя пробовал и наоборот заплюсовать), 6 – на МК и 11-14 к МК.
    P.S:Микроконтроллер прошит. напряжение падается такое же как и на дисплей ( подключены параллельно)
    Не знаю зачем 15 и 16 вывод… Может что-то тоже надо к ним подключать? В протеусе их нет. Не знаю….

    Ответить

    sarge Ответил:

    Даташиты просто космос…
    Надо найти нормальные даташиты где все расписано, я с этим дисплеем никогда не работал так что мало что подскажу. Единственное на VEE оч странное напряжение линия прямоугольников – это задранная донельзя контрастность, при такой настройке вы ничего кроме квадратов не увидите.

    15 и 16 вывод – обычно для подсветки светодиодной юзается, пока можно забить скорее всего, но нужно смотреть даташит.

    Ответить

  5. Вот более расширенные, но ничего интересного там нет…
    http://www.infinitumpage.mx/GIOSYS/DV-20200.pdf
    http://www.tabalabs.com.br/musica/alesis/lcd/ds16235.pdf
    А что более расширенно тогда надо?
    Получается я все же правильно подключил и не сломал его раз квадраты есть… Может что то с МК…

    Ответить

  6. Если ЖК показывает квадраты, то значит он точно рабочий?
    Видимо надо как-то проверить сам МК тогда раз с ЖК все в порядке чтоли….
    Я вот так задавал:
    #include
    #include
    #include
    #include
    #define _XTAL_FREQ 4000000 //4MHz
    #pragma config MCLRE = OFF, FOSC = INTOSCIO, WDTE = OFF, PWRTE = ON
    Может частота не та или биты конфигурации не верно включил…. Посмотрите пожалуйста.
    Не знаю 4 МГц ли внутренний генератор….

    Ответить

    sarge Ответил:

    нет не точно, но за квадратами вы не сможете ничего увидеть, так как контрастность на максимуме. Нужно увеличить напряжение на vee, чтобы квадраты пропали.

    Ответить

    Василий Ответил:

    Да я понял уже. Странно вроде то, что 1 линия квадратов, а у меня ЖК на 2 строки.
    А с генератором и битами конфигурациями все в порядке? Я все так задал?

    Ответить

    sarge Ответил:

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

    Ответить

    Василий Ответил:

    А как это вообще можно решить то?) Просто берется и запускается. Я написал как я подключал ЖК выше.
    Что тут еще с ним можно поделать – не знаю…
    P.S. Вам не понравились прошлые даташиты и вот нашел более полные :
    http://www.infinitumpage.mx/GIOSYS/DV-20200.pdf
    http://www.tabalabs.com.br/musica/alesis/lcd/ds16235.pdf
    но увы для меня та информация полезной не оказалась.

    Ответить

    sarge Ответил:

    Вы не ответили, запустился ли дисплей в протеусе по вашей схеме подключения и с вашим кодом.

    Ответить

  7. Т.е.? Ну я в протеусе собрал (индикатор в протеусе был разумеется другой, но тоже 20х2) и все работает естественно.
    Потом дал МК знакомому, он прошил его моей прошивкой, я подключил и результата нет.

    Ответить

    sarge Ответил:

    Тогда надо искать даташит на контроллер который установлен на этом дисплее, и смотреть разницу между ним и HD44780, для эксперимента было бы неплохо подключить стандартный HD44780 к вашему девайсу.

    Ответить

    sarge Ответил:

    Поискал чутка, в этом дисплее используется KS-0066, они идут как взаимозаменяемые с hd44780, но есть какие то нюансы в инициализации шины 4 бита. Копайте в эту сторону.

    Ответить

    Василий Ответил:

    А может быть, что надо -5В подавать на Vss? А то я видел некоторые так делают. (боюсь пробовать, чтобы не сжечь). + Я подключал не совсем как у Вас. Я RW заземлил. Может в этом ЖК он как бы инвертный и надо наоборот на +…. Хотя если он аналогичен….
    Не знаю где Вы это прочли, но как я не вбиваю свой ЖК ничего не выдается, да и про проблемы с 4 битами не встречал….

    Ответить

    sarge Ответил:

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

    http://forum.primuss3.com/viewtopic.php?f=14&t=215
    http://www.radiokot.ru/forum/viewtopic.php?f=20&t=584&hilit=44780&start=520
    http://www.microchip.su/showthread.php?t=5438&page=9
    http://kazus.ru/forums/showthread.php?t=103491

    Есть куча тем, с вечным перетиранием как правильно инициализировать, и для всякого китайского шрота всегда найдется какое-нибудь минимальное изменение, без железа помочь вам я ничем не смогу. Максимум еще раз направить – копать в сторону инициализации дисплея.

    Ответить

  8. Пробежался по всем ссылкам. Как я понял худший вариант — купить мне HD44780 индикатор. который как я понял и используется в Протеусе, переписать программу, перепрошить МК и проверять. Но хотелось бы очень этого избежать… Лишнии затраты, да и ЖК меньше….
    Если это связано как все пишут с инициализацией, то это зависит от библиотека, так? (я использую библиотеки, а не сам инициализирую, т.к. не умею.)
    Вот я использовал такую:
    http://forum.chipmk.ru/index.php/topic/340-%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0-lcd-%D0%B4%D0%BB%D1%8F-pic/
    Она от стандартной Hi-tech позволяет использовать конкретные выводы МК, что мне и надо.
    Не знаю поддерживает ли она мой ЖК-контроллер…. В этой библиотеки есть настройки и для 20х2 разрешения как у меня…
    Не знаете как узнать подходит она или нет?
    Даже тогда не знаю что и делать… Программатора как на зло под рукой нет… Может это вообще с МК проблемы…

    Ответить

    sarge Ответил:

    Худший правильно поняли, я бы на вашем месте еще попробовал по 8 битной шине завести, чтобы понять жив пациент или нет.

    Количество строк и длина насколько я помню значения не имеет для инициализации. Узнать без программатора – никак, только опыты с железом вам помогут понять рабочий ваш вариант или нет.

    Ответить

  9. Якобы бытует мнение, что у некоторых просто не хватает питания чтоли….
    Так вроде -0.3В там…

    Ответить

    sarge Ответил:

    Supply Voltage for LCD Drive Vdd-Vee Vdd-13.5 — Vdd+0.3 V

    Ответить

    Василий Ответил:

    INTOSCIO и INTOSC — в чем разница? У меня ведь 4МГц?
    И если я включил PWRTE, то из-за этого может не работать? Может у меня сбрасывается постоянно

    Ответить

    sarge Ответил:

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

    Из-за PWRTE сброс происходить будет только при пониженном питании, если у вас номиналы ок, то ничего не произойдет.

    Ответить

  10. Напряжение у меня порядка 4.8-5.2В
    INTOSCIO — я это ведь задал в битах конфигурации. INTOSC — на это у меня ругается.
    OSC вывод ведь вывод для генератора? Они у меня подключены к дисплею как раз….

    Ответить

    sarge Ответил:

    Ну и должно работать если не ругается, в этом случае они используются как ио порты просто.

    Другое дело что по даташиту такой директивы для вашего мк нету, я вижу INTRC и INTRCIO.
    Я вообще эти пины стараюсь только после отладки на других подрубать, чтобы по граблям не ходить в случае чего…

    Ответить

  11. Здравствуйте. Мне прошили микросхему и несовсем должный результат….
    Там у меня в протуесе все работает. Должна быть такая палочка: |
    А у меня вместо этого число 12 мелким шрифтом…

    Ответить

    sarge Ответил:

    А как на этом дисплее выглядит число мелким шрифтом то?)) Я что то себе слабо 2 представляю на половине разряда…

    А вообще, ну вот тут я вообще не представляю как можно вам помочь, я уже предлагал варианты покупки второго дисплея и отладки в 8 битном режиме, а не 4 битном.

    Ответить

  12. Так всеж запустилось. Только этот символ….
    Это проблемы связанные с библиотекой или железом?

    Ответить

    sarge Ответил:

    Скорее всего со связкой библиотеки с железом, вы же говорите что в протеусе работает, значит на стандартном hd44780 запустится должно.

    Ответить

  13. У меня разве такой? Вроде KS-0066 Вы писали.
    Как то заменить это чтоли попробовать…

    Ответить

    sarge Ответил:

    Я говорю, что то что запускается в протеусе, отрабатывает на hd44780, на KS-0066 может не запуститься.
    Я когда-то так и не смог запустить винстаровский на базе KS-0066, кучу нервов убил пока не купил другой на hd44780.

    Ответить

  14. Блин тогда придется опять перепрошивать, идти к мужику… Или же маркером чертить по дисплею эту линию)
    Знакомого с нужным дисплее к сожалению нет, чтобы поменяться.

    Ответить

    sarge Ответил:

    Так может уже пора свой программатор прикупить?)

    Ответить

  15. Уважаемый sarge
    Материалы Ваших статей использую для освоения C, многое уже проянилось, за что Вам большое спасибо! В целом разобрался с работой LCD-панели – в Proteus и на макетке все работает! Но появились вопросы.
    1. Помогите разобраться с работой функции lcd_puts(const char * s), она у Вас выводит в LCD строку прямо из PIC. И действительно выводит! А по описанию дисплея (использую MT-16S2R), как я понял, можно отправлять лишь адреса символов по внутренней кодовой таблице. Написал код на ASM-е – все работает, но это же неудобно. А тут сразу выводится строка. Пожалуйста, поясните как понимать выражение с параметрами функции, в частности, фрагмент “*s” (т.е. как это все работает)? В т.ч. и цикл while(*s), ведь в скобках д.б. условие?
    2. Большую помощь в понимании процессов оказывает режим пошаговой отладки. Но вот с чем я никак не могу справиться. Содержимое регистров PIC прекрасно отображается в окне Watch. А вот значения глобальных и локальных переменных посмотреть никак не удается. В окне Watch они не отображаются (и не должны). Есть окно Locals (полагаю, как раз для этих целей), но оно пустое. И добавить в него информацию никак не получается. В контекстном меню окна почти все опции “серые”, кроме Properties. Все листинги брал с Вашего сайта “Эксперимент №6”, но и в других проектах все аналогично. Подумал, у меня MPLAB “кривая” (v8.85.00), но и в Proteus окно PIC CPU Variables также пустое и ничего в него не вводится.
    Прошу извинить, если вопросы “детские”, но я полный новичок в C, пока в стадии обучения.

    Ответить

    sarge Ответил:

    1. Для отправки символа используется функция lcd_write(c), которая как раз таки также расположена внутри lcd_puts(), отправляющей всю строку.
    *s – читайте про работу с указателями в C, while(*s) пока не закончится вся строка, выдираем по одному символу.

    2. Показывайте пример конкретный, кидайте архив на мыло мне (sargein@gmail.com) и попробуем разобраться. Но предупреждаю, мплаба у меня сейчас даже нету, поэтому под протеус давайте все.

    Ответить

    Paulwasw Ответил:

    Большое спасибо за ответ. Указатели… Читал про это, но на практике не признал. Звезду пытался интерпретировать, как умножение. Теперь идея начинает проясняться в деталях, но надо еще поработать.
    К вопросу 2 – Проект отправил Вам на почту, там все вместе: и Proteus, и MPLAB. Собственно, это код из текущего Эксперимента, немного измененный под PIC16F873A. Зачем такой большой PIC? Во-первых, я уже убедился: на шину данных нужно вешать порт целиком. Иначе можно долго ошибки выкорчевывать. А к порту B планировал на перспективу подключить кнопки для переключения режимов. Так вот, в файле lcd.c собраны функции проекта. К примеру, я хочу наблюдать значение параметра “с” в теле функции lcd_write, либо текущее значение указателя “*s” в lcd_puts, либо значение переменной “init_value” в lcd_init(). Судя по документации, окно PIC CPU Variables как раз для этого и должно служить. Но не получается.

    Ответить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.