Первым делом нужно было собрать устройство, на котором можно было потренироваться, но так как на тот момент у меня была платка от другой «игрушки», грех было не воспользоваться этой платой, так как обвязка МК в обоих схемах почти идентичная. Исходная схема платы ниже:
Дальше нужно было подключить дисплей, у нас даже остается 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/
Добавить комментарий