Подключение к микроконтроллеру PIC16F84A LCD дисплея.

Подключение к микроконтроллеру PIC16F84A, с кварцем 4 МГц (20 МГц), LCD дисплея на микроконтроллере HD44780 (применялся дисплей WH1602A 2×16).
Линия RS к RA1, E к RA0, DB4 к RB4, DB5 к RB5, DB6 к RB6, DB7 к RB7.


#include <pic1684 .h>

void low_init()
{
TRISA=0x00;
TRISB=0x00;
}

//	LCD биты и переменные
#define LCD_width  15		//	Ширина дисплея
#define LCD_height 1		//	Высота дисплея
#define RS_1 RA1 = 1		//	RA1
#define RS_0 RA1 = 0		//	RA1
#define E_1  RA0 = 1		//	RA0
#define E_0  RA0 = 0		//	RA0

const unsigned char addLUT[4] = {0x80, 0xC0, 0x94, 0xD4};
unsigned char LCD_Address, LCD_Line;
char buffer[15];
//	-LCD биты и переменные

void delay(unsigned int p)
{
unsigned int i;
for(i=0;i<p ;i++){asm("NOP");}
}

//	LCD
void WriteNibble(unsigned char data)
{
E_1;
PORTB = (data & 0x0F)*16;
E_0;
delay(300);
}

void WriteByte(unsigned char data)
{
E_1;
PORTB = (data >> 4)*16;
E_0;
E_1;
PORTB = (data & 0xF)*16;
E_0;
delay(300);
}

void SetLCDPosition(char row, char col)
{
RS_0;
WriteByte(addLUT[row] + col);
RS_1;
LCD_Address=col;
LCD_Line = row;
}

void ClearLCD(void)
{
RS_0;
WriteByte(0x01);
delay(1000);
RS_1;
SetLCDPosition(0,0);
}

void ShowChar(unsigned char c)
{
RS_1;
WriteByte(c);
LCD_Address++;
if(LCD_Address>LCD_width)
if(LCD_Line<lcd_height )
SetLCDPosition(LCD_Line+1,0);
else
SetLCDPosition(0,0);
}

void ShowStr(unsigned char *s)
{
while (*s != 0) ShowChar(*s++);
}

void InitLCD(void)
{
int i;
E_0;
RS_0;
delay(5000);
WriteNibble(0x33);
WriteNibble(0x33);
WriteNibble(0x33);
WriteNibble(0x22);
WriteByte(0x28);
WriteByte(0x01);
WriteByte(0x10);
WriteByte(0x06);
WriteByte(0x0C);
for(i=0x40; i < 0x5F; i++)
{
delay(1000);
RS_0;
WriteByte(i);
delay(1000);
ShowChar(0);
}
RS_1;
SetLCDPosition(0, 0);
buffer[0] = 'O';
buffer[1] = 'k';
buffer[2] = '\0';
ShowStr(buffer);
}
//	-LCD биты

void main()
{
low_init();	//	инициализация контроллера
delay(10000);
InitLCD();	//	инициализация дисплея
delay(100000);
ClearLCD();	//	очистка дисплея

ShowStr("alex-exe.ru\0");	//	вывод строки
}

Описание функций:

  • delay — задержка
  • WriteNibble — отправка полубайта
  • WriteByte — отправка байта, частями, по полбайта
  • ClearLCD — очистка дисплея
  • SetLCDPosition(X,Y) — установить курсор
  • ShowChar(символ) — отправить символ на дисплей
  • ShowStr(строка) — отправить строку на дисплей
  • InitLCD — инициализация дисплея
  • Файл исходников

    Статья обновлена 1 марта 2011 года

15 комментариев на « Подключение к микроконтроллеру PIC16F84A LCD дисплея.»

  1. ОгИл пишет 06.03.2012 в 12:15 #

    Огромное спасибо за этот материал, все очень доходчиво и понятно!!!
    Я вот немного изменил програмку, сделал поменьше,

    void InitLCD(void) //инициализация дисплея
    {
    E=0;
    RS=0;
    pauze (5000);
    WriteByte(0b00000010);
    WriteByte(0b00000110);
    WriteByte(0b00001100);
    WriteByte(0b00010000);
    WriteByte(0b00101000);
    ClearLCD();
    }

    и

    void WriteByte(unsigned char data) //отправка байта, частями, по полбайта
    {
    E=1;
    PORTB = data;
    E=0;
    E=1;
    PORTB = data << 4;
    E=0;
    pauze (300);
    }

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

  2. ОгИл пишет 06.03.2012 в 12:18 #

    Кстати, удалось убрать функцию WriteNibble(), что уменьшило размер текста программы.

  3. Alex_EXE пишет 07.03.2012 в 09:15 #

    Спасибо. Ближайшее время проверю.

  4. Alex_EXE пишет 21.03.2012 в 17:05 #

    Проверил, код работает нормально, сэкономить удалось 81 байт.
    Еще раз спасибо за модификацию.

  5. ОгИл пишет 30.03.2012 в 00:08 #

    Да, давно писал:) такой код перетирает все что было в порте и приходилось использовать 2 порта для RS, E и DB4-DB7. лучше вставить

    void WriteByte(unsigned char c)
    {
    PORT = (c & 0x0F) | (PORT & 0x0F);
    E=1;
    asm(«nop»);
    E=0;
    PORT = ((c << 4) & 0x0F) | (PORT & 0x0F);
    E=1;
    asm("nop");
    E=0;
    Delay(10);
    }

    а такой код ни чуть не меньше вашего, спасибо.

  6. ОгИл пишет 30.03.2012 в 00:12 #

    нет, правильно так

    PORT = (c & 0xF0) | (PORT & 0x0F);
    PORT = ((c << 4) & 0xF0) | (PORT & 0x0F);

  7. wayfarer пишет 29.08.2012 в 22:04 #

    Здравствуйте!
    А не могли бы вы подсказать, как/чем его скомпилировать? Пробовал через mplab и picc, но не получилось.
    Или скинуть непосредственно hex. Я в этом деле новенький..
    Спасибо!

  8. Alex_EXE пишет 01.09.2012 в 00:59 #

    Компилятор HI-TECH использую во всех проектах

  9. NESTERKA пишет 23.05.2016 в 21:42 #

    В данной программе в строках 010 и 011 должен быть знак присвоения т.е. = перед числом 15 и числом 1
    010 #define LCD_width =15 // Ширина дисплея
    011 #define LCD_ heigt =1// Высота дисплея
    В этом случае компиляция с помощью HI THech v9.50
    происходит успешно.
    Желательно дополнить программу ADC вольтметром.

  10. NESTERKA пишет 25.05.2016 в 18:16 #

    В первой строке 01 необходимо записать
    #include
    При симуляции в PROTEUS v7.10 на индикатор выводится периодически только Ok.
    В настройках MPLAB 8.92 или др. версии, можно выбирать PIC16F84A или PIC16F628A для данной программы.

  11. NESTERKA пишет 25.05.2016 в 18:22 #

    Дополнение. Почему то в строке 01 #include исчезло указание на заголовочный файл. В том который и исходном тексте архива необходимо убрать 1684.

  12. Виктор пишет 19.12.2017 в 01:24 #

    Как переменные выводить на экран?

  13. Alex_EXE пишет 20.12.2017 в 10:55 #

    Посмотрите комментарии в статье STM32. 5. Символьный дисплей HD44780

  14. Антон пишет 28.03.2018 в 11:10 #

    А есть схемка под этот код в Multisim?

  15. Alex_EXE пишет 28.03.2018 в 14:48 #

    Нет.

Комментарии RSS

Оставьте отзыв