В данном материале будет рассказано про подключение дисплея из Китая LCD 1602 (копия HD44780) к микроконтроллеру PIC18F4550 и его программирование в среде MikroC.
Дисплей был заказан на AliExpress вместе с модулем-преобразователем в интерфейс I2C:
На данном модуле всего 4 вывода: Vdd (питание 5В), Gnd (земля), SCL (тактовый сигнал I2C), SDA (линия передачи I2C)
Подключаем питание к модулю дисплея, линии SCL и SDA к соответствующим выводам микроконтроллера I2C (в случае PIC18F4550 - выводы 33,34).
1. Передача байта контроллеру дисплея производится с посылки его уникального адреса. В моем случае адрес - 0x7F.
2. Затем отправляется байт данных, который модулем I2C преобразуется для вывода данных на дисплей следующим образом:
/*
LCD Микросхема
RS P0
RW P1
EN P2
D4 P4
D5 P5
D6 P6
D7 P7
На ножке P3 подключена подсветка. 1 вкл, 0 выкл.
*/
Про назначение данных выводов читайте в даташите HD44780
Чтобы передать байт данных необходимо сначала отправить старшие 4 бита, затем младшие 4 бита.
3. Набор функций в среде MikroC для работы с дисплеем LCD1602 через преобразователь I2C:
#define ADD 0x7F // Адрес микросхемы
////////////////////////////////////////
/*
LCD Микросхема
RS P0
RW P1
EN P2
D4 P4
D5 P5
D6 P6
D7 P7
На ножке P3 подключена подсветка. 1 вкл, 0 выкл.
*/
///////////////////////////////////////////////////////////
// Отправление байта данных на модуль дисплея
//////////////////////////////////////////////////////////
void pcf8574_byte_out(unsigned int data, unsigned int add)
{
unsigned int take=0;
add &= 0xFE;
I2C_Start();
take=I2C_Wr(add);
if(!take)
I2C_Wr(data);
I2C_Stop();
}
///////////////////////////////////////////////////////////
// Передача команды на модуль дисплея
// От предыдущей функции отличается тем, что для передачи управляющей команды требуется передернуть вывод E дисплея
//////////////////////////////////////////////////////////
void com_lcd(unsigned int com)
{
com |= 0x08; // Р3 в единицу, дабы горела подсветка
com |= 0x04; // Е в единицу
pcf8574_byte_out(com, ADD); // Вывод данных
com &= 0xFB; // Е в ноль
pcf8574_byte_out(com, ADD); // Вывод данных
}
///////////////////////////////////////////////////////////
// Инициализация дисплея. В начал программы необходимо один раз проинициализировать дисплей
//////////////////////////////////////////////////////////
void init_lcd(void)
{
delay_ms(20);
com_lcd(0x30); // Переход в 4-х битный режим
delay_ms(5);
com_lcd(0x30); // Переход в 4-х битный режим
delay_us(100);
com_lcd(0x30); // Переход в 4-х битный режим
delay_us(40);
com_lcd(0x20); // Переход в 4-х битный режим
delay_us(40);
com_lcd(0x20); // Установка параметров
com_lcd(0x80); // Установка параметров
com_lcd(0x00); // Выключаем дисплей
com_lcd(0x80); // Выключаем дисплей
com_lcd(0x00); // Очищаем дисплей
com_lcd(0x10); // Очищаем дисплей
com_lcd(0x00); // Устанавливаем режим ввода данных
com_lcd(0x60); // Устанавливаем режим ввода данных
com_lcd(0x00); // Включаем дисплей с выбранным курсором
com_lcd(0xC0); // Включаем дисплей с выбранным курсором
}
///////////////////////////////////////////////////////////
// Вывод символа на дисплей
//////////////////////////////////////////////////////////
void char_out(unsigned int data)
{
unsigned int data_h = ((data & 0xF0) + 0x09);
unsigned int data_l = ((data << 4) + 0x09);
pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит
data_h |= 0x04;
pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит
data_h &= 0xF9;
pcf8574_byte_out(data_h, ADD); // Передача старших 4 бит
pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит
data_l |= 0x04;
pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит
data_l &= 0xF9;
pcf8574_byte_out(data_l, ADD); // Передача младших 4 бит
}
///////////////////////////////////////////////////////////
// Вывод строки на дисплей
//////////////////////////////////////////////////////////
void str_out_lcd(char *str)
{
while((*str) != ' ')
{
char_out(*str);
str++;
}
}
///////////////////////////////////////////////////////////
// Очистка дисплея
//////////////////////////////////////////////////////////
void clear_lcd()
{
com_lcd(0x00);
com_lcd(0x10);
}
///////////////////////////////////////////////////////////
// Установка указателя на 1 строку
//////////////////////////////////////////////////////////
void line1_lcd()
{
com_lcd(0x00);
com_lcd(0x20);
}
///////////////////////////////////////////////////////////
// Установка указателя на 2 строку
//////////////////////////////////////////////////////////
void line2_lcd()
{
com_lcd(0xC0);
com_lcd(0x00);
}
///////////////////////////////////////////////////////////
// Перемещение строки в право
//////////////////////////////////////////////////////////
void lcd_move_right()
{
com_lcd(0x10);
com_lcd(0xC0);
}
///////////////////////////////////////////////////////////
// Перемещение строки влево
//////////////////////////////////////////////////////////
void lcd_move_left()
{
com_lcd(0x10);
com_lcd(0x80);
}
Пример:
void main(){
char text[]="Dobriy Vecher!";
OSCCON = 0b11110010; // 18F450 - выбор внутреннего генератора 8Мгц;
ADCON1=0x0F; // Все порты цифровые;
CMCON = 0x07; // Отключение регистра компаратора;
I2C_Init(100000); // Инциализация I2C
delay_ms(100);
init_lcd(); // Инциализация дисплея
delay_ms(100);
clear_lcd(); // Очистка дисплея
delay_ms(100);
str_out_lcd(text); // Вывод текста на экран
}