Управляем ЖК дисплеем HD44780 с помощью ассемблера

от автора

В университете на одном профильном предмете начали изучать стенд на основе микроконтроллера МК-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: пост первый, поэтому принимаю всю критику в свою сторону, постараюсь в дальнейшем все учесть

ссылка на оригинал статьи http://habrahabr.ru/post/166735/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *