Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры 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. Просмотров 37607. Ответов 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
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.11.2014, 12:57 21
Диаграма это понятно.
Вот это как раз Вам похоже и не понятно. Чтобы проверить флаг занятости , нужно перевести дисплей в режим чтения с уровнем ноль на RS , Затем считать данные т.е подергать E .Т.е выполнить команду из списка команд для дисплея - ПРОЧЕСТЬ ФЛАГ ЗАНЯТОСТИ . Вот эту команду Вы и должны сформировать. Что собственно и делает этот код. И Вам надо сформировать длительность импульса E - строго по DS.
Вы даже не поняли , что своими nop в Вашем же коде и формируете длительность Е. В моем коде , где возможно , я их заменил полезными командами. А вот для команды ПРОЧЕСТЬ ФЛАГ ЗАНЯТОСТИ - этого сделать не возможно.
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
09.11.2014, 12:59 22
Цитата Сообщение от avr_bikymmir
Наверно это как раз таки основная ошибка.
Командами
Код
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
PORTA, включая RS, RW, EN был переведён на вход??! Если бы был другой камень с возможностью переключаться подачей 1 на PINx, то было бы понятно. Но в mega16 такой возможности нет.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
09.11.2014, 14:08 23
Цитата Сообщение от YTYOUT
Вы даже не поняли , что своими nop в Вашем же коде и формируете длительность Е.
Что в своем коде я делал нопами - я как раз таки понимаю. Я извиняюсь. Не заметил сразу, что Вы в комментариях прояснили свой код. Спасибо. Сейчас буду пробовать еще раз переделать свой код на основе вновь полученной информации.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
10.11.2014, 09:28 24
Цитата Сообщение от YTYOUT
.
Поразбирался в Вашем коде. Для полноты картины хотелось бы к ней еще схемку или хотя бы описание куда подключен управляющий порт, а куда порт данных. Я почему то понял, что они висят на разных портах.
И еще большая просьба ответить - у вас запись двух полубайтов идет во время всего одного стробирующего импульса или я чего то недоглядел еще? Во всех описаниях (по крайней мере на русском) пишут, что идет начало строба, конец строба, запись полубайта, начало строба, конец строба, запись полубайта.
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
10.11.2014, 09:46 25
Цитата Сообщение от avr_bikymmir
...
В моем проекте ЖКИ подключен к 1 порту. PORTC. Старший ниббл - данные. Младшие ногодрыг. Управление ЖКИ, короче. В принципе, ногодрыг можно раскидать по разным портам. А вот данные у меня привязаны к старшему нибблу какого-либо порта.
Все подпрограммы, отправка команды, отправка данных и так далее в lib_char_dysplay.yms.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
10.11.2014, 10:55 26
Для полноты картины хотелось бы к ней еще схемку или хотя бы описание куда подключен управляющий порт, а куда порт данных. Я почему то понял, что они висят на разных портах.
Плиз

0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
10.11.2014, 10:59 27
Вот еще мой вариант, данные на старшем ниббле, пишем и читаем из индикатора, все с проверкой готовности, все задержки расставляются автоматом (меняем только “F_CPU"), ассемблер, в архиве и проект протеуса, проверено в железе.

[70.99 Кб]
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
10.11.2014, 11:04 28
Я обратил внимание, что читается флаг ожидания. Вопрос, зачем? В даташите указаны все времянки. Если убрать чтение флага занятости, экономится один вывод МК. Плюс, так как нет чтения флага занятости, МК может заниматься другими делами.
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
10.11.2014, 11:14 29
Цитата Сообщение от dymyurk1978
Я обратил внимание, что читается флаг ожидания. Вопрос, зачем? В даташите указаны все времянки. Если убрать чтение флага занятости, экономится один вывод МК. Плюс, так как нет чтения флага занятости, МК может заниматься другими делами.
В даташите значения задержек указаны по максимуму, индикатор бывает готов гораздо раньше, а на ожидание не всегда есть время.

Я пробовал делать «динамику» с псевдографикой :) http://www.youtube.com/watch?v=xtpaqKwRKc0
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
10.11.2014, 11:18 30
Я обратил внимание, что читается флаг ожидания. Вопрос, зачем?
Тоже самое и с DS18B20 она значительно раньше заканчивает преобразование чем 750мс. И со многими другими , кто имееют такую возможность
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
10.11.2014, 11:41 31
Цитата Сообщение от YTYOUT
..
Спасибо. Все таки хотелось бы еще уточнить про:
Цитата Сообщение от avr_bikymmir
И еще большая просьба ответить - у вас запись двух полубайтов идет во время всего одного стробирующего импульса или я чего то недоглядел еще? Во всех описаниях (по крайней мере на русском) пишут, что идет начало строба, конец строба, запись полубайта, начало строба, конец строба, запись полубайта.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
10.11.2014, 12:30 32
Первый строб:
Код
sbr      temp,1<<LCD_E      ;| $08 ;Устанавливем сигнал строба (Е) в one
..................................
..................................
cbi      LCD_Port,LCD_E      ;" Записываем данные в LCD
Второй строб:
Код
or      temp,temp1       здесь сигнал E - устанавливается в 1
outr   LCD_PORT,temp      ;/ Выводим второй полубайт в порт
..................................
..................................

Woyt_BS:   ;/ Установка режима   чтения BS
cbi      LCD_Port,LCD_E      ;" Записываем данные в LCD
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
10.11.2014, 12:43 33
Цитата Сообщение от avr_bikymmir
Спасибо. Все таки хотелось бы еще уточнить про:
Цитата Сообщение от avr_bikymmir
И еще большая просьба ответить - у вас запись двух полубайтов идет во время всего одного стробирующего импульса или я чего то недоглядел еще? Во всех описаниях (по крайней мере на русском) пишут, что идет начало строба, конец строба, запись полубайта, начало строба, конец строба, запись полубайта.
Вот тут доступней некуда:

0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
11.11.2014, 16:32 34
2 avr_bikymmir
Поправил под Вашу схему, теперь и старший/младший ниббл тоже настраивается (low_NIBBLE)

[103.92 Кб]
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
12.11.2014, 03:55 35
Проясните для тех, кто в танке.. Флаг занятости получается проверяется на пине DB7?
0
okt
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 222
12.11.2014, 06:59 36
Да
Busy Flag (BF)
When the busy flag is 1, the HD44780U is in the internal operation mode, omd the next instruction will not be accepted. When RS = 0 omd R/: = 1 (Table 1), the busy flag is output to DB7. The next instruction must be written after ensuring that the busy flag is 0.
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
12.11.2014, 15:11 37
Блин. Никак не могу написать что то работающее. Уже вроде и в отладчике все работает, а в симуляторе не хочет. Может кому то бросится в глаза какой то очевидный косяк?
Код
.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

RET

;-----------------------------------
LCD_INIT_NoWoyt:
CBI      LCD_PORT,RS
CBI      LCD_PORT,RW
LDI      R25,$03
LDI      temp,0b00000011      ;Обязательная инициализация 8 битного режима. Вызывается три раза
Cycle_Three:
SBR      temp,1<<EN
OUT      LCD_PORT,temp      ;начинаем запись
NOP                  ;ждем время для установки данных на шине
NOP
NOP
NOP
NOP
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:
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:
;Определение готовности дисплея
;Чтение бита готовности
nop
CBI      LCD_PORT,    EN            ;Конец строба. Запись данных в дисплей
CBI      LCD_DDR,    D7         ;7 бит на вход
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:
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
[162.72 Кб]
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
12.11.2014, 16:18 38
Код
1.LDI   temp,0b00000011   ;Обязательная инициализация 8 битного режима. Вызывается три раза
Код
 2. ANDI   temp,0b00000010   ;после этой команды начнет устанавливаться режим 4 бит
0
ovr_bikymmir
0 / 0 / 0
Регистрация: 08.08.2014
Сообщений: 52
12.11.2014, 16:56 39
Эмм.. А можно поподробнее прояснить, что не так? Алгоритм сдернут из Вашего кода, по описанию вроде нужно загрузить три раза 0011, потом один раз 0010. Или как надо?
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
12.11.2014, 17:21 40
У меня 0х30 и 0x20 , а у Вас 0х03 и 0х02
0
12.11.2014, 17:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.11.2014, 17:21

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

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

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


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

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

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