В университете на одном профильном предмете начали изучать стенд на основе микроконтроллера МК-51, дисплея HD44780, клавиатуры. Все это дело программируется через COM порт с помощью ассемблера. На тот момент я изучат микроконтроллеры семейства AVR (а именно Atmega8), поэтому появилось желание научиться инициализировать и выводить на экран какую-нибудь информацию с помощью ассемблера без применения библиотек. После продолжительных поисков нашел только то, как дисплей запрограммировать на языке C с помощью библиотек, в которых не совсем понятно, что происходит. Поэтому было принято решение написать код самому, с использованием ассемблерных команд. Дисплей 0802, две строки.
Первым делом нужно было собрать устройство, на котором можно было потренироваться, но так как на тот момент у меня была платка от другой «игрушки», грех было не воспользоваться этой платой, так как обвязка МК в обоих схемах почти идентичная. Исходная схема платы ниже:
Дальше нужно было подключить дисплей, у нас даже остается 2 не задействованных вывода ( PD0, PD1). Все программируется через JTAG (X1). Соединял дисплей по этой схеме:
Я решил использовать 4 битный режим передачи, как я тогда думал, что его осуществить будет легче. Схему пришлось изменить ввиду отсутствия светодиодной подсветки (нет 15 и 16 вывода на дисплее), также убрал не нужный мне светодиодный индикатор (D1, R2). Питал всю схему и дисплей от аккумулятора от сотового.
В итоге у меня получилось это:
Плату изготавливал с помощью ЛУТ (лазерно утюжный метод)
Настало время программной части. Программу писал на AVRstudio
.include <m8def.inc>
#define RS 2 //RS=PD2
#define E 3 //E=PD3
.def temp = r16
rjmp reset
.org 40
reset:
ldi r16, HIGH(RAMEND) ;настройка стека
out SPH,r16
ldi r16,LOW(RAMEND)
out SPL,r16
ldi r16,0xfc ;настройка ножек PD2-PD7 на выход
out ddrd,r16
ldi r16,0x00
out portd,r16
rcall LCD_init
sbi portb,6 ;пишем данные
rcall LCD_dat
rjmp loop
LCD_init:
ldi temp,0x30 ;управляющее слово
rcall LCD_com1 ;вызов программы ввода
ldi temp,0x30
rcall LCD_com1
ldi temp,0x30
rcall LCD_com1
ldi temp,0x20 ;4 бит режим
rcall LCD_com1
ldi temp,0x20
rcall LCD_com
ldi temp,0x0c
rcall LCD_com
ldi temp,0x06
rcall LCD_com
ldi temp,0x01
rcall LCD_com
ret
LCD_dat:
ldi ZL, LOW(DB << 1)
ldi ZH, HIGH(DB << 1)
ldi r21,8 ;количество элементов в массиве
m1: lpm temp, Z+
rcall LCD_com
dec r21
cpi r21,0
brne m1
ret
LCD_com:
ldi r24,(0<<RS)|(1<<E)
sbic portb,6
ldi r24,(1<<RS)|(1<<E)
out portD,r24
mov r23,temp
andi temp,0b11110000 ;вырываем старшую тетраду
or temp,r24 ;суммируем с E и RS
out portD,temp
ldi r24,(0<<RS)|(0<<E)
out portD,r24 ;выводим
rcall func_delay
ldi r24,(0<<RS)|(1<<E)
sbic portb,6
ldi r24,(1<<RS)|(1<<E)
out portD,r24
andi r23,0b00001111 ;вырываем младшую тетраду
swap r23
mov temp,r23
or temp,r24 ;суммируем с E и RS
out portD,temp ;выводим
ldi r24,(0<<RS)|(0<<E)
out portD,r24
rcall func_delay
ret
LCD_com1:
ldi r24,(0<<RS)|(1<<E)
out portD,r24
or temp,r24
out portD,temp
ldi r24,(0<<RS)|(0<<E)
out portD,r24
rcall func_delay
ret
loop: rjmp loop
func_delay: ;задержка
ldi r17,0x20
ldi r18,0x00
func_delay_subb:
subi r18,1
sbci r17,0
brcc func_delay_subb
ret
DB: .db 0xA8,0x70,0x65,0xB3,0x65,0xE0,0x3A,0x29 ;массив символов
Программу старался писать не отходя от алгоритма приведенного в даташите.
Пришлось сделать разделение на подпрограммы LCD_com1 и LCD_com, так как не получалось отправлять команды настройки и коды символов через одну подпрограмму.
Если нужно выводить на вторую строку тоже нужно добавить эти строки:
cbi portb,6 ;пишем команды на вторая строку, начало строки
ldi temp,0xc2
rcall LCD_com
sbi portb,6 ;пишем данные
rcall LCD_dat
Однако, по непонятным мне причинам при выводе на экран информации в 2х строчный режим контрастность сильно снижается.
Коды символов нужно брать из таблицы и заносить в массив, не забывая про ограничение размеров экрана
В дальнейшем планируется применить навыки на практике, термометр на процессоре, реобас или еще где-нибудь
Исходный код проекта:
dl.dropbox.com/u/77527472/LCDasm.zip
В нем подключена кнопка на ресет, при нажатии, содержимое дисплея обновляется
Даташит на дисплей
dl.dropbox.com/u/77527472/wh1602-datasheet.pdf
Даташит на микроконтроллер, там же есть система команд на него
dl.dropbox.com/u/77527472/ATmega8(L).pdf
ps: пост первый, поэтому принимаю всю критику в свою сторону, постараюсь в дальнейшем все учесть
Автор: CryENG