Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.84/209: Рейтинг темы: голосов - 209, средняя оценка - 4.84
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
1

HD44780+ATMega16+ASM

05.11.2014, 12:06. Просмотров 37769. Ответов 96
Метки нет (Все метки)

Писал когда то програмку для выводов символов на ЖКИ. Раньше работала. Решил тут недавно добавить функции из этой программы в другую - не выводятся символы. Залил старую программу - тоже не фига не выводится. только горят верхние квадраты в верхней строчке (регулировка контраста не помогает). То ли что то изменил, то ли звезды не так сложились.. Ни в реальном железе (Pinboard2), ни в протеусе работать не хочет. Может подскажет кто-где ошибка?
Сам код:
.include "m16def.yms" ; ATMiko16

//--------------------------------
.DSEG

.def temp=R16

.equ LCD_PORT = PORTA
.equ LCD_DDR = DDRA
.equ LCD_PIN = PINA

.equ D4 = 0
.equ D5 = 1
.equ D6 = 2
.equ D7 = 3

.equ RS = 4
.equ EN = 5

//---------------------------------
//-----------------------------------------------
.CSEG

.ORG $0000
RJMP INIT

//Инициализация МК-------------------------------
INIT:
//Инициализация стека----------
ldi r16,low(ROMend)
out SPL,r16
ldi r16,high(ROMend)
out SPH,r16
//-----------------------------

//Инициализация дисплея
RCALL LCD_INIT
RCALL WAIT_100us

LDI temp, 0b10000000 //Адрес DDROM - 0x00 (первая строка)
RCALL Two

LDI temp, 0xb1
RCALL WrData
RCALL WAIT_100us

LDI temp, M
RCALL WrData
RCALL WAIT_100us
//---------------------------------

LDI temp, 0b11000000 //Адрес DDROM - 0x40 (вторая строка)
RCALL Two

LDI temp, M
RCALL WrData
RCALL WAIT_100us

STOP:
NOP
RJMP STOP

//------------------------------------------------
//Подпрограммы------------------------------------

//---------------------------------
LCD_INIT:
RCALL WAIT_20ms
sbi LCD_DDR, D4 ;Ножки порта на выход
sbi LCD_DDR, D5
sbi LCD_DDR, D6
sbi LCD_DDR, D7

sbi LCD_DDR, RS
sbi LCD_DDR, EN

cbi LCD_PORT, RS ;оистить значение RS, EN
cbi LCD_PORT, EN
RCALL WAIT_100us

LDI temp, 0b00000011
RCALL One ;Начальная инициализация
RCALL WAIT_100us
LDI temp, 0b00000011
RCALL One ;вызывается
RCALL WAIT_100us
LDI temp, 0b00000011
RCALL One ;три раза
RCALL WAIT_100us

LDI temp, 0b00000010 ;4x битный режим
RCALL One
RCALL WAIT_100us

LDI temp, 0x28 ;2 строки 5х7
RCALL Two
RCALL WAIT_100us

LDI temp, 0x06 ;автоинкремент счетчика DDROM
RCALL Two
RCALL WAIT_100us

LDI temp, 0x0c ;Дисплей вкл, курсор выкл
RCALL Two
RCALL WAIT_100us

LDI temp, 0x01 ;очистить LCD
RCALL Two
RCALL WAIT_5ms

LDI temp, 0x06 ;очистить LCD
RCALL Two
RCALL WAIT_5ms

RET

//----------------------------------
WrData:
CLR R17 ;Чистим R17
SBR R17, 0b00010000 ;Установим 5 бит в R17 (RS=1 запись данных)
RJMP TwoData
RET

Two: ;Записать в дисплей
CLR R17
TwoData:
PUSH R16 ;Загрузка значения в стек
SWAP R16 ;поменяли полубайты местами
ANDI temp, 0b00001111 ;маскируем старшую часть байта
OR temp, R17 ;объединяем младшую часть байта и R17
OUT LCD_PORT, temp ;выводим получившееся значение в порт
NOP
NOP
NOP

SBI LCD_PORT, EN ;начало строба
NOP
NOP
NOP
NOP
NOP
CBI LCD_PORT, EN ;конец строба

RCALL WAIT_100us
NOP
POP R16 ;вытащили оригинал данных из стека
ANDI temp, 0b00001111 ;замаскировали старшие полубайты
OR temp, R17 ;объединили два регистра

One:
OUT LCD_PORT, temp ;вывели получившееся значение в порт
NOP
NOP
NOP

SBI LCD_PORT, EN ;начало строба
NOP
NOP
NOP
NOP
NOP
NOP
CBI LCD_PORT, EN ;конец строба
RCALL WAIT_100us ;задержка

RET

//----------------------------------
//Подпрограммы задержки

WAIT_20ms:
; =============================
; delay loop generator
; 160000 cycles:
; -----------------------------
; delaying 159975 cycles:
ldi R17, $E1
WGLOOP01: ldi R18, $EC
WGLOOP11: dec R18
brne WGLOOP11
dec R17
brne WGLOOP01
; -----------------------------
; delaying 24 cycles:
ldi R17, $08
WGLOOP21: dec R17
brne WGLOOP21
; -----------------------------
; delaying 1 cycle:
nop
; =============================

RET

//----------------------------------

WAIT_5ms: ;Расчет делался в программе
; =============================
; delay loop generator
; 40000 cycles:
; -----------------------------
; delaying 39999 cycles:
ldi R17, $43
WGLOOP02: ldi R18, $C6
WGLOOP12: dec R18
brne WGLOOP12
dec R17
brne WGLOOP02
; -----------------------------
; delaying 1 cycle:
nop
; =============================

RET

//----------------------------------
WAIT_100us:
; =============================
; delay loop generator
; 800 cycles:
; -----------------------------
; delaying 798 cycles:
ldi R17, $02
WGLOOP03: ldi R18, $84
WGLOOP13: dec R18
brne WGLOOP13
dec R17
brne WGLOOP03
; -----------------------------
; delaying 2 cycles:
nop
nop
; =============================

RET


[44.35 Кб]
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.11.2014, 12:06
Ответы с готовыми решениями:

Работа с дисплеем HD44780 в Протеус (ATMega16, ASM)
Писал когда то програмку для выводов символов на ЖКИ. Раньше работала. Решил тут недавно добавить...

Дисплей HD44780 и Atmega16
Написал код для вывода текста на дисплей HD44780 через мегу16 и все работало и строки выводил пока...

Работа с LCD дисплеем HD44780 из МК Atmega16 (GCC)
Здравствуйте, пытаюсь подключить LCD дисплей к микроконтроллеру, скачал библиотеку, но уже на...

По нажатию кнопки вывести данные на дисплей HD44780 ATMega16 AVR Studio GCC
Здравствуйте, уважаемые любители-программисты. Нуждаюсь в небольшой помощи по программированию...

Не работает USART ATMega16 (asm)
Пытаюсь тут сделать прием данных по усарту. В дальнейшем планировалось сделать вывод строки...

96
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
05.11.2014, 13:06 2
RW на минус посади.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
05.11.2014, 13:10 3
Цитата Сообщение от avr_bikymmir
Может подскажет кто-где ошибка?
В задержке «WAIT_100us» у Вас ломается R17, В котором Вы держите «RS», сохраните его в стэке или выберите другой регистр.

0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
05.11.2014, 14:05 4
Цитата Сообщение от tyzord66
В задержке «WAIT_100us» у Вас ломается R17, В котором Вы держите «RS», сохраните его в стэке или выберите другой регистр.
Спасибо огромное. Сам бы, наверно, очень долго искал бы ошибку. Я так понял, что лучше всегда в стэке сохранять регистры на всякий случай.
И не понятно - судя по скрину, у вас русские буквы протеус нормально выводит. У меня вместо "Я" кракозябра выводится..
0
05.11.2014, 14:05
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
05.11.2014, 15:57 5
Цитата Сообщение от avr_bikymmir
И не понятно - судя по скрину, у вас русские буквы протеус нормально выводит. У меня вместо "Я" кракозябра выводится..
Замените:

