Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Подключение разных дисплейчиков
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение rhf-admin »

Ну что ж не в первый раз уже такие вопросы. Ладно, по просьбам трудящихся :D размер вложения увеличен до 5 Мбайт. Выкладывайте, у кого что есть
С уважением, администрация сайта.
mg12
Читатель
Читатель
Сообщения: 5
Зарегистрирован: 22 мар 2010, 21:22

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение mg12 »

Уважаемый rhf-admin и Fuhrer, спасибо за помощь. Но я немного не понял, как это "Опрашивай его с интервалом, по которому ты успеешь записать его символы на бумажко :) Начерти листочек формата А4 и выводи каждую группу символов примерно по алгоритму: вывод первых 16 знаков по порядку -> кольцо программы с опросом кнопки -> кнопку нажал -> инкремент (в нужном количестве) адресов на следующие 16 символов и так далее.

Еще если у вас есть на ассемблере, выложите пожалуйста.
а, я выложу схему на протеусе7.
Заранее благодарен.
Fuhrer
Читатель
Читатель
Сообщения: 3
Зарегистрирован: 03 май 2010, 18:55
Откуда: Екатеринбург
Контактная информация:

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Fuhrer »

Вот код для управления дисплеем 16 символов в одной строке(программно две по восемь!)

Код: Выделить всё

		PROCESSOR	PIC16F877
		RADIX		HEX
#include		"p16f877.inc"
#define	XTAL	.20000000
		errorlevel  -302
		__CONFIG _HS_OSC & _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & 

_BODEN_ON & _PWRTE_ON & _WDT_ON
		__IDLOCS    H'0001'
;=============================
BANK0	MACRO
			bcf			STATUS,RP0	; Установить банк 0
			bcf			STATUS,RP1	; 
		ENDM
;=============================
BANK1	MACRO  
			bsf			STATUS,RP0	; Установить банк 1
			bcf			STATUS,RP1	; 
		ENDM
;=============================
BANK2	MACRO  
			bcf			STATUS,RP0	; Установить банк 2
			bsf			STATUS,RP1	; 
		ENDM
;=============================
BANK3	MACRO  
			bsf			STATUS,RP0	; Установить банк 3
			bsf			STATUS,RP1	; 
		ENDM
;===============================================================
;					PIC16F877 I/O
;                 +------------   ------------+
;                -|MCLR/Vpp            RB7/PGD|-  
;                -|RA0/AN0             RB6/PGC|-  
;                -|RA1/AN1             RB5    |-  
;                -|RA2/AN2/Vref-       RB4    |-  
;                -|RA3/AN3/Vref+       RB3/PGM|-  
;                -|Ra4/TOCKI	       RB2    |-  
;                -|RA5/AN4/SS          RB1    |-  
;                -|RE0/RD/AN5          RB0/INT|-  
;                -|RE1/WR/AN6          Vdd    |-  +5V
;                -|RE2/CS/AN7          Vss    |-  GND
;   +5V          -|Vdd                RD7/PSP7|-  
;   GND          -|Vss                RD6/PSP6|-  LCD E
;   XTAL         -|OSC1/CLKIN         RD5/PSP5|-  (LCD R/W)
;   XTAL         -|OSC2/CLKOUT        RD4/PSP4|-  LCD R/S
;                -|RC0/T1OSO/T1CKI RC7/RX/DT  |-  
;                -|RC1/T1OSI/CCP2  RC6/TX/CK  |-  
;                -|RC2/CCP1        RC5/SDO    |-  
;                -|RC3/SCK/SCL     RC4/SDI/SDA|-  
;   LCD DB4      -|RD0/PSP0        RD3/PSP3   |-  LCD DB7
;   LCD DB5      -|RD1/PSP1        RD2/PSP2   |-  LCD DB6
;                 +------------   ------------+
;
;===============================================================
#define		DB4			PORTD,0 ; Младший бит данных
#define		DB5			PORTD,1 ; 
#define		DB6			PORTD,2 ; 
#define		DB7			PORTD,3 ; Старший бит данных
#define		RS			PORTD,4 ; Выбор регистра (RS=0 команды; RS=1 данные)
#define		RW			PORTD,5 ; Линия выбора операции
#define		E			PORTD,6 ; Линия стробирования/синхронизации
;
LCD_ENABLE	equ			b'00000000'	; PORTD настроен на вывод данных
OPTION_RS	equ			b'10001111' ; Предделитель к WDT
;------------------------------------------------------------
; распределение RAM 
	CBLOCK		020h
			Flags	; Флаги
	ENDC

	CBLOCK
			DEL
			DEL1		; Регистры задержки
			DEL2		; 
			DEL3		; 
			LCDBYTE		; Регистр обмена данными с LCD
			LCDBYTERD	; Регистр данных, считанных из LCD
	ENDC

	CBLOCK
			Char_0
			Char_1
			Char_2
			Char_3
			Char_4
			Char_5
			Char_6
			Char_7
			Char_8
			Char_9
			Char_A
			Char_B
			Char_C
			Char_D
			Char_E
			Char_F
	ENDC
;------------------------------------------------------------
		org		00		; Вектор сброса (начальная точка программы)
		goto	Main
;------------------------------------------------------------
Main	; Конфигурирование процесора
		BANK0
		clrf		PORTA		; Сброс PORTA
		clrf		PORTB		; Сброс PORTB
		clrf		PORTC		; Сброс PORTC
		clrf		PORTD		; Сброс PORTD
		clrf		PORTE		; Сброс PORTE
		clrf		ADCON0		; АЦП - отключить
		clrf		Flags		; Сброс всех флагов
		clrf		LCDBYTE
		clrf		LCDBYTERD
		BANK1					; Банк 1
		movlw		0x06		; 
		movwf		ADCON1		; Загрузить конфигурацию все - цифровые
		movlw		B'00000000'	; 
		movwf		TRISA		; 
		movlw		B'00000000'	; 
		movwf		TRISB		; 
		movlw		B'00000000'	; 
		movwf		TRISC		; 
		movlw		B'00000000'	; 
		movwf		TRISD		; 
		movlw		B'00000000'	; 
		movwf		TRISE		; 
		movlw		OPTION_RS	; Предделитель к WDT 1:128
		movwf		OPTION_REG	; Загрузка конфигурации в регистр OPTION
		movlw		b'00000111'	; Выводы PORTA - цифровые АЦП - отключить
		movwf		ADCON1		; Загрузка конфигурации в регистр управления АЦП
;		bcf			CVRCON,CVREN	; Только для PIC16F877A
		BANK0					; Банк 0
		clrf		INTCON		; Запретить все прерывания
		bcf			ADCON0,ADON	; Работа в цифровом режиме АЦП - off
		call		delay1
;*************************** ИНИЦИАЛИЗАЦИЯ LCD **********************
InitLCD
		movlw	0x03	; b'00000011 - Ширина линии 8 бит, 1 строка, 5x8
		call	SendInit	; Передать команду инициализации
		movlw	0x03	; b'00000011 - Ширина линии 8 бит, 1 строка, 5x8
		call	SendInit	; Передать команду инициализации
		movlw	0x03	; b'00000011 - Ширина линии 8 бит, 1 строка, 5x8
		call	SendInit	; Передать команду инициализации
		bsf		E		; Подать импульс
		call	DPulse	; Выполнить задержку.
		bcf		E		; Прекратить импульс
		call	DelayCmd	; Выполнить задержку
		movlw	0x20	; b'00100000 - Ширина линии 4 бита, 1 строка, 5x8
		call	SendCmd	; Передать команду
		bsf		E		; Подать импульс
		call	DPulse	; Выполнить задержку.
		bcf		E		; Прекратить импульс
		call	DelayCmd	; Выполнить задержку
		movlw	0x0C	; b'00001100 - Включить изображение, курсоры выключены
		call	SendCmd	; Передать команду
		call	DelayCmd	; Выполнить задержку
		movlw	0x01	; b'00000001 - Clear, DDRAM, AC=0
		call	SendCmd	; Передать команду
		goto	Load_1	;Перейти к загрузке данных
;============================================================
SendInit	; Передача команды инициализации в LCD
		movwf	LCDBYTE		; Данные в регистр отправки в LCD
		swapf	LCDBYTE,W	; Передаётся сначала старший полубайт
		andlw	B'00001111'	; Старший полубайт не используется
		movwf	PORTD		; Установка данных PORTD
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
		call	DelayCmd	; Выполнить задержку без проверки флага
; Отправка младшего полубайта команды
		movfw	LCDBYTE		;Подготовить младший полубайт
		andlw	B'00001111'	;Старший полубайт не используется
		movwf	PORTD		;Установка данных PORTD
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
DelayCmd	; Delay 30.720200 mSecs
		movlw	.250
		movwf	DEL
P_Cmd
		clrwdt
		movlw	.255
		addlw	-1
		btfss	STATUS,Z
		goto	$-2
		decfsz	DEL,f
		goto	P_Cmd
		return
;============================================================
SendCmd		; Передача команды в LCD
		movwf	LCDBYTE		; Данные в регистр отправки в LCD
		swapf	LCDBYTE,W	; Передаётся сначала старший полубайт
		andlw	B'00001111'	; Старший полубайт не используется
		movwf	PORTD		; Установка данных PORTD
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
		call	BusyCheck	; Проверка флага занятости
		call	BusyCheck	; Повторная проверка (по даташиту)
; Отправка младшего полубайта команды
		movfw	LCDBYTE		;Подготовить младший полубайт
		andlw	B'00001111'	;Старший полубайт не используется
		movwf	PORTD		;Установка данных PORTD
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
		call	BusyCheck	; Проверка флага занятости
		call	BusyCheck	; Повторная проверка (по даташиту)
		return
;============================================================
SendChar	; Передача данных в LCD
        movwf   LCDBYTE		;Данные в регистр отправки в LCD
        swapf   LCDBYTE,W	;Передать сначала старший полубайт
        andlw   B'00001111'	;Старший полубайт не используется
        movwf   PORTD		;Установка данных PORTD
        bsf     RS			;Подать сигнал R/S - запись данных.
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
		call	BusyCheck	; Проверка флага занятости
		call	BusyCheck	; Повторная проверка (по даташиту)
        movfw   LCDBYTE		;Подготовить младший полубайт данных
        andlw   B'00001111'	;Старший полубайт не используется
        movwf   PORTD		;Установка данных PORTD
        bsf     RS			;Подать сигнал R/S - запись данных.
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bcf		E			; Закончить стробирующий импульс
		call	BusyCheck	; Проверка флага занятости
		call	BusyCheck	; Повторная проверка (по даташиту)
		return
;============================================================
BusyCheck	; Проверка флага занятости LCD
		clrwdt
		clrf	PORTD		; Сбросить выводы PORTD
		BANK1
		movlw	0x0F		; Линию данных установить как вход
		movwf	TRISD		; Загрузить конфигурацию
		BANK0
		bcf		RS			; Установить LCD в режим приёма команд
		bsf		RW			; Установить LCD в режим чтения данных
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		swapf	PORTD,W		; Read upper nibble busy flag, DDRam address
		andlw	0xF0		; Очистить младший полубайт (принимаем старший)
		movwf	LCDBYTERD	; Сохранить в регистре обмена
		bcf		E			; Закончить стробирующий импульс
		call	DPulse		; Выполнить задержку.
		bsf		E			; Начать стробирующий импульс
		call	DPulse		; Выполнить задержку.
		movf	PORTD,W		; Read lower nibble busy flag, DDRam address
		andlw	0x0F		; Очистить старший полубайт (принимаем младший)
		iorwf	LCDBYTERD,F	; Объединение принятых полубайтов
		bcf		E			; Закончить стробирующий импульс
		btfsc	LCDBYTERD,7	; Проверка флага занятости LCD
		goto	BusyCheck	; LCD всё ещё занят
		bcf		RW			; LCD установить в режим записи данных
		BANK1
		movlw	0x00		; Установить PORTD как выход
		movwf	TRISD		; Загрузить конфигурацию
		BANK0
		return
;=================== ЗАГРУЗКА СИМВОЛЬНЫХ ДАННЫХ =============
Load_1
		movlw	0x2A		; '*'
		movwf	Char_0		; 
		movlw	0x2A		; '*'
		movwf	Char_1		; 
		movlw	0x2A		; '*'
		movwf	Char_2		; 
		movlw	0x2A		; '*'
		movwf	Char_3		; 
		movlw	0x2A		; '*'
		movwf	Char_4		; 
		movlw	0x2A		; '*'
		movwf	Char_5		; 
		movlw	0x2A		; '*'
		movwf	Char_6		; 
		movlw	0x20		; ' '
		movwf	Char_7		; 
		movlw	0x20		; ' '
		movwf	Char_8		; 
		movlw	0x20		; ' '
		movwf	Char_9		; 
		movlw	0x20		; ' '
		movwf	Char_A		; 
		movlw	0x20		; ' '
		movwf	Char_B		; 
		movlw	0x20		; ' '
		movwf	Char_C		; 
		movlw	0x20		; ' '
		movwf	Char_D		; 
		movlw	0x20		; ' '
		movwf	Char_E		; 
		movlw	0x20		; ' '
		movwf	Char_F		; 
		call	SendLCD_Data; Вывести данные на дисплей
		call	delay		; 
		call	delay		; 
Load_2
		movlw	0x2A		; '*'
		movwf	Char_0		; 
		movlw	0x2A		; '*'
		movwf	Char_1		; 
		movlw	0x2A		; '*'
		movwf	Char_2		; 
		movlw	0x2A		; '*'
		movwf	Char_3		; 
		movlw	0x2A		; '*'
		movwf	Char_4		; 
		movlw	0x2A		; '*'
		movwf	Char_5		; 
		movlw	0x2A		; '*'
		movwf	Char_6		; 
		movlw	0x2A		; '*'
		movwf	Char_7		; 
		movlw	0x2A		; '*'
		movwf	Char_8		; 
		movlw	0x2A		; '*'
		movwf	Char_9		; 
		movlw	0x20		; ' '
		movwf	Char_A		; 
		movlw	0x20		; ' '
		movwf	Char_B		; 
		movlw	0x20		; ' '
		movwf	Char_C		; 
		movlw	0x20		; ' '
		movwf	Char_D		; 
		movlw	0x20		; ' '
		movwf	Char_E		; 
		movlw	0x20		; ' '
		movwf	Char_F		; 
		call	SendLCD_Data; Вывести данные на дисплей
		call	delay		; 
		call	delay		; 
Load_3
		movlw	0x2A		; '*'
		movwf	Char_0		; 
		movlw	0x2A		; '*'
		movwf	Char_1		; 
		movlw	0x2A		; '*'
		movwf	Char_2		; 
		movlw	0x2A		; '*'
		movwf	Char_3		; 
		movlw	0x2A		; '*'
		movwf	Char_4		; 
		movlw	0x2A		; '*'
		movwf	Char_5		; 
		movlw	0x2A		; '*'
		movwf	Char_6		; 
		movlw	0x20		; ' '
		movwf	Char_7		; 
		movlw	0x2A		; '*'
		movwf	Char_8		; 
		movlw	0x2A		; '*'
		movwf	Char_9		; 
		movlw	0x2A		; '*'
		movwf	Char_A		; 
		movlw	0x2A		; '*'
		movwf	Char_B		; 
		movlw	0x20		; ' '
		movwf	Char_C		; 
		movlw	0x20		; ' '
		movwf	Char_D		; 
		movlw	0x20		; ' '
		movwf	Char_E		; 
		movlw	0x20		; ' '
		movwf	Char_F		; 
		call	SendLCD_Data; Вывести данные на дисплей
		call	delay		; 
		call	delay		; 
Load_4
		movlw	0x2A		; '*'
		movwf	Char_0		; 
		movlw	0x2A		; '*'
		movwf	Char_1		; 
		movlw	0x2A		; '*'
		movwf	Char_2		; 
		movlw	0x2A		; '*'
		movwf	Char_3		;
		movlw	0x2A		; '*'
		movwf	Char_4		; 
		movlw	0x2A		; '*'
		movwf	Char_5		; 
		movlw	0x2A		; '*'
		movwf	Char_6		; 
		movlw	0x2A		; '*'
		movwf	Char_7		; 
		movlw	0x2A		; '*'
		movwf	Char_8		; 
		movlw	0x2A		; '*'
		movwf	Char_9		; 
		movlw	0x2A		; '*'
		movwf	Char_A		; 
		movlw	0x2A		; '*'
		movwf	Char_B		; 
		movlw	0x2A		; '*'
		movwf	Char_C		; 
		movlw	0x2A		; '*'
		movwf	Char_D		; 
		movlw	0x2A		; '*'
		movwf	Char_E		; 
		movlw	0x2A		; '*'
		movwf	Char_F		; 
		call	SendLCD_Data; Вывести данные на дисплей
		call	delay		; 
		call	delay		; 
Load_5
		movlw	0x2A		; '*'
		movwf	Char_0		; 
		movlw	0x2A		; '*'
		movwf	Char_1		; 
		movlw	0x2A		; '*'
		movwf	Char_2		; 
		movlw	0x2A		; '*'
		movwf	Char_3		; 
		movlw	0x2A		; '*'
		movwf	Char_4		; 
		movlw	0x2A		; '*'
		movwf	Char_5		; 
		movlw	0x2A		; '*'
		movwf	Char_6		; 
		movlw	0x2A		; '*'
		movwf	Char_7		; 
		movlw	0x2A		; '*'
		movwf	Char_8		; 
		movlw	0x2A		; '*'
		movwf	Char_9		; 
		movlw	0x2A		; '*'
		movwf	Char_A		; 
		movlw	0x2A		; '*'
		movwf	Char_B		; 
		movlw	0x2A		; '*'
		movwf	Char_C		; 
		movlw	0x2A		; '*'
		movwf	Char_D		; 
		movlw	0x2A		; '*'
		movwf	Char_E		; 
		movlw	0x2A		; '*'
		movwf	Char_F		; 
		call	SendLCD_Data; Вывести данные на дисплей
		goto	Loop		; Уход из программы в вечную задержку
;======================== ПЕРЕДАЧА ДАННЫХ ===================
SendLCD_Data	; Вывод данных на индикацию
		movlw	0x01		; b'00000001 - Clear, DDRAM, AC=0
		call	SendCmd		; Передать команду
;====================== ПЕРВАЯ СТРОКА ДАННЫХ ================
		movfw	Char_0		; Нулевой символ
		call	SendChar	; 
		movfw	Char_1		; Первый символ
		call	SendChar	; 
		movfw	Char_2		; Второй символ
		call	SendChar	; 
		movfw	Char_3		; Третий символ
		call	SendChar	; 
		movfw	Char_4		; Четвёртый символ
		call	SendChar	; 
		movfw	Char_5		; Пятый символ
		call	SendChar	; 
		movfw	Char_6		; Шестой символ
		call	SendChar	; 
		movfw	Char_7		; Седьмой символ
		call	SendChar	; 
;============== ПЕРЕВОД КУРСОРА НА ВТОРУЮ СТРОКУ ============
NextString	; Команда перевода курсора на начало второй строки
		movlw	0xC0		; DDRAM=0x40 (На начало второй строки)
		call	SendCmd		; Передать команду
;====================== ВТОРАЯ СТРОКА ДАННЫХ ================
		movfw	Char_8		; Восьмой символ
		call	SendChar	; 
		movfw	Char_9		; Девятый символ
		call	SendChar	; 
		movfw	Char_A		; Десятый символ
		call	SendChar	; 
		movfw	Char_B		; Одиннадцатый символ
		call	SendChar	; 
		movfw	Char_C		; Двенадцатый символ
		call	SendChar	; 
		movfw	Char_D		; Тринадцатый символ
		call	SendChar	; 
		movfw	Char_E		; Четырнадцатый символ
		call	SendChar	;
		movfw	Char_F		; Пятнадцатый символ
		call	SendChar	;
		return
;===== КОЛЬЦО ПРОГРАММЫ ПОСЛЕ ВЫПОЛНЕНИЯ УПРАВЛЕНИЯ LCD =====
Loop
		bsf		PORTA,0
		call	delay
		bcf		PORTA,0
		call	delay
		goto	Loop
;==============ЗАДЕРЖКА СТРОБИРУЮЩЕГО ИМПУЛСА================
DPulse	; Задержка стробирующего импульса 8.6 uSecs.
		clrwdt
		movlw	.10
		addlw	-1
		btfss	STATUS,Z
		goto	$-2
		return
;************************* ЗАДЕРЖКА *************************
delay ; Задержка 629.146200 mSecs
		movlw	0x06	; Задать значение задержки
		movwf	DEL1 
		clrf	DEL2 
		clrf	DEL3 
dloop
		clrwdt
		decfsz	DEL3,f 
		goto	$+2 
		decfsz	DEL2,f 
		goto	$+2 
		decfsz	DEL1,f 
		goto	dloop
		return
;************************* ЗАДЕРЖКА *************************
delay1 ; Задержка 104.858200 mSecs
		movlw	0x01	; Задать значение задержки
		movwf	DEL1 
		clrf	DEL2 
		clrf	DEL3 
dloop1
		clrwdt
		decfsz	DEL3,f 
		goto	$+2 
		decfsz	DEL2,f 
		goto	$+2 
		decfsz	DEL1,f 
		goto	dloop1
		return

		END
Serhio
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 21 авг 2014, 19:58

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Serhio »

Всем доброго времени суток! Решил написать в эту тему поскольку она оказалась наиболее близкой к моей. Помогите пожалуйста разобраться с кодом на асме для PIC16F876a. Я изучил тему http://www.radiohlam.ru/program/dot_matrix_LCD_prg.htm - подключение жки по 8-ми битному интерфейсу. Переделал код под PIC16F876A, собрал схему в протеусе и при моделировании вместо символов у меня появляется всего лишь только курсор. Подскажите пожалуйста, знатоки пиков. Ниже приведу код

LIST P=16F876A.INC
#Include <P16F876A.inc>
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF ; 11111100110001 - защиты памяти нет, низковольтное программирование запрещено, сброс по питанию запрещен,

;********* Переменные ************************************
CBLOCK 0x20 ;Начальный адрес блока констант
T_ext ;таймер внешнего цикла
T_int ;таймер внутреннего цикла
T_n ;таймер начальной задержки
M_byte ;байт посылки
ENDC ;
;******** Константы ***************************************
Cr1 equ .50 ;длительность 1-й задержки 50 циклов
Cr2 equ .25 ;длительность 2-й задержки 25х50 циклов
Cr3 equ .200 ;длительность 3-й задержки 200х50 циклов
Status equ 03h ; Регистр выбора банка
TrisA equ 05h ; Регистр выбора направления работы выводов порта А
TrisB equ 06h ; Регистр выбора направления работы выводов порта В
PortA equ 05h ; Регистр управления защелками порта А
PortB equ 06h ; Регистр управления защелками порта В
Cmcon equ 1Fh ; вкл/выкл компараторов
;********************************************************
org 0
;******** ИНИЦИАЛИЗАЦИИЯ КОНТРОЛЛЕРА ********************************************************
;******** Установка направления работы порта A: RA5, RA4, RA3 - входы, RA2, RA1, RA0 - выходы
;******** Установка направления работы порта B: RB7, RB6, RB5, RB4, RB3, RB2 - выходы, RB1, RB0 - тоже выходы ***
start movlw .7 ;
movwf Cmcon ; выключить компараторы и включить эти пины как цифровые входы/выходы
clrf PortA ; инициализация защелок порта А
clrf PortB ; инициализация защелок порта В
bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status).
movlw .56 ; Записать конфигурацию порта A в аккумулятор (W). .56=00111000
movwf TrisA ; Скопировать конфигурацию порта А из W в регистр TrisA
movlw .0 ; Записать конфигурацию порта В в аккумулятор (W). .3=00000011
movwf TrisB ; Скопировать конфигурацию порта B из W в регистр TrisB.
bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит регистра Status).
;******** ИНИЦИАЛИЗАЦИЯ ЖКИ ***************************************************************************
;******** Пауза более 30 мс + FUNCTION SET **************************************************************
movlw .56 ; DB7...DB0=00111000
movwf M_byte ; записать это значение в байт сообщения
call in_port ; запись в порт
bcf PortA, 1 ; RS=0
bcf PortA, 2 ; RW=0
call pause3
call zapis ;
;******** Пауза более 39 мкс *****************************************************************************
call pause1
;******** Продолжение инициализации DISPLAY ON/OFF MODE **************************************************
movlw .14 ; DB7...DB0=00001110
movwf M_byte ; записать это значение в байт сообщения
call in_port ; запись в порт
call zapis ;
;******** Пауза более 39 мкс *****************************************************************************
call pause1
;******** Продолжение инициализации DISPLAY CLEAR ********************************************************
movlw .1 ; DB7...DB0=00000001
movwf M_byte ; записать это значение в байт сообщения
call in_port ; запись в порт
call zapis ;
;******** Пауза более 1,53 мс ****************************************************************************
call pause2
;******** Продолжение инициализации ENTRY MODE SET *******************************************************
movlw .6 ; DB7...DB0=00000110
movwf M_byte ; записать это значение в байт сообщения
call in_port ; запись в порт
call zapis ;
;******** Пауза более 39 мкс *****************************************************************************
call pause1

;******** Инициализация дисплея закончена ****************************************************************
;******** Вывод информации *******************************************************************************
;******** Set DDRAM ADDRESS ******************************************************************************
movlw .131 ; db7=1, address=03h
movwf M_byte
call in_port
call zapis
call pause1
;******** Вывод символа *********************************************************************************
movlw .82 ; symbol="R"
movwf M_byte
call in_port
bsf PortA,1 ; RS=1
call zapis
call pause1
;******** Вывод символа *********************************************************************************
movlw .97 ; symbol="a"
movwf M_byte
call in_port
call zapis
call pause1
;******** Вывод символа *********************************************************************************
movlw .100 ; symbol="d"
movwf M_byte
call in_port
call zapis
call pause1
;******** Вывод символа *********************************************************************************
movlw .105 ; symbol="i"
movwf M_byte
call in_port
call zapis
call pause1
;******** Вывод символа *********************************************************************************
movlw .111 ; symbol="o"
movwf M_byte
call in_port
call zapis
call pause1
;******** Вывод символа *********************************************************************************
; movlw .104 ; symbol="h"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .108 ; symbol="l"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .97 ; symbol="a"
; movwf M_byte
;; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .109 ; symbol="m"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Set DDRAM ADDRESS ******************************************************************************
; movlw .196 ; db7=1, address=44h
; movwf M_byte
; call in_port
; bcf PortA,1 ; RS=0
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .80 ; symbol="Р"
; movwf M_byte
; call in_port
; bsf PortA,1 ; RS=1
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
;movlw .97 ; symbol="a"
;movwf M_byte
;call in_port
;call zapis
;call pause1
;******** Вывод символа *********************************************************************************
;movlw .227 ; symbol="д"
;movwf M_byte
;call in_port
;call zapis
;call pause1
;******** Вывод символа *********************************************************************************
;movlw .184 ; symbol="и"
;movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .111 ; symbol="o"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .120 ; symbol="х"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .187 ; symbol="л"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .97 ; symbol="a"
; movwf M_byte
; call in_port
; call zapis
; call pause1
;******** Вывод символа *********************************************************************************
; movlw .188 ; symbol="м"
;movwf M_byte
;call in_port
;call zapis
;call pause1
;*******************************************************************************************************
stop nop
goto stop
;
;
;******** Процедура записи в LCD *************************************************************************
zapis bsf PortA, 0 ; E=1 - запись
nop ; 1 мкс - пауза для записи
nop ; 1 мкс - пауза для записи
bcf PortA,0 ; E=0 - выключить запись
return
;******** Процедура Паузы 1 (39 мкс) *********************************************************************
pause1 movlw Cr1
movwf T_int ; загрузить значение таймера для паузы в T_int
cikl1 nop
nop
nop
nop
nop
nop
decfsz T_int,1
goto cikl1
return
;******** Процедура Паузы 2 (1.53 мс) ********************************************************************
pause2 movlw Cr2
movwf T_ext ; загрузить значение для внешнего цикла
cikl2 movlw Cr1
movwf T_int ; загрузить значение для внутреннего цикла
cikl3 decfsz T_int,1
goto cikl3 ; внутренний цикл
decfsz T_ext,1
goto cikl2 ; внешний цикл
return
;******** Процедура Паузы 3 (30 мс) ********************************************************************
pause3 movlw Cr3
movwf T_n ; загрузить значение для внешнего цикла
cikl4 movlw Cr1
movwf T_int ; загрузить значение для внутреннего цикла
cikl5 nop
decfsz T_int,1
goto cikl5 ; внутренний цикл
decfsz T_n,1
goto cikl4 ; внешний цикл
return
;******** Процедура записи байта сообщения в защелки портов *********************************************
in_port btfsc M_byte,7 ; если 7-й бит посылки = 0, то следующая команда пропускается
bsf PortB,4 ; DB7=1
btfss M_byte,7 ; если 7-й бит посылки =1, то следующая команда пропускается
bcf PortB,4 ; DB7=0
;------------------------------------
btfsc M_byte,6 ; если 6-й бит посылки = 0, то следующая команда пропускается
bsf PortB,5 ; DB6=1
btfss M_byte,6 ; если 6-й бит посылки =1, то следующая команда пропускается
bcf PortB,5 ; DB6=0
;------------------------------------
btfsc M_byte,5 ; если 5-й бит посылки = 0, то следующая команда пропускается
bsf PortB,2 ; DB5=1
btfss M_byte,5 ; если 5-й бит посылки =1, то следующая команда пропускается
bcf PortB,2 ; DB5=0
;------------------------------------
btfsc M_byte,4 ; если 4-й бит посылки = 0, то следующая команда пропускается
bsf PortB,6 ; DB4=1
btfss M_byte,4 ; если 4-й бит посылки =1, то следующая команда пропускается
bcf PortB,6 ; DB4=0
;------------------------------------
btfsc M_byte,3 ; если 3-й бит посылки = 0, то следующая команда пропускается
bsf PortB,3 ; DB3=1
btfss M_byte,3 ; если 3-й бит посылки =1, то следующая команда пропускается
bcf PortB,3 ; DB3=0
;------------------------------------
btfsc M_byte,2 ; если 2-й бит посылки = 0, то следующая команда пропускается
bsf PortB,7 ; DB2=1
btfss M_byte,2 ; если 2-й бит посылки =1, то следующая команда пропускается
bcf PortB,7 ; DB2=0
;------------------------------------
btfsc M_byte,1 ; если 1-й бит посылки = 0, то следующая команда пропускается
bsf PortB,1 ; DB1=1
btfss M_byte,1 ; если 1-й бит посылки =1, то следующая команда пропускается
bcf PortB,1 ; DB1=0
;------------------------------------
btfsc M_byte,0 ; если 0-й бит посылки = 0, то следующая команда пропускается
bsf PortB,0 ; DB0=1
btfss M_byte,0 ; если 0-й бит посылки =1, то следующая команда пропускается
bcf PortB,0 ; DB0=0
;------------------------------------
return
;***********************************************************************************************
end
Serhio
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 21 авг 2014, 19:58

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Serhio »

Протеус выдает следующую ошибку
pic16 ADC PC=0x0002. ADC conversion started before "wait" time has expired following previous conversion or channel change.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение rhf-admin »

А первоначальный код, непеределанный (который из статьи и написан для PIC16F628A) - он в протеусе нормально работает? Просто может это с самим протеусом глюк?
С уважением, администрация сайта.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение rhf-admin »

А кроме того, для 876-го надо при инициализации не только компараторы выключить, но и все пины A/D-преобразователя настроить как цифровые (после ресета они все настроены как аналоговые).
Кстати, адреса регистров у 876-го не совпадают с 628A. 1Fh - это в 876-м не CMCON, а ADCON1 и расположен он в первом банке. А CMCON у него по адресу 1Ch и тоже в первом банке (у PIC16F628A CMCON был в нулевом банке).
Так что инициализация для 876-го должна быть такой:
movlw .7 ;
bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status).
movwf CMCON
movwf ADCON1
P.S. Ну и написать надо правильно адреса регистров:
ADCON1 equ 1Fh
CMCON equ 1Ch
С уважением, администрация сайта.
Serhio
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 21 авг 2014, 19:58

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Serhio »

rhf-admin писал(а):А первоначальный код, непеределанный (который из статьи и написан для PIC16F628A) - он в протеусе нормально работает? Просто может это с самим протеусом глюк?
Да, непеределанный работает. Только русский шрифт выдает некорректно. Сначала тоже думал на протеус
Serhio
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 21 авг 2014, 19:58

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Serhio »

Так что инициализация для 876-го должна быть такой:
movlw .7 ;
bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status).
movwf CMCON
movwf ADCON1
Огромнейшее Вам спасибо! :clapping: Именно перевода пинов из аналоговых в цифровые мне и не хватало. Читал про это на форумах несколько раз, а проверить так и не сообразил)))). Все работает :D
Serhio
Читатель
Читатель
Сообщения: 12
Зарегистрирован: 21 авг 2014, 19:58

Re: Нужна помощь по подключению LCD и клавиатуры к PIC16F877

Сообщение Serhio »

Помогите пожалуйста с вопросом позиционирования символов. Не могу найти в инете адреса строк и символов в них. В примере 4я позиция 1й строки обозначена как .131 - где можно посмотреть остальные адреса символов и строк? (как их указать)
Ответить