Подключение к микроконтроллеру 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 года
Alex_EXE | 23.07.2009 | Микроконтроллеры |
ОгИл пишет 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);
}
Посмотрите, пожалуйста, опытным взглядом 🙂 программа стала примерно на треть меньше, вроде работает, какие последствия такой переделки, спасибо.
ОгИл пишет 06.03.2012 в 12:18 #
Кстати, удалось убрать функцию WriteNibble(), что уменьшило размер текста программы.
Alex_EXE пишет 07.03.2012 в 09:15 #
Спасибо. Ближайшее время проверю.
Alex_EXE пишет 21.03.2012 в 17:05 #
Проверил, код работает нормально, сэкономить удалось 81 байт.
Еще раз спасибо за модификацию.
ОгИл пишет 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);
}
а такой код ни чуть не меньше вашего, спасибо.
ОгИл пишет 30.03.2012 в 00:12 #
нет, правильно так
PORT = (c & 0xF0) | (PORT & 0x0F);
PORT = ((c << 4) & 0xF0) | (PORT & 0x0F);
wayfarer пишет 29.08.2012 в 22:04 #
Здравствуйте!
А не могли бы вы подсказать, как/чем его скомпилировать? Пробовал через mplab и picc, но не получилось.
Или скинуть непосредственно hex. Я в этом деле новенький..
Спасибо!
Alex_EXE пишет 01.09.2012 в 00:59 #
Компилятор HI-TECH использую во всех проектах
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 вольтметром.
NESTERKA пишет 25.05.2016 в 18:16 #
В первой строке 01 необходимо записать
#include
При симуляции в PROTEUS v7.10 на индикатор выводится периодически только Ok.
В настройках MPLAB 8.92 или др. версии, можно выбирать PIC16F84A или PIC16F628A для данной программы.
NESTERKA пишет 25.05.2016 в 18:22 #
Дополнение. Почему то в строке 01 #include исчезло указание на заголовочный файл. В том который и исходном тексте архива необходимо убрать 1684.
Виктор пишет 19.12.2017 в 01:24 #
Как переменные выводить на экран?
Alex_EXE пишет 20.12.2017 в 10:55 #
Посмотрите комментарии в статье STM32. 5. Символьный дисплей HD44780
Антон пишет 28.03.2018 в 11:10 #
А есть схемка под этот код в Multisim?
Alex_EXE пишет 28.03.2018 в 14:48 #
Нет.