[52.8 Кб]
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
06.11.2014, 07:24 6
Цитата Сообщение от tyzord66
Замените:
И еще раз благодарю!
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
08.11.2014, 07:20 7
Решил доработать программу, используя проверку бита занятости. Инициализация в ней проходит точно, но при выводе символа, если не использовать ручную задержку, не показывает первый символ. Если поставить задержку после вывода первого символа - не выводится следующий, ну и т.д. В чем может быть проблема?

Код:.include "m16def.yms" ; ATMiko16

//--------------------------------
.DSEG

.def temp=R16
.def RS_1=R20

.equ LCD_PORT = PORTA
.equ LCD_DDR = DDRA
.equ LCD_PIN = PINA

.equ D4 = 0
.equ D5 = 1
.equ D6 = 2
.equ D7 = 3

.equ RS = 4
.equ EN = 5
.equ RW = 6

//---------------------------------
//-----------------------------------------------
.CSEG

.ORG $0000
RJMP INIT

//Инициализация МК-------------------------------
INIT:
//Инициализация стека----------
ldi r16,low(ROMend)
out SPL,r16
ldi r16,high(ROMend)
out SPH,r16
//-----------------------------

//Инициализация дисплея
RCALL LCD_INIT

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0b10000000 //Адрес DDROM - 0x00 (первая строка)
RCALL Cmd
; RCALL WAIT_100us

RCALL BusyWoyt
RCALL Port_Out
LDI temp, H;0xb1
RCALL WrData
; RCALL WAIT_100us

RCALL BusyWoyt
RCALL Port_Out
LDI temp, M
RCALL WrData

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0b11000000 //Адрес DDROM - 0x40 (вторая строка)
RCALL Cmd

RCALL BusyWoyt
RCALL Port_Out
LDI temp, N
RCALL WrData

STOP:
NOP
RJMP STOP

//------------------------------------------------
//Подпрограммы------------------------------------

//---------------------------------
LCD_INIT:
SBI LCD_DDR, D4 ;Ножки порта на выход
SBI LCD_DDR, D5
SBI LCD_DDR, D6
SBI LCD_DDR, D7

SBI LCD_DDR, RS
SBI LCD_DDR, EN
SBI LCD_DDR, RW

CBI LCD_PORT, RS ;оистить значение RS, EN
CBI LCD_PORT, EN
CBI LCD_PORT, RW

RCALL WAIT_20ms
LDI temp, 0b00000011
RCALL One ;Начальная инициализация
RCALL WAIT_100us

LDI temp, 0b00000011
RCALL One ;вызывается
RCALL WAIT_100us

LDI temp, 0b00000011
RCALL One ;три раза
RCALL WAIT_100us

LDI temp, 0b00000010 ;4x битный режим
RCALL One
RCALL WAIT_100us

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0x28 ;2 строки 5х7
RCALL Cmd

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0x06 ;автоинкремент счетчика DDROM
RCALL Cmd

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0x0c ;Дисплей вкл, курсор выкл
RCALL Cmd

RCALL BusyWoyt
RCALL Port_Out
LDI temp, 0x01 ;очистить LCD
RCALL Cmd

RET

//----------------------------------
WrData:
CLR RS_1 ;Чистим регистр для установки бита RS
SBR RS_1, 0b00010000 ;Установим 5 бит в R17 (потом будет RS=1)
RJMP TwoData
RET

Cmd: ;Записать в дисплей
CLR RS_1
TwoData:
PUSH R16 ;Загрузка значения в стек
SWAP R16 ;поменяли полубайты местами

ANDI temp, 0b00001111 ;маскируем старшую часть байта
OR temp, RS_1 ;объединяем младшую часть байта и R17 (RS=1 запись данных)
OUT LCD_PORT, temp ;выводим получившееся значение в порт
NOP
NOP

;Стробирующий импульс
SBI LCD_PORT, EN ;начало строба
NOP
NOP
NOP
NOP
CBI LCD_PORT, EN ;конец строба

POP R16 ;вытащили оригинал данных из стека
ANDI temp, 0b00001111 ;замаскировали старшие полубайты
OR temp, RS_1 ;объединили два регистра

One:
OUT LCD_PORT, temp ;вывели получившееся значение в порт
NOP
NOP

SBI LCD_PORT, EN ;начало строба
NOP
NOP
NOP
NOP
CBI LCD_PORT, EN ;конец строба

RET

;Определение готовности дисплея
;Чтение бита готовности
BusyWoyt:
CLI ; Ожидаем флаг занятости
CBI LCD_PORT,RS ; Команда(RS=0)
SBI LCD_PORT,RW ; Читаем (RW=1)

BusyLoop:
RCALL PortIn ; Порты на вход
SBI LCD_PORT,EN ; EN = 1
RCALL En_Pouse

IN temp, LCD_PIN ; Чтение порта

PUSH temp

CBI LCD_PORT,EN ;EN=0
NOP
NOP
NOP
NOP

SBI LCD_PORT,EN ; EN = 1
RCALL En_Pouse

CBI LCD_PORT,EN ;EN=0
RCALL En_Pouse

POP R16 ;Достаем считанный байт. В нем должен быть бит готовности

ANDI R16, 0x80 ; (0b10000000) Маскируем старший бит - бит готовности
CPI temp, 0x80
BREQ BusyLoop ; Если бит не установлен - читаем порт опять

SEI ; разрешаем прерывания
RET

;Инициализация DB7..DB4 на вход
PortIn:
IN R16, LCD_DDR ; Динные из DDR в регистр
ANDI R16, 0xf0 ; (0b00001111)Обнуляем старшие 4 бита
OUT LCD_DDR, R16 ; DB4..DB7 на вход

IN R16, LCD_PORT ; читаем значение порта
ANDI R16, 0xF0 ; (0b11110000) порт данных Вход Hi-Z
OUT LCD_PORT, R16 ; Вывести в порт
RET
;Инициализация DB7..DB4 на выход
Port_Out:
IN R16, LCD_DDR ; Состояние DDR в регистр
ORI R16, 0x0F ; выставили все младшие биты в 1
OUT LCD_DDR, R16 ; Вывели в порт

RET

//----------------------------------
//Подпрограммы задержки

WAIT_20ms:
; =============================
; delay loop generator
; 160000 cycles:
; -----------------------------
; delaying 159975 cycles:
ldi R17, $E1
WGLOOP01: ldi R18, $EC
WGLOOP11: dec R18
brne WGLOOP11
dec R17
brne WGLOOP01
; -----------------------------
; delaying 24 cycles:
ldi R17, $08
WGLOOP21: dec R17
brne WGLOOP21
; -----------------------------
; delaying 1 cycle:
nop
; =============================

RET

//----------------------------------

WAIT_5ms: ;Расчет делался в программе
; =============================
; delay loop generator
; 40000 cycles:
; -----------------------------
; delaying 39999 cycles:
ldi R17, $43
WGLOOP02: ldi R18, $C6
WGLOOP12: dec R18
brne WGLOOP12
dec R17
brne WGLOOP02
; -----------------------------
; delaying 1 cycle:
nop
; =============================

RET

//----------------------------------
WAIT_100us:
; =============================
; delay loop generator
; 800 cycles:
; -----------------------------
; delaying 798 cycles:
ldi R17, $02
WGLOOP03: ldi R18, $84
WGLOOP13: dec R18
brne WGLOOP13
dec R17
brne WGLOOP03
; -----------------------------
; delaying 2 cycles:
nop
nop
; =============================

RET

;Пауза для стробирующего импульса
En_Pouse:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
Вот что получается:


Кстати в реальном железе, на пинбоарде, ни первая программа, ни вторая не работают почему то

[161.38 Кб]
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
08.11.2014, 10:31 8
Не вникая глубоко в код, не мешает RW индикатора к PA6 подключить (по схеме)
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
08.11.2014, 12:54 9
Цитата Сообщение от tyzord66
Не вникая глубоко в код, не мешает RW индикатора к PA6 подключить (по схеме)
Прошу прощения. Это в процессе различных проб не исправил. С подключенным RW тоже самое.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
08.11.2014, 14:03 10
При чтении необходимо придерживаться правила 4х битного режима, те необходимо читать оба ниббла, при этом «BF» Вы получите только после чтения второго ниббла и в Вашем случае это будет не 7й бит, а 3й.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
08.11.2014, 16:37 11
Цитата Сообщение от tyzord66
При чтении необходимо придерживаться правила 4х битного режима, те необходимо читать оба ниббла, при этом «BF» Вы получите только после чтения второго ниббла и в Вашем случае это будет не 7й бит, а 3й.
Что то не придумал ничего другого, кроме такого варианта. Не хочет работать все равно. Больше в голову ничего не приходит.
Код
BusyWoyt:
CLI                  ; Ожидаем флаг занятости
RCALL   PortIn         ; Порты на вход
;1
CBI      LCD_PORT,RS      ; Команда(RS=0)
;2
SBI      LCD_PORT,RW      ; Читаем (RW=1)

BusyLoop:
;3
SBI      LCD_PORT,EN      ; EN = 1
RCALL    En_Pouse

;4
IN      temp,   LCD_PIN      ; Чтение порта

;5
CBI      LCD_PORT,EN      ;EN=0
NOP
NOP
NOP
NOP

;6
SBI      LCD_PORT,EN      ; EN = 1
RCALL    En_Pouse

;7
IN      temp,   LCD_PIN      ;Достаем считанный байт

;8
CBI      LCD_PORT,EN      ;EN=0
RCALL    En_Pouse

;9
CBI      LCD_PORT,RW      ; (RW=0)

SWAP    R16            ;поменяли полубайты местами
ANDI   R16,   0b00001000          ; Маскируем старший бит - бит готовности
CPI      temp,    0b000001000
BREQ   BusyLoop      ; Если бит не установлен - читаем порт опять

SEI                  ; разрешаем прерывания
RET

PortIn:
IN   R16,      LCD_DDR      ; Динные из DDR в регистр
ANDI   R16,      0x00
OUT   LCD_DDR,   R16

IN      R16,   LCD_PORT   ; читаем значение порта
ANDI   R16,   0x00              ;  порт данных Вход Hi-Z
OUT      LCD_PORT,   R16         ; Вывести в порт
RET

Port_Out:
IN      R16,      LCD_DDR
ORI      R16,      0xfF
OUT      LCD_DDR,   R16

RET
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
08.11.2014, 20:20 12
Это код как раз с проверкой готовности.

[1.58 Кб]
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
09.11.2014, 05:13 13
Цитата Сообщение от YTYOUT
Это код как раз с проверкой готовности.
Немного непонятен ваш алгоритм проверки готовности. Прошу объяснить..

И самое непонятное для меня.. Тут вы вручную устанавливаете бит LCD_BUSY, насколько я понял
Код
ldi temp,1<<LCD_BUSY|1<<LCD_RW|0<<LCD_RS
outr LCD_PORT,temp
И после установки вручную как будто проверяете его
Код
BS_WAIT:
sbic   PINB,LCD_BUSY      ; Цикл проверки BS
rjmp   BS_WAIT
Что такое MsbOne в этой строчках?
Код
cbi      LCD_CtrlDDR,MsbOne
Код
sbi      LCD_CtrlDDR,MsbOne   ;+ ПортB переключаем на выход
Для меня непонятно как установкой/очисткой бита можно переключать порт на выход/вход..

И почему программа проверки бита готовности вызывается после записи данных в порт?

Буду благодарен за разъяснения.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
09.11.2014, 07:29 14
Вот рабочий проект, давным-давно баловался. Если что в pattern поправьте с VFD на LCD. Видео

[29.25 Кб]
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
09.11.2014, 09:42 15
avr_bikymmir Посмотрел Ваши коды в студии. Исправил. Наверняка, не всё.
Код
.include "m16def.yms" ; ATMiko16

//--------------------------------
.DSEG

.def temp=R16

.equ   LCD_PORT    = PORTA
.equ   LCD_DDR      = DDRA
.equ    LCD_PIN      = PINA

.equ   D4       = 0
.equ   D5       = 1
.equ    D6       = 2
.equ   D7       = 3

.equ   RS      = 4
.equ   EN      = 5
.equ   RW      = 6

//---------------------------------
//-----------------------------------------------
.CSEG

.ORG $0000
;RJMP INIT

//Инициализация МК-------------------------------
INIT:
//Инициализация стека----------
ldi r16,low(ROMend)
out SPL,r16
ldi r16,high(ROMend)
out SPH,r16
//-----------------------------
CLR      ZH
//Инициализация дисплея
RCALL    LCD_INIT
RCALL   WAIT_100us

LDI temp, 0b10000000      //Адрес DDROM - 0x00 (первая строка)
RCALL    Two

LDI    temp, 0xb1
RCALL WrData
;   RCALL   WAIT_100us

LDI    temp, M
RCALL WrData
;   RCALL   WAIT_100us
//---------------------------------

LDI temp, 0b11000000      //Адрес DDROM - 0x40 (вторая строка)
RCALL    Two

LDI    temp, M
RCALL WrData
;   RCALL   WAIT_100us

STOP:
NOP
RJMP STOP

//------------------------------------------------
//Подпрограммы------------------------------------

//---------------------------------
LCD_INIT:
RCALL   WAIT_20ms
LDI      R16,$FF
OUT      LCD_DDR,R16
;   sbi      LCD_DDR, D4            ;Ножки порта на выход
;   sbi      LCD_DDR, D5
;   sbi      LCD_DDR, D6
;   sbi      LCD_DDR, D7

;   sbi      LCD_DDR, RS
;   sbi      LCD_DDR, EN
;*************************************************
;   SBI      LCD_DDR,RW
;*************************************************
cbi      LCD_PORT, RS         ;оистить значение RS, EN
cbi      LCD_PORT, EN
;*************************************************
CBI      LCD_PORT,RW
;*************************************************

;   RCALL    WAIT_100us

LDI    temp, 0b00000011
RCALL    One                  ;Начальная инициализация
RCALL   WAIT_5ms
;   RCALL   WAIT_100us
;   LDI    temp, 0b00000011
RCALL    One                  ;вызывается
RCALL   WAIT_100us
;   LDI    temp, 0b00000011
RCALL    One                  ;три раза
RCALL   WAIT_100us

LDI    temp, 0b00000010      ;4x битный режим
RCALL    One
RCALL   WAIT_100us

LDI    temp, 0x28            ;2 строки 5х7
RCALL    Two
RCALL   WAIT_100us

LDI    temp, 0x06            ;автоинкремент счетчика DDROM
RCALL    Two
RCALL   WAIT_100us

LDI    temp, 0x0c            ;Дисплей вкл, курсор выкл
RCALL    Two
RCALL   WAIT_100us

LDI    temp, 0x01            ;очистить LCD
RCALL    Two
RCALL   WAIT_5ms

LDI    temp, 0x06            ;очистить LCD
RCALL    Two
RCALL   WAIT_5ms

RET

//----------------------------------
WrData:
CLR    R17                  ;Чистим R17
SBR    R17, 0b00010000         ;Установим 5 бит в R17 (RS=1 запись данных)
RJMP    TwoData
RET

Two:                           ;Записать в дисплей
CLR    R17
TwoData:
RCALL   BusyWoyt

PUSH    R16                     ;Загрузка значения в стек
SWAP    R16                     ;поменяли полубайты местами
ANDI    temp, 0b00001111         ;маскируем старшую часть байта
OR       temp, R17               ;объединяем младшую часть байта и R17
OUT     LCD_PORT, temp            ;выводим получившееся значение в порт
RCALL   PAUSE_RET
;   NOP
;   NOP
;   NOP

SBI      LCD_PORT, EN            ;начало строба
RCALL   PAUSE_RET
;   NOP
;   NOP
;   NOP
;   NOP
;   NOP
CBI    LCD_PORT, EN            ;конец строба

RCALL   WAIT_100us
NOP
POP    R16                     ;вытащили оригинал данных из стека
ANDI    temp, 0b00001111         ;замаскировали старшие полубайты
OR       temp, R17               ;объединили два регистра

One:
OUT     LCD_PORT, temp            ;вывели получившееся значение в порт
RCALL   PAUSE_RET
SBI      LCD_PORT, EN            ;начало строба
RCALL   PAUSE_RET
CBI    LCD_PORT, EN            ;конец строба

RET
//----------------------------------
//Подпрограммы задержки
WAIT_20ms:
; =============================
;    delay loop generator
;     160000 cycles:
; -----------------------------
; delaying 159975 cycles:
ldi  R17, $E1
WGLOOP01:  ldi  R18, $EC
WGLOOP11:  dec  R18
brne WGLOOP11
dec  R17
brne WGLOOP01
; -----------------------------
; delaying 24 cycles:
ldi  R17, $08
WGLOOP21:  dec  R17
brne WGLOOP21
; -----------------------------
; delaying 1 cycle:
nop
; =============================

RET

//----------------------------------

WAIT_5ms:                        ;Расчет делался в программе
; =============================
;    delay loop generator
;     40000 cycles:
; -----------------------------
; delaying 39999 cycles:
ldi  R17, $43
WGLOOP02:  ldi  R18, $C6
WGLOOP12:  dec  R18
brne WGLOOP12
dec  R17
brne WGLOOP02
; -----------------------------
; delaying 1 cycle:
nop
; =============================
PAUSE_RET:

RET

//----------------------------------
WAIT_100us:
; =============================
;    delay loop generator
;     800 cycles:
; -----------------------------
; delaying 798 cycles:
ldi  R17, $02
WGLOOP03:  ldi  R18, $84
WGLOOP13:  dec  R18
brne WGLOOP13
dec  R17
brne WGLOOP03
; -----------------------------
; delaying 2 cycles:
nop
nop
; =============================

RET

BusyWoyt:
;   CLI                  ; Ожидаем флаг занятости

CBI      LCD_DDR, D4            ;Ножки порта на выход
CBI      LCD_DDR, D5
CBI      LCD_DDR, D6
CBI      LCD_DDR, D7

;   RCALL   PortIn         ; Порты на вход
;1
CBI      LCD_PORT,RS      ; Команда(RS=0)
;2
SBI      LCD_PORT,RW      ; Читаем (RW=1)

BusyLoop:
;3
SBI      LCD_PORT,EN      ; EN = 1
RCALL    PAUSE_RET
;   RCALL    En_Pouse
;4
IN      R20,LCD_PIN      ; Чтение порта

;5
CBI      LCD_PORT,EN      ;EN=0
NOP
NOP
NOP
NOP

;6
SBI      LCD_PORT,EN      ; EN = 1
RCALL    PAUSE_RET
;   RCALL    En_Pouse

;7
IN      R21,LCD_PIN      ;Достаем считанный байт

;8
CBI      LCD_PORT,EN      ;EN=0
RCALL    PAUSE_RET
;   RCALL    En_Pouse

;9
;   CBI      LCD_PORT,RW      ; (RW=0)

SBRC   R20,3
RJMP   BusyLoop

;   SWAP    R16            ;поменяли полубайты местами
;   ANDI   R16,   0b00001000          ; Маскируем старший бит - бит готовности
;   CPI      temp,    0b000001000
;   BREQ   BusyLoop      ; Если бит не установлен - читаем порт опять

;   SEI                  ; разрешаем прерывания
RET

PortIn:
IN   R16,      LCD_DDR      ; Динные из DDR в регистр
ANDI   R16,      0x00
OUT   LCD_DDR,   R16

IN      R16,   LCD_PORT   ; читаем значение порта
ANDI   R16,   0x00              ;  порт данных Вход Hi-Z
OUT      LCD_PORT,   R16         ; Вывести в порт
RET

Port_Out:
IN      R16,      LCD_DDR
ORI      R16,      0xfF
OUT      LCD_DDR,   R16

RET
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
09.11.2014, 11:31 16
Цитата Сообщение от dymyurk1978
Вот рабочий проект, давным-давно баловался. Если что в pattern поправьте с VFD на LCD. Видео
А можно сам проект увидеть?
Цитата Сообщение от okt
avr_bikymmir Посмотрел Ваши коды в студии. Исправил. Наверняка, не всё.
В принципе, прям принципиальное отличие, нашел в одном месте. Вот в этой строке и всем, что относится к ней.
Код
SBRC   R20,3
Наверно это как раз таки основная ошибка. Дома проверю. Спасибо.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.11.2014, 11:48 17
Код
;***************************************
;-  Woyt BS   для ускорения вывода на LCD
;***************************************
Woyt_BS:   ;/ Установка режима   чтения BS
cbi      LCD_Port,LCD_E      ;" Записываем данные в LCD ( Эта команда записи второго полубайта данных ( опять таки избавиться от nop ибо переход 2 такта занимает)
cbi      LCD_CtrlDDR,MsbOne ( MsbOne (старший бит)  - переключает pin для проверки ЗАНЯТ на вход)
ldi      temp,1<<LCD_BUSY|1<<LCD_RW|0<<LCD_RS (Включаем поддтяжку на pin проверки т.е подключаем pullup резистор ко входу, и режим проверки устанавливаем RW=1 , RS=0
outr   LCD_PORT,temp
Вот тут немного ждём
nop                     ;/ Для частоты 18.432 Мгц нужно не менее
nop
nop                     ;/ (3-х) команд NOP !!
nop
sbi      LCD_PORT,LCD_E      ; Установить (Е )
немного ждем
nop
nop
Собственно проверяем
BS_WAIT:
sbic   PINB,LCD_BUSY      ; Цикл проверки BS
rjmp   BS_WAIT
sbi      LCD_CtrlDDR,MsbOne   ;+ ПортB переключаем на выход
ret
Собственно от тут немного ждём и ещё немного диаграмма на Ваш дисплей описанная в его DS.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
09.11.2014, 12:13 18
Архив добавил. ЖКИ подключен по 4 битной шине питания. Без чтения флага занятости. Вывод ЖКИ RW на минус. Вывод на дисплей делается следующим образом: модуль вывода информации на дисплей сделан на КА. Начальное состояние - инициализация дисплея. Дальше модуль посимвольно выплевывает на дисплей информацию. Изначально задумывалось по символу раз в 1 мс. Но, чтобы мультик прокручивало, я закомментировал ожидание. У дисплея минимальная задержка примерно 40 мкс. Если убрать комментирование и woyt_40_us, модуль будет работать раз в 1 мс.
Будут вопросы, спрашивайте.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
09.11.2014, 12:31 19
Цитата Сообщение от dymyurk1978
Архив добавил. ЖКИ подключен по 4 битной шине питания. Без чтения флага занятости.
Вот как раз таки интересует с чтением флага. Без чтения вроде как то заработало (во всяком случае в протеусе)
Цитата Сообщение от YTYOUT
Собственно от тут немного ждём и ещё немного диаграмма на Ваш дисплей описанная в его DS.
Диаграма это понятно. Меня интересует алгоритм проверки флага занятости.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
09.11.2014, 12:35 20
Чтение флага не нужно, если четко соблюдать времянки дисплея. Экономится один вывод МК и нет бесполезного ожидания флага. Можно заниматься другими делами.
0
09.11.2014, 12:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2014, 12:35

Не работают часы на ATMega16 (asm)
Помогите, пожалуйста, начинающему. В качестве первого проекта решил написать програмку часов (так...

Не получается опросить клавиатуру (ATmega16, ASM)
Написал программу для интереса, которая должна при нажатии кнопки которая подключена к порту С7...

Опрос порта на нажатие кнопки (ASM, ATMega16)
Не могу разобраться в чем дело, в моем проекте порт РС настроен как приемник к каждой ножке будет...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru