Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 19:56:17

Изучать асемблер начал недавно, решил разобраться в исрользовании LCD 1602 для начала, текст выводить научился по примерам из исходников но не могу понять одного,
например подключен LCD к порту B 0,1,2,3 PIC16F84A, а нужно подключить к B 4,5,6,7.
Не могу понять как определяются биты порта к которым подключен дисплей
С восьми битным интерфейсом всё понятно, использовать весь порт и всё.
Спойлер;;;;;;;;;;Проба работы в 4 битном режиме;;;;;;;;;;;;;
; LCD: D0-D7 подключены к RB0-RB7
; E - RA3, RS - RA2, R/W - GND
;==========
LIST P=16F84A
__CONFIG _XT_OSC & _CP_OFF & _PWRTE_OFF & _WDT_OFF
include P16F84A.inc
;==========

Var_1 equ 20h ;
Var_2 equ 21h ;
;==========
#define RS PORTA,2 ; вывод RS
#define E PORTA,3 ; вывод E
#define LCD_PORT PORTB
org 0 ;
;==========
clrf STATUS ; Настройка выводов МК
clrf PORTA ;
clrf PORTB ;
bsf STATUS,RP0 ;
clrf TRISA ;
clrf TRISB ;
bcf STATUS,RP0 ;

;===
; Variable Definitions

cblock H'20'
delay_1
delay_2
delay_3
tempLCD
endc

;==============
; Reset Vector

;org 0x0000
goto Start

Init

;===
; Set up port and pins

banksel TRISB ; select TRISC bus
movlw B'00000000' ; all pins output
movwf TRISB

banksel PORTB ; select LATC and clear
clrf PORTB

return

;========
; Delay subroutine which lasts for 100 * cty

delay_long
movwf delay_3
delay_long_loop2
movlw D'13'
movwf delay_2
clrf delay_1
delay_long_loop1
decfsz delay_1,f
goto delay_long_loop1
decfsz delay_2,f
goto delay_long_loop1
decfsz delay_3,f
goto delay_long_loop2

return

;==========
; Delay subroutine 1000 * cty

delay_short
movwf delay_2
delay_short_loop2
movlw D'249'
movwf delay_1
delay_short_loop1
nop
decfsz delay_1,f
goto delay_short_loop1
decfsz delay_2,f
goto delay_short_loop2

return

;==================
;LCD Initialisation

LCD_Init
movlw D'5'
call delay_long

;banksel PORTB
bcf RS ; commands so RS bit set low
movlw b'00010000' ; must be more than 15ms
call delay_short
;banksel PORTB
movlw 0x03 ; send first high nibble
movwf LCD_PORT
call Nibble
movlw D'6' ; must be more than 4.1ms
call delay_short
;banksel PORTB
movlw 0x03 ; send second high nibble
movwf LCD_PORT
call Nibble
movlw D'1' ; must be more than 100us
call delay_short
;banksel PORTB
movlw 0x03 ; send third high nibble
movwf LCD_PORT
call Nibble
movlw D'5' ; must be more than 5ms
call delay_short

;banksel PORTB
movlw 0x02 ; set 4 bit mode
movwf LCD_PORT
call Nibble
movlw 0x28 ; function set: 4 bit, 2 lines, 5 x 7 font
call LCD_Cmd
movlw 0x08 ; display switch: D = 0, C = 0, B = 0
call LCD_Cmd
call LCD_Clear
movlw 0x0C ; display switch: D = 1, C = 0, B = 0
call LCD_Cmd

movlw 0x06 ; input set: I/D = 1, S = 0
call LCD_Cmd

;banksel PORTB ; make sure LATC port is clear
clrf PORTB

movlw D'50' ; initialisation delay
call delay_long

return

;============
; LCD Command

LCD_Cmd
movwf tempLCD ; move contents of w into tempLCD
swapf tempLCD,w ; swap contents of tempLCD put result in w
andlw 0x0f ; select high nibble
movwf LCD_PORT
bcf RS ; RS set low due to instruction write
call Nibble
movlw D'1'
call delay_short

movfw tempLCD ; move contents of tempLCD into w
andlw 0x0f ; select low nibble
movwf LCD_PORT
bcf RS ; RS set low due to instruction write
call Nibble
movlw D'1'
call delay_short

return

;==========
; LCD Write

LCD_Write
movwf tempLCD ; move contents of w into tempLCD
swapf tempLCD,w ; поменять местами содержимое tempLCD положить результат в w
andlw 0xf ; Выбрать старший полубайт
movwf LCD_PORT ; Записать в порт
bsf RS ; RS set high due to instruction write
call Nibble
movlw D'1'
call delay_short
movfw tempLCD ; move contents of tempLCD into w
andlw 0xf ; select low nibble
movwf LCD_PORT
bsf RS ; RS set high due to instruction write
call Nibble
movlw D'5' ; vary this delay to control writing speed
call delay_long
return

;=========
; Send nibble - toggle E pin

Nibble
bsf E ; E set high
movlw D'1'
call delay_short
bcf E ; E set low
movlw D'2'
call delay_short

return

;===========
; LCD line 1

LCD_Line1
movlw 0x80
call LCD_Cmd

return

;===========
; LCD line 2

LCD_Line2
movlw 0xC0
call LCD_Cmd

return

;==============
; Clear Command

LCD_Clear
movlw 0x01
call LCD_Cmd

return

;============
; Write Space

LCD_Space
movlw 0x20
call LCD_Write

return

;=============
; Program main

Start
call Init
call LCD_Init

Main
call LCD_Clear
call LCD_Line1

Top_Line
movlw b'01001000' ; H
call LCD_Write
movlw 'e'
call LCD_Write
movlw 'l'
call LCD_Write
movlw 'l'
call LCD_Write
movlw 'o'
call LCD_Write
call LCD_Space
movlw 'W'
call LCD_Write
movlw 'o'
call LCD_Write
movlw 'r'
call LCD_Write
movlw 'l'
call LCD_Write
movlw 'd'
call LCD_Write
movlw D'255'
call delay_long

Bottom_Line
call LCD_Line2
movlw 'L'
call LCD_Write
movlw 'C'
call LCD_Write
movlw 'D'
call LCD_Write
movlw ' '
call LCD_Write
call LCD_Space
movlw 'p'
call LCD_Write
movlw 'i'
call LCD_Write
movlw 'c'
call LCD_Write
movlw '1'
call LCD_Write
movlw '6'
call LCD_Write
movlw 'f'
call LCD_Write
movlw D'255'
call delay_long

goto $ ; loop forever

end
Вложения
test_1684.asm
(7.31 KiB) Скачиваний: 285

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 20:35:45

Есть "хитрая" команда "andlw 0xf" - разберись.

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 21:35:56

вот ковырял тут "andlw 0x0f ; select high nibble" но что то не получилось,
Сейчас ещё разок попробую
я так понимаю нужно на "andlw 0xF0" заменить, что то не работает

Добавлено after 49 minutes 21 second:
andlw 0xf0 ; Выделяем старший полубайт
movwf TEMP ; Помещаем старший полубайт во временныую переменную TEMP
movfw LCD_PORT ; Считали данные с порта данных LCD
andlw 0x0f ; Маскируем разряды, не относящиеся к LCD
iorwf TEMP, w ; Объединяем значащие полубайты
movwf LCD_PORT ; Записываем новое значение в порт данных LCD
bsf E
bcf E ; Strobe out the LCD Data
movlw 0xD0 ; Задержка на 250 uS !!!!!!!!!!!!!!!!
movwf DCnt


В другом исходнике тоже не помогает "andlw 0x0f"

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 21:47:27

Кроме передачи данных есть еще инициализация дисплея...

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 22:08:00

вот этот исходник то что мне нужно, но хотелось бы разобраться.
Кстати тоже не могу поменять биты порта.
Спойлерlist p=16f84A ; list directive to define proces
#include <p16f84A.inc> ; processor specific variable

__config _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ;

;***** VARIABLE DEFINITIONSBLE DEFINITIONSBLE
;cblock 0x40
cblock 0x0C
w_temp
w_temp1
status_temp
pclath_temp

TEMP
Temp
Cnt
DCnt
DCnt2

endc
;Define Information
#DEFINE RS PORTA, 0 ; RC4 is RS line of LCD
#DEFINE E PORTA, 1 ; RC5 is E line of LCD
; RB0-RB3 are D4-D7 of LCD
;************************************************************
; LCD Module commands
;************************************************************
#define DISP_ON 0x0C ; Display on
#define CLR_DISP 0x01 ; Clear the Display (команда требует задержки на 5 mS)
#define ENTRY_INC 0x06 ;
#define LINE1 0x80 ; Начало первой линии
#define LINE2 0xC0 ; Начало второй линии
#define LCD_DATA PORTB
;***********************************************************
org 0x00 ;
goto INIT ;
;********************* Обработчик прерываний ***************
org 0x04 ; interrupt vector
goto INTERRUPT
;************************ЗДЕСЬ ТАБЛИЦЫ,ПОДПРОГРАММЫ И Т.Д.**
;***********************************************************
;*************************************************************************;
; Initialize the LCD ;
;*************************************************************************;
InitLCD:
call Delay40ms ; Wait 40 msecs before Reset
bcf RS ; send an 8 bit instruction
movlw 0x30 ; Reset Command
call NybbleOut ; Send the Nybble
call Delay5ms ; Wait 5 msecs before Sending Again
movlw 0x30
call NybbleOut ; Send the Nybble
call Delay5ms
movlw 0x30
call NybbleOut ; Send the Nybble
call Delay5ms
movlw 0x20 ; Set 4 Bit Mode !!!
call NybbleOut
;--- Задержка на 250 uS ---
movlw 0xD0
movwf DCnt
DLoopIL:
decfsz DCnt, f
goto DLoopIL
;----------
movlw b'00101000' ;0x28 ; 4 bit, 2 Линии, 5x7 Точек
call SendINS
movlw b'00010000' ;0x10 ; display shift off
call SendINS
movlw CLR_DISP ; Clear the Display RAM
call SendINS
call Delay5ms ; Wait 5 msecs (Note, Can take up to 4.1 msecs)
movlw ENTRY_INC ; increment cursor
call SendINS
movlw b'00001100' ;0x0C ; display on cursor off
call SendINS
movlw LINE1 ;
call SendINS
return
;*************************************************************************;
; Send an instruction in W out to the LCD ;
;*************************************************************************;
SendINS:
movwf Temp ; Save the Temporary Value
bcf RS ; Командный режим
call NybbleOut
movfw Temp ; Send the HIGH Nybble
swapf Temp, w ; Send the LOW Nybble
call NybbleOut
return

;*************************************************************************;
; Send the character in W out to the LCD
; Отправить символ в W на ЖК-дисплее
;*************************************************************************;
SendASCII: ; Send nbr as ASCII character
addlw '0'
SendCHAR: ; Отправить символ на LCD-дисплей
movwf Temp ; Сохранить временное значение
bsf RS ; Режим данных
call NybbleOut
movfw Temp ; Отправить старший полубайт
swapf Temp, w ; Отправить младший полубайт
bsf RS ; Режим данных
call NybbleOut
return
;*************************************************************************;
; Send the nibble in W out to the LCD ;
;*************************************************************************;
NybbleOut: ; Send a Nybble to the LCD
andlw 0xf0 ; Выделяем старший полубайт
movwf TEMP ; Помещаем старший полубайт во временныую переменную TEMP
movfw LCD_DATA ; Считали данные с порта данных LCD
andlw 0x0f ; Маскируем разряды, не относящиеся к LCD
iorwf TEMP, w ; Объединяем значащие полубайты
movwf LCD_DATA ; Записываем новое значение в порт данных LCD
bsf E
bcf E ; Strobe out the LCD Data
movlw 0xD0 ; Задержка на 250 uS !!!!!!!!!!!!!!!!
movwf DCnt
DLoop1:
decfsz DCnt, f
goto DLoop1
return

;**************************************************************************
; Задержка 5, 40, 80 миллисекунд
;**************************************************************************
Delay80ms:
movlw 0xFF ; устанавливаем начальное значение переменной (256)
goto $+4
Delay40ms:
movlw 0x85 ; устанавливаем начальное значение переменной (133)
goto $+2 ; перескакиваем через следующий оператор
Delay5ms:
movlw 0x10 ; устанавливаем начальное значение переменной...
movwf DCnt2 ; ...внешнего цикла (16)
DLoopOut:
movlw 0xFF ; устанавливаем начальное значение переменной...
movwf DCnt ; ...вложенного цикла (256)
DLoopIn: ; Продолжительность внетреннего цикла ~0,3 mS
decfsz DCnt, f ; декремент переменной цикла
goto DLoopIn ; если DCnt не 0, повторить декремент
decfsz DCnt2, f ; иначе декремент переменной внешнего цикла
goto DLoopOut ; если DCnt2 не 0, повторить декремент
return
;************************ПРЕРЫВАНИЕ*************************
INTERRUPT:
movwf w_temp
movfw STATUS
bcf STATUS, RP0
movwf status_temp
movfw PCLATH
movwf pclath_temp

btfsc INTCON, RP0
goto PORTB_INT
;***************ОБРАБОТКА ТАЙМЕРА************
;************** ЗДЕСЬ КОД ОБРАБОТКИ ТАЙМЕРА**
goto END_INT
;********************************************

PORTB_INT:
;************** ЗДЕСЬ КОД ОБРАБОТКИ КЛАВИШ***



; ----------

END_INT:

bcf INTCON, RBIF
bcf STATUS, RP0
movfw pclath_temp
movwf PCLATH
movfw status_temp
movwf STATUS
swapf w_temp, f
swapf w_temp, w
retfie

; **************** Конец обработчика прерывания ***********
;----------

INIT:
clrf PORTA ; initialize PORTA
;movlw 0x07
;movwf CMCON ; отключение аналоговых компараторов
clrf STATUS
clrf INTCON
movlw b'00000000'
movwf PORTA
clrf PORTB

bsf STATUS, RP0

movlw b'00000000'
movwf TRISA^80
movlw b'00000000'
movwf TRISB^80
bcf OPTION_REG^80,NOT_RBPU

bcf STATUS, RP0
call InitLCD

;******************************************************************
;****************ГЛАВНЫЙ ЦИКЛ***************************
main:


movlw LINE1+4 ; Вывод 2 CТРОКА 3 ПОЗИЦИЯ
call SendINS
movlw 'H'
call SendCHAR
movlw 'E'
call SendCHAR
movlw 'L'
call SendCHAR
movlw 'L'
call SendCHAR
movlw 'O'
call SendCHAR
movlw LINE2
call SendINS
;movlw ' '

;call SendCHAR
movlw 'W'
call SendCHAR
movlw 'o'
call SendCHAR
movlw 'r'
call SendCHAR
movlw 'd'
call SendCHAR
movlw '!'
call SendCHAR
movlw '!'
call SendCHAR
movlw '!'
call SendCHAR
LOOP: goto LOOP



end


Добавлено after 9 minutes 36 seconds:
Кроме передачи данных есть еще инициализация дисплея...

я менял и там и там,
в протеусе видно что импульсы идут с нужных ножек а лсд молчит
Последний раз редактировалось greck Пт янв 17, 2020 01:18:44, всего редактировалось 1 раз.

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 22:41:56

у тебя действително 84 пик? просто их счас ненайти а под другие надо коректировать исходники

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 22:46:06

Со старых запасов есть и 628 и 84
А исходник был под PIC16F1459 я его переделал для 84го

Re: LCD1602 Assembler pic по 4м битам

Чт янв 16, 2020 23:50:14

movlw b&#39;00101000&#39
Чо за хрень?

Re: LCD1602 Assembler pic по 4м битам

Пт янв 17, 2020 00:09:19

...А исходник был под PIC16F1459 я его переделал для 84го...
Смелый подход при условии что
...Изучать асемблер начал недавно...
Можно добавить не оттуда начал.
Последний раз редактировалось otest Пт янв 17, 2020 00:10:12, всего редактировалось 1 раз.

Re: LCD1602 Assembler pic по 4м битам

Пт янв 17, 2020 01:22:43

movlw b&#39;00101000&#39
Чо за хрень?

А в MPLAB у меня нормально, movlw b'00101000' это видать сайт с кодировкой что то напутал

Добавлено after 16 minutes 37 seconds:
...А исходник был под PIC16F1459 я его переделал для 84го...
Смелый подход при условии что
...Изучать асемблер начал недавно...
Можно добавить не оттуда начал.


А что такого про смелый подход, поменять порты с С на B сложно? или может сконфигурировать мк сложно.
А вообще все мигалки кнопки EEPROM динамическую индикацию я уже освоил.
С дисплеем занялся потому как имеется исходник синтезатора частоты на pic16f84a с LCD МТ10-Т7 с енкодером а хотелось бы LCD хотябы двух строчный.

Кстати ассемблер начал изучать из за этого синтезатора, изначально диапазон 144-146 МГц думаю щас я подправлю под себя, открыл исходник блокнотом
минут 10, 15 пытался что то там высмотреть а там не понятно ни чего, в общем решил я понять что же там. Вот так и начал учить ассемблер.

Добавлено after 55 minutes 57 seconds:
у тебя действително 84 пик? просто их счас ненайти а под другие надо коректировать исходники

Посмотрел в интернет магазинах, их просто валом.
Вложения
test_1684_2.asm
(14.32 KiB) Скачиваний: 269

Re: LCD1602 Assembler pic по 4м битам

Пт янв 17, 2020 02:24:04

movfw - в среднем семействе нет команды. movfw LCD_PORT - наверно правильнее movf LCD_PORT

Re: LCD1602 Assembler pic по 4м битам

Пт янв 17, 2020 04:18:12

movfw - в среднем семействе нет команды. movfw LCD_PORT - наверно правильнее movf LCD_PORT

Что самое интересное работает эта программа :))

Re: LCD1602 Assembler pic по 4м битам

Пт янв 17, 2020 13:13:13

movfw - в среднем семействе нет команды. movfw LCD_PORT - наверно правильнее movf LCD_PORT

Команды МК нет, а ассемблерная команда есть... :tea:
Все очень просто: movfw <reg> абсолютно идентична movf <reg>, w и всего лишь наводит эстетический порядок в мнемонике.... :)

ЗЫ. По теме. Автору рекомендую В ДАННОМ СЛУЧАЕ добавить к загрузке ниббла swap. И младший ниббл станет старшим.
Вообще, смена пинов может быть любой. Для этого можно применить табличный пересчет retlw.

Re: LCD1602 Assembler pic по 4м битам

Вс янв 19, 2020 19:41:09

Получилось как то так

Код:
NybbleOut
        MOVWF   DATA1               ; B'00110010'
        ANDLW   B'11110000'         ; B'11110000'
        MOVWF   DATA2               ; B'00110000'
        MOVF    PORTB, W            ; B'00000000'
        ANDLW   B'00001111'         ;
        IORWF   DATA2, W            ;
   SWAPF   DATA2, W            ; меняем местами биты порта
        MOVWF   PORTB               ;
        CALL    TOGGLE_E            ;

        SWAPF   DATA1, F            ;
        MOVF    DATA1, W            ;
        ANDLW   B'11110000'         ;
        MOVWF   DATA2               ;
        MOVF    PORTB, W            ;
        ANDLW   B'00001111'         ;
        IORWF   DATA2, W            ;
   SWAPF   DATA2, W            ; меняем местами биты порта
        MOVWF   PORTB               ;
        CALL    TOGGLE_E            ;
        RETURN

Re: LCD1602 Assembler pic по 4м битам

Пн янв 20, 2020 10:45:54

movfw - в среднем семействе нет команды. movfw LCD_PORT - наверно правильнее movf LCD_PORT


Псевдокоманды заложены в "слэнговый набор" макросов IDE.
Открываем IDE (у меня 8.92)
тыць help
выбираем раздел topics
в выпавшем меню выбираем language tools -> mpasm assembler
тыць OK...
Далее в левой менюшке
reference -> instruction sets -> 12-Bit/14-Bit Instruction Width Pseudo-Instructions
и читаньки-распечатаньки.
Там моного чего интересного-полезного имеется.
:beer:

Re: LCD1602 Assembler pic по 4м битам

Сб фев 08, 2020 12:47:45

Оу, вау, да неужели в супер-20-20 году кто-то еще начинает изучать PIC16F84A, да еще и на ассемблере? Ваааау... Прям как археологическая раскопка. Видимо, раскопали книжки Корабельникова и видеоуроки доцэнта Ласёва или как его там.
На мой взгляд, после первого беглого знакомства с ассемблером, и особенно с PIC16F84, эти древнейшие артефакты прошлого тысячелетия надо оставить. Они просто не стоят потраченных сил и времени.
Я бы даже не стал рекомендовать ничего распечатывать - пустой перевод бумаги и тонера. Полезного там, по состоянию на 20-20 год, нет ничегошеньки. Это как сейчас смотреть в кинескопный монитор 14 дюймов 800х600 точек - в то время такие как раз и были.

Re: LCD1602 Assembler pic по 4м битам

Пн фев 10, 2020 14:11:49

Возможно PIC16F84A не стоит детального изучения - их на сегодня только в антикварных коллекциях встретить можно...
А вот ассемблер изучать смысл ВСЕГДА имеется!.
:wink:
Ответить