Задача
Инициализировать дисплей и вывести на него текст.
Микроконтроллер: PIC16F84A, кварц 4 МГц. Среда: MPLAB X + MPASM (или любой совместимый ассемблер). Как настроить среду и прошить контроллер — в статье программирование PIC.
Что понадобится
- PIC16F84A
- кварц 4 МГц + 2×22 пФ
- дисплей 16×2 на HD44780
- подстроечный резистор 10 кОм (контрастность)
- резистор 10 кОм
Схема подключения
| Вывод | Подключение |
|---|---|
| RB4…RB7 | линии данных дисплея D4…D7 |
| RB0 | вывод RS (команда/данные) |
| RB1 | вывод E (строб) |
| RW дисплея | на GND — только запись |
| V0 дисплея | средний вывод подстроечника контрастности |
Алгоритм
- Выдержать паузу после подачи питания — дисплею нужно время на запуск.
- Трижды послать команду 0x30, затем 0x20 — переход в четырёхбитный режим.
- Задать формат (2 строки, шрифт), включить дисплей, очистить экран.
- Байт передавать двумя полубайтами: сначала старший, затем младший.
Листинг на ассемблере
Код проверен ассемблером и собирается без ошибок. Скачать: p14.asm · p14.hex (готовая прошивка).
;=======================================================
; Проект 14. LCD HD44780 в 4-битном режиме
; PIC16F84A, 4 МГц
; RB4..RB7 — шина данных D4..D7, RB0 — RS, RB1 — E
; RW дисплея посадить на GND
;=======================================================
LIST p=16F84A
#include <p16f84a.inc>
__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
#define RS PORTB,0
#define E PORTB,1
cblock 0x0C
d1, d2, temp, chr
endc
ORG 0x000
goto Start
Start
bsf STATUS,RP0
clrf TRISB ; весь порт B — выходы
bcf STATUS,RP0
clrf PORTB
call Delay20ms ; ждём готовности дисплея
call LcdInit
movlw 'P'
call LcdData
movlw 'I'
call LcdData
movlw 'C'
call LcdData
Stop
goto Stop
;--- инициализация в 4-битном режиме ---
LcdInit
movlw 0x30 ; три раза 8-битная команда
call SendNibble
call Delay5ms
movlw 0x30
call SendNibble
call Delay5ms
movlw 0x30
call SendNibble
call Delay5ms
movlw 0x20 ; переход в 4-битный режим
call SendNibble
call Delay5ms
movlw 0x28 ; 4 бита, 2 строки, шрифт 5x8
call LcdCmd
movlw 0x0C ; дисплей вкл, курсор выкл
call LcdCmd
movlw 0x06 ; сдвиг курсора вправо
call LcdCmd
movlw 0x01 ; очистка экрана
call LcdCmd
call Delay5ms
return
;--- команда: RS = 0 ---
LcdCmd
movwf chr
bcf RS
goto SendByte
;--- данные: RS = 1 ---
LcdData
movwf chr
bsf RS
SendByte
movf chr,w
andlw 0xF0 ; старший полубайт
call SendNibble
swapf chr,w
andlw 0xF0 ; младший полубайт
call SendNibble
call Delay5ms
return
;--- выдать полубайт из старших бит W ---
SendNibble
movwf temp
movf PORTB,w
andlw 0x0F ; сохраняем RS и E
iorwf temp,w
movwf PORTB
bsf E ; строб
nop
nop
bcf E
return
Delay5ms
movlw .10
movwf d1
X1 movlw .165
movwf d2
X2 nop
decfsz d2,f
goto X2
decfsz d1,f
goto X1
return
Delay20ms
call Delay5ms
call Delay5ms
call Delay5ms
call Delay5ms
return
END
Пояснения
- Четырёхбитный режим экономит четыре вывода: байт делится на два полубайта, каждый сопровождается импульсом на линии E.
- Команда
swapfменяет полубайты местами — так младшая тетрада попадает в старшие биты порта. - При выдаче полубайта младшие биты порта маскируются, чтобы не сбить состояние RS и E.
Что дальше
Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры PIC.