Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры 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. Просмотров 37605. Ответов 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
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
12.11.2014, 17:23 41
Цитата Сообщение от avr_bikymmir
Блин. Никак не могу написать что то работающее. Уже вроде и в отладчике все работает, а в симуляторе не хочет. Может кому то бросится в глаза какой то очевидный косяк?
Если я не сбился со счета, у Вас уже целых три рабочих примера, один даже под Вашу схему адаптирован.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
12.11.2014, 17:28 42
Цитата Сообщение от YTYOUT
У меня 0х30 и 0x20 , а у Вас 0х03 и 0х02
У Вас же и схема подключния другая.
Цитата Сообщение от tyzord66
Если я не сбился со счета, у Вас уже целых три рабочих примера, один даже под Вашу схему адаптирован.
Хочется досконально понять как все работает. Я разбирался с одной из трех. Вторая без проверки флага. С Вашей я не очень разобрался.
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
12.11.2014, 17:34 43
avr_bikymmir По мне, Вы, наряду с нарушениями временных диаграмм обмена с дисплеем, неправильно пытаетесь считать состояние BF. На основе Вашего кода тронул инициализацию и чтение BF.
Код
.include "m16def.yms" ; ATMiko16

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

.def temp =R16
.def temp1=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

;Вывод символов

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

LDI    temp, H;0xb1
RCALL    WrData

LDI    temp, M
RCALL    WrData

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

LDI    temp, N
RCALL    WrData

STOP:
NOP
RJMP STOP
//------------------------------------------------
//Подпрограммы------------------------------------

//---------------------------------
LCD_INIT:
RCALL   WAIT_20ms
LDI      R16, 0xff
OUT      LCD_DDR,R16

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

RCALL   LCD_INIT_NoWoyt

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

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

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

LDI    temp, 0x01            ;очистить LCD
RCALL    Cmd
PAUSE_RET:
RET

;-----------------------------------
LCD_INIT_NoWoyt:
CBI      LCD_PORT,RS
CBI      LCD_PORT,RW
LDI      R25,$03
LDI      temp,0b00000011      ;Обязательная инициализация 8 битного режима. Вызывается три раза
Cycle_Three:
OUT      LCD_PORT,temp      ;начинаем запись
RCALL   STROB_EN
RCALL   WAIT_20ms

;      SBR      temp,1<<EN
;     OUT      LCD_PORT,temp      ;начинаем запись
;    NOP                  ;ждем время для установки данных на шине
;   NOP
;  NOP
;      NOP
;     NOP
;   CBR   R16,1<<EN

;   CBI      LCD_Port,EN      ;запись данных в  LCD
;      RCALL   WAIT_100us
;     IN      temp,LCD_Port
SUBI   R25,1
BRMI   END_INIT_NoWoyt
BRNE   Cycle_Three
ANDI   temp,0b00000010   ;после этой команды начнет устанавливаться режим 4 бит
RJMP   Cycle_Three
END_INIT_NoWoyt:
RCALL   WAIT_100us
LDI   R16,$02
LDI   R17,$08

OUT      LCD_PORT,R16
RCALL   STROB_EN

OUT      LCD_PORT,R17
RCALL   STROB_EN

RCALL   BusyWoyt

RET
//----------------------------------
WrData:
CLR    temp1               ;Чистим регистр для установки бита RS
SBR    temp1, (1<<RS)      ;Установим 5 бит в R17 (потом будет RS=1)
CBR      temp1, 0<<RW
RJMP    Write
RET
Cmd:                     ;Записать в дисплей
CLR      temp1
OUT      LCD_Port, temp1
Write:
PUSH    temp                  ;Загрузка значения в стек
SWAP    temp                  ;поменяли полубайты местами
ANDI    temp, 0b00001111         ;маскируем старшую часть байта
OR       temp, temp1               ;объединяем младшую часть байта и R17 (RS=1 запись данных)

SBR      temp,1<<EN            ;Начало строба начинается строкой ниже
OUT     LCD_PORT, temp            ;выводим получившееся значение в порт
POP    R16                     ;вытащили оригинал данных из стека
ANDI    temp, 0b00001111         ;замаскировали старшие полубайты
OR       temp, temp1               ;объединили два регистра
CBI      LCD_Port,EN               ;конец строба
SBR      temp, 1<<EN               ;начало строба начинается строкой ниже
NOP
OUT     LCD_PORT, temp            ;вывели получившееся значение в порт
RCALL   BusyWoyt
RET

BusyWoyt:
;Определение готовности дисплея
;Чтение бита готовности
LDI   R21,0b11110000
OUT   DDRA,R21

SBI   LCD_PORT,RW            ;Конец строба. Запись данных в дисплей
;   CBI      LCD_DDR,    D7         ;7 бит на вход
RCALL   PAUSE_RET
RCALL   STROB_EN

MOV   R1,R0

RCALL   PAUSE_RET
RCALL   STROB_EN

;   LDI      temp,       (1<<D7)|(1<<RW)|(0<<RS)   ;
;  OUT      LCD_PORT,   temp
;   NOP
;  NOP
; NOP
;   NOP
;  nop
;   SBI      LCD_PORT,   EN
;  NOP
; NOP
;NOP
;   NOP
;  nop
;   CBI      LCD_PORT,   EN
BusyLoop:
SBRC   R1,3
RJMP   BusyWoyt
CLR      R21
OUT      PORTA,R21
SER      R21
OUT      DDRA,R21

;   SBIC   PINA,D7
;  RJMP   BusyLoop
; SBI    LCD_DDR,   D7
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_100us:
; =============================
;    delay loop generator
;     800 cycles:
; -----------------------------
; delaying 798 cycles:
Push r17
Push R18
ldi  R17, $02
WGLOOP03:  ldi  R18, $84
WGLOOP13:  dec  R18
brne WGLOOP13
dec  R17
brne WGLOOP03
; -----------------------------
; delaying 2 cycles:
nop
nop
; =============================
POP R18
POP R17
RET
;*************************************************
STROB_EN:
RCALL   PAUSE_RET
SBI      LCD_Port,EN      ;запись данных в  LCD
RCALL   PAUSE_RET
CBI      LCD_Port,EN      ;запись данных в  LCD
IN      R0,PINA
RET
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
12.11.2014, 17:40 44
Цитата Сообщение от okt
avr_bikymmir По мне, Вы, наряду с нарушениями временных диаграмм обмена с дисплеем, неправильно пытаетесь считать состояние BF. На основе Вашего кода тронул инициализацию и чтение BF.
Проверку флага по моему полностью взял у YTYOUT. Инициализацию вроде тоже
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
12.11.2014, 17:55 45
Вот как производитель дает проверку BF
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
12.11.2014, 18:05 46
Цитата Сообщение от okt
Вот как производитель дает проверку BF
Вложение:
BF_HD44780.GIF
Вы так человека совсем запутаете, это 8ми битный режим.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
12.11.2014, 18:08 47
Цитата Сообщение от avr_bikymmir
Блин. Никак не могу написать что то работающее. Уже вроде и в отладчике все работает, а в симуляторе не хочет. Может кому то бросится в глаза какой то очевидный косяк?
Так Вы готовности не дождетесь, без какой-либо активности на «EN»

Код
BusyLoop:
SBIC   PINA,D7
RJMP   BusyLoop
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.11.2014, 00:26 48
Это ошибка
Код
CBR   temp1, 0<<RW
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
13.11.2014, 11:53 49
Цитата Сообщение от YTYOUT
Это ошибка
Код:
CBR temp1, 0<<RW
Эту строку убрал. По моему она вообще лишняя.

Цитата Сообщение от tyzord66
Так Вы готовности не дождетесь, без какой-либо активности на «EN»
Сделал так
Код
BusyWoyt:
;Определение готовности дисплея
;Чтение бита готовности
nop
CBI      LCD_PORT,    EN            ;Конец строба. Запись данных в дисплей
CBI      LCD_DDR,    D7         ;7 бит на вход

LDI      temp,       (1<<D7)|(1<<RW)|(0<<RS)   ;
OUT      LCD_PORT,   temp
BusyLoop:
NOP
NOP
NOP
NOP
NOP
SBI      LCD_PORT,   EN
NOP
NOP
NOP
NOP
NOP
CBI      LCD_PORT,   EN
SBIC   PINA,D7
RJMP   BusyLoop
SBI    LCD_DDR,   D7
RET
Не заводится
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.11.2014, 12:08 50
А протеус умеет выдавать бит занятости?
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
13.11.2014, 12:14 51
Ну у tyzord66 работает программа. Вроде через проверку.
Дома попробую в пинбоард залить
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.11.2014, 12:44 52
Грубых ошибок не вижу. Надо проверять в железе.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
13.11.2014, 13:28 53
Цитата Сообщение от YTYOUT
Грубых ошибок не вижу. Надо проверять в железе.
Выводит "N" на втором знакоместе в первой строчке.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
13.11.2014, 19:57 54
Цитата Сообщение от avr_bikymmir
Ну у tyzord66 работает программа. Вроде через проверку.
Дома попробую в пинбоард залить
Чуть раньше я приводил ссылку на ролик, где задействован этот пример.

Можно немного упростить:

[103.83 Кб]
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.11.2014, 23:33 55
Цитата Сообщение от avr_bikymmir
Цитата Сообщение от YTYOUT
Грубых ошибок не вижу. Надо проверять в железе.
Выводит "N" на втором знакоместе в первой строчке.
LDI temp, 0b10000000 //Aa?an DDROM - 0x00 (ia?aay no?iea)
RCALL Cmd
LDI temp, 0b11000000 //Aa?an DDROM - 0x40 (aoi?ay no?iea)
RCALL Cmd
Закомментируй эти строчки . ПРоверь без них
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
13.11.2014, 23:46 56
Столько времени потрачено на то, чтобы проверить программу в Proteus...
Симулятор AVR-Studyo. Осциллограф. За неимением такового светодиоды. Макетка, ЖКИ. Все. Я никогда не проверял свои программы в Proteus. Потому что помимо своих глюков, симуляторы зачастую не показывают реальную картину.
Так что, ТС, прекратите тратить впустую время. Изучили даташит на ЖКИ. Составили алгоритм. Проверили программу в симуляторе AVR-Studyo. Прошили МК, проверили в железе. Не работает, разбираемся почему. Разобрались. Проверили. Все, ваша программа работает. Начали делать следующий проект.
Я мог бы показать один свой проект. 40 файлов. Программа сложная. Да если бы я проверял свой проект в протеус, сидел бы голодным.
Так что, если взялись за изучение МК, осциллограф должен быть. Если ну очень трудно с ним, значить поставить себе задачу в ближайшее же время приобрести его. Это если вы работаете с более-менее сложной периферией. Цифровые МС, ЖКИ, к примеру.
Если задача попроще, светодиодик вам в помощь. И тестовые закладки в программе.
Желаю удачи.
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
14.11.2014, 00:33 57
Суждение псевдопрофессионала:
Цитата Сообщение от dymyurk1978
... Я никогда не проверял свои программы в Proteus. Потому что ... и т. д.
Проверить свои задумки в Proteus никогда не помешает, потом на железе отшлифуется...
Только с Proteus еще и надо уметь работать...
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
14.11.2014, 05:19 58
Цитата Сообщение от YTYOUT
Закомментируй эти строчки . ПРоверь без них
Тоже самое. На самом деле то, что выводится N ни о чем не говорит. Он потом стал выводить L.
Нашел в Proteus вроде как средство для отладки. Он пишет логи инициализации дисплея, как я понял
Вот что пишет при симуляции моей программы
Лог1

Добавляю еще раз строчку инициализации 4х битного режима
Код
RCALL   LCD_INIT_NoWoyt
---->   LDI    temp,0b00000010<-----
RCALL   Cmd
LDI    temp, 0x28
RCALL    Cmd
Пишет так
log2

Вот лог от рабочей программы tyzord66
Лог от рабочей программы

Из чего я предполагаю, что инициализация все таки проходит некорректно.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
14.11.2014, 09:43 59
Цитата Сообщение от avr_bikymmir
Из чего я предполагаю, что инициализация все таки проходит некорректно.
Попробуйте в «LCD_INIT_NoWoyt» в команде сбросить флаг «DL» - 0b00000011:
Код
      LDI      temp,0b00000010         ;Обязательная инициализация 8 битного режима. Вызывается три раза
2dymyurk1978
Я все свои проекты отлаживаю в протеус, даже сетевые девайсы удается «вылезать» на 100%, не используя железо. Вот для аналога протеус не пляшет :( .
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
14.11.2014, 11:28 60
Цитата Сообщение от tyzord66
Попробуйте в «LCD_INIT_NoWoyt» в команде сбросить флаг «DL» - 0b00000011:
В смысле так сделать?
Код
LDI      R25,$03
LDI      temp,0b00000010
Cycle_Three:
Тогда лог так выглядит:
0
14.11.2014, 11:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.11.2014, 11:28

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

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

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


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

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

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