/*
* ATMEGA8A.asm
*
* Created: 12.10.2016 23:31:40
* Author: AD-Admin
*/
.include "m8Adef.inc"
.def temp=R16
rjmp Init
reti ; External Interrupt Request 0
reti ; External Interrupt Request 1
.org 20
Init:
//ldi temp,0b11111111 ; грузим признак выхода
//out DDRB,temp ; в регистр управления портом "B"
//ldi temp,0b00000000 ;обнуляем
//out PortB,temp ;порт Б
ldi temp,0b11111111 ; грузим признак выхода
out DDRC,temp ; в регистр управления портом "C"
ldi temp,0b00000000 ;обнуляем
out PortC,temp ;порт C
ldi temp,0b11111111 ; грузим признак входа (0-вход)
out DDRD,temp ; в регистр упр. портом "D"
ldi temp,0b00000000 ; грузим признак "активности" (1-активность)
out PortD,temp ; в регистр входа
//Main:
RCALL LCD_INIT ; инициализация дисплея !
////////////////////////////////////////////////////////////////////////
Main:
LDI R16 , 0x00 ; печать символа '0'
RCALL LCD_CHAR
LDI R16 , 0x10 ; печать символа ' ' (пробел)
RCALL LCD_CHAR
LDI R16 , 0x01 ; печать символа '0'
RCALL LCD_CHAR
LDI R16 , 0x10 ; печать символа ' ' (пробел)
RCALL LCD_CHAR
LDI R16 , 17 ; печать символа 'галка'
RCALL LCD_CHAR
rcall Ystza1
rcall LCDCLR
rjmp Main
; позиционирование печати
LDI R18 , 0 ;(Y) 3 строка (отсчет с 0)
LDI R17 , 5 ;(X) 41 линия по горизонтали
RCALL LCD_POS
LDI R16 , 0x01 ; печать символа '9'
RCALL LCD_CHAR
rcall Ystza1
rcall LCDCLR
rjmp Main
////////////////////////////////////////////////////////////////////////
Ystza1: //около 1 сек (1mhz)
ldi R19, 0b01000000
ldi R20, 0b01000010
ldi R21, 0b00001111
rcall Delay
ret
Ystza2:
ldi R19, 0b10000000
ldi R20, 0b00000000
ldi R21, 0b00000000
rcall Delay
ret
Delay:
subi R19,1
sbci R20,0
sbci R21,0
brcc Delay
ret
//---------------------------------------------------------------------------------------
; ДРАЙВЕР МИНИМАЛЬНОЙ ФУНКЦИОНАЛЬНОСТИ
; для дисплеев на контроллере PHILIPS PCD 8544 (NOKIA 3310, 5110)
; автор Горбуков Виталий (Vitaly V Gorbukov)
;
gorbukov@yandex.ru http://vg.ucoz.ru ;
;1. ОПИСАНИЕ ВЫЗОВОВ И ПРИМЕР ИСПОЛЬЗОВАНИЯ ДРАЙВЕРА
;
; Вызовы:
;
; LCD_INIT - инициализация дисплея
;
; LCD_POS (R17=X, R18=Y) - позиционирование вывода на экране (работает не на всех дисплеях)
;
; LCD_CHAR (R16=char) - вывод символа на дисплей
;
;
;
; ЗНАКОГЕНЕРАТОР дисплея содержит 17 символов:
; +-------+----+----+----+----+----+----+----+----+
; |код |0x00|0x01|0x02|0x03|0x04|0x05|0x06|0x07|
; +-------+----+----+----+----+----+----+----+----+
; |символ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
; +-------+----+----+----+----+----+----+----+----+
;
; +-------+----+----+----+----+----+----+----+----+--------------+
; |код |0x08|0x09|0x0A|0x0B|0x0C|0x0D|0x0E|0x0F|0x10 |
; +-------+----+----+----+----+----+----+----+----+--------------+
; |символ | 8 | 9 | A | B | C | D | E | F | ' ' (пробел)|
; +-------+----+----+----+----+----+----+----+----+--------------+
;
; Символы рисуются на матрице 5х8 точек (4 вертикальных. линии на символ + 1 одна пустая
; линия как интервал между символами)
;
; Типовое использование библиотеки (текст программы)
;+--------------------------------------------------------------+
;|.include "m32def.inc" ; файл дефайнов вашего контроллера |
;| |
;|.CSEG |
;|.ORG 0x0000 |
;| RJMP START |
;| . . . . . таблица переходов по прерываниям . . . . . |
;|START: |
;| . . . . установка стека . . . . . |
;| . . . . . ваша инициализация . . . . . |
;| |
;| |
;| RCALL LCD_INIT ; инициализация дисплея ! |
;| |
;| LDI R16 , 0x00 ; печать символа '0' |
;| RCALL LCD_CHAR |
;| |
;| LDI R16 , 0x10 ; печать символа ' ' (пробел) |
;| RCALL LCD_CHAR |
;| |
;| ; позиционирование печати | |
;| LDI R18 , 2 ;(Y) 3 строка (отсчет с 0) |
;| LDI R17 , 40 ;(X) 41 линия по горизонтали |
;| RCALL LCD_POS |
;| |
;| LDI R16 , 0x0F ; печать символа 'F' |
;| RCALL LCD_CHAR |
;| |
;| . . . . . продолжение программы . . . . . |
;| |
;|LOOP: |
;| rjmp LOOP ; пустой цикл (останов) |
;| |
;|.include "lcd5110mini.asm" ; подключение этой библиотеки |
;+--------------------------------------------------------------+
;
;
;
;2. ПОДКЛЮЧЕНИЕ ДИСПЛЕЯ И НАСТРОЙКА БИБЛИОТЕКИ
;
; --------------------------------------------------------------------------------------------
;
; ВНИМАНИЕ !
; Обычно эти дисплеи питаются от 3.3 вольт, если вам необходимо питать дисплей от
; источника 5 вольт - поставьте последовательно с линией питаний два-три диода !
;
; +---------------------+
; | подключение дисплея |
; +---------------------+
; Укажите к пинам каких портов подключены линии управления дисплеем:
; В примере ниже подключение произведено к порту D (порт вывода PORTD; порт настройки DDRD)
; соответственно, например для порта A это будут PORTA и DDRA, и так же для других портов)
;
; Линия управления сбросом дисплея (RST, RES. RESET)
.equ RSTPORT =PORTC ; порт к которому подключен сигнал RST (RES, RESET)
.equ RSTDDR =DDRC
.equ RSTPIN =2 ; номер пина порта
; Линия последовательных данных дисплея (MOSI, DI)
.equ MOSIPORT =PORTC ; порт к которому подключен сигнал MOSI (или DI)
.equ MOSIDDR =DDRC
.equ MOSIPIN =1 ; номер пина порта
; Линия управления видом данные\команды (DC, D/C)
.equ DCPORT =PORTC ; порт к которому подключен сигнал DC (D/C)
.equ DCDDR =DDRC
.equ DCPIN =4 ; номер пина порта
; Линия тактирования данных (CLK, SCK, CLOCK)
.equ CLKPORT =PORTC ; порт к которому подключен сигнал CLK (SCK, CLOCK)
.equ CLKDDR =DDRC
.equ CLKPIN =0 ; номер пина порта
; Линию выбора дисплея SCE (CS) дисплея подключить на землю !
;
; Теперь после подключения дисплея нужно выбрать нужный вариант инициализации портов ввода вывода
;
; Если все линии управления (RST, MOSI, DC, CLK) подключены к одному порту ввода\вывода
; то расскоментируйте ниже DDR_ONE_LINE, иначе раскоментируйте DDR_MULTI_LINE
;
; работать модуль будет с любым из вариантов, но имейте ввиду что вариант DDR_ONE_LINE
; даст меньший размер кода при компиляции чем вариант DDR_MULTU_LINE на 2 байта
;
;
; ВНИМАНИЕ! Ниже используется инициализация при подключении дисплея к пинам одного порта !
; поэтому расскомментирован вариант DDR_ONE_LINE !!!
.MACRO DDR_INIT
DDR_ONE_LINE ; разбивка по пинам одного порта
; DDR_MULTI_LINE ; разбивка по пинам разных портов
.ENDMACRO
; Строка инициализации дисплея, не меняйте ее если не знаете что делаете !
; последовательность инициализации для Nokia 5110, 3310
LCD_INIT_STR: .DB 0x21, 0xC2, 0x06, 0x13, 0x20, 0x0C, 0x80, 0x40
//LCD_INIT_STR: .DB 0x21, 0x13, 0x04, 0xB8, 0x20, 0x0C//, 0x80, 0x40
.equ LCD_INIT_LEN = 8 ; количество байт инициализации
; строка инициализации для Simens C55 (лично не проверял!)
;LCD_INIT_STR: .DB 0x21, 0x09, 0xE0, 0x16, 0x06, 0x20, 0x0C, 0x80, 0x40
;.equ LCD_INIT_LEN = 9 ; количество байт инициализации
;========================= ДАЛЕЕ НАСТРАИВАЕМЫХ ПАРАМЕТРОВ НЕТ !!! ============================
.MACRO DDR_ONE_LINE ; разбивка по пинам одного порта
; RST MOSI DC SCK
in R16 , RSTDDR
ori R16 , (1<<RSTPIN)|(1<<MOSIPIN)|(1<<DCPIN)|(1<<CLKPIN)
out MOSIDDR , R16
.ENDMACRO
.MACRO DDR_MULTI_LINE ; разбивка по пинам разных портов
sbi RSTDDR , RSTPIN
sbi MOSIDDR , MOSIPIN
sbi DCDDR , DCPIN
sbi CLKDDR , CLKPIN
.ENDMACRO
LCD_INIT: ; -------------------------------------------------------------- инициализация LCD
DDR_INIT ; инициализация линий порта управления
; сброс дисплея
cbi RSTPORT , RSTPIN ; RST=0
ldi ZL , low (LCD_INIT_STR*2) ; адрес строки инициализации
sbi RSTPORT , RSTPIN ; RST=1
ldi ZH , high(LCD_INIT_STR*2)
ldi R17 , LCD_INIT_LEN ; размер строки инициализации
cbi DCPORT , DCPIN ; DC=0 передаем команды
LCD_INIT_loop: ; отправка строки инициализации на дисплей
lpm R16 , Z+
rcall LCD_SENDBYTE
dec R17
brne LCD_INIT_loop
sbi DCPORT , DCPIN ; DC=1 передаем данные
LCDCLR: clr R16 ; очистка экрана
ldi R17 , 252
LCD_INIT_CLR_loop: rcall LCD_SENDBYTE
rcall LCD_SENDBYTE
DEC R17
BRNE LCD_INIT_CLR_loop
ret
LCD_POS: ;---------------------------------------------------------------- позиционирование
; R17=X R18=Y
push R16
cbi DCPORT , DCPIN ; DC=0
; ldi R16 , 0x20 ; стандартный режим команд
; rcall LCD_SENDBYTE
ldi R16 , 0x80
add R16 , R17 ; X координата
rcall LCD_SENDBYTE
ldi R16 , 0x40
add R16 , R18 ; Y координата
rcall LCD_SENDBYTE
pop R16
ret
LCD_SENDBYTE: ;---------------------------------------- отправка байта на дисплей (R16 байт)
push R17
push R16
ldi R17 , 8 ; количество бит в байте
LCD_SENDBYTE_loop:
cbi MOSIPORT , MOSIPIN ; mosi=0
sbrc R16 , 7
sbi MOSIPORT , MOSIPIN ; mosi=1
sbi CLKPORT , CLKPIN ; sck=1
lsl R16
cbi CLKPORT , CLKPIN ; sck=0
dec R17
brne LCD_SENDBYTE_loop
pop R16
pop R17
ret
LCD_CHAR: ; ------------------------------------------------------------------ ВЫВОД СИМВОЛА
; R16 - символ
push ZL
push ZH
push R17
sbi DCPORT , DCPIN ; DC=1
LDI ZL , low (lcd_charset*2)
LDI ZH , high(lcd_charset*2)
LDI R17 , 0
LSL R16
LSL R16
ADD ZL , R16
ADC ZH , R17
LDI R17 , 4
LCD_CHAR_LOOP: ; отправка символа на экран
LPM R16 , Z+
RCALL LCD_SENDBYTE
DEC R17
BRNE LCD_CHAR_LOOP
CLR R16 ; пробел между символами
RCALL LCD_SENDBYTE
pop R17
pop ZH
pop ZL
RET
lcd_charset: ; -------------------------------------- минимальный набор символов для вывода
.db 0x3E, 0x41, 0x41, 0x3E ; 0
.db 0x44, 0x42, 0x7F, 0x40 ; 1
.db 0x42, 0x61, 0x51, 0x4E ; 2
.db 0x22, 0x41, 0x49, 0x36 ; 3
.db 0x1C, 0x12, 0x79, 0x10 ; 4
.db 0x27, 0x45, 0x45, 0x39 ; 5
.db 0x3E, 0x49, 0x49, 0x32 ; 6
.db 0x01, 0x71, 0x09, 0x07 ; 7
.db 0x36, 0x49, 0x49, 0x36 ; 8
.db 0x26, 0x49, 0x49, 0x3E ; 9
.db 0x7C, 0x12, 0x11, 0x7E ; A
.db 0x7F, 0x49, 0x49, 0x36 ; B
.db 0x3E, 0x41, 0x41, 0x22 ; C
.db 0x7F, 0x41, 0x22, 0x1C ; D
.db 0x7F, 0x49, 0x49, 0x49 ; E
.db 0x7F, 0x09, 0x09, 0x01 ; F
.db 0x00, 0x00, 0x00, 0x00 ; пробел
.db 0b00001000, 0b00011100, 0b00001000, 0b00000000 ; 17 +