Задание 2. Перемещение символа по экрану. ЛАБОРАТОРНАЯ РАБОТА №7 КОМАНДЫ ВВОДА/ВЫВОДА И ОБРАЩЕНИЯ К ПОДПРОГРАММАМ. РАБОТА СО СТЕКОМ Цель работы – изучение команд ввода/вывода, обращения к подпро-граммам, работы со LCD дисплеем. Задание 1. Вывести сообщение «smart students».  Микроконтроллер управляется программой: #include "p16f84a.inc" ;PIC16F84A definitions for MPASM assembler CHAR EQU 0x0C ;инициализация LCD CHAR_COUNT EQU 0x0D ;определение стартового бита ;MESSAGE_ ADDR_INDEX EQU 0x0E ;адрес EEPROM LCD TEMP EQU 0x10 CONSTANT START_ADDR = 0x00 ;стартовый адрес EEPROM CONSTANT LCD_CAPACITY = 0x50 ;размерность LCD 4x20 = 80 = 50H ; Отключим предупреждение 302 (о банках памяти) errorlevel -302 ORG 0 ; Инициализация портов BSF STATUS, RP0 ;Выберем банк 1 MOVLW 0x80 ;отключение подтягивающих резисторов MOVWF OPTION_REG MOVLW 0x00 ;назначение портов А на выход MOVWF TRISA MOVLW 0x00 ;назначение портов В на выход MOVWF TRISB BCF STATUS, RP0 ;Выберем банк 0 MOVLW 0x00 ; включение счетчика с 0 MOVWF CHAR_COUNT ; отправка инструкции в память LCD преобразование курсора CALL CLEAR_DISPLAY CALL ENAB_DISPLAY_CURSOR MAIN MOVLW START_ADDR ; отправка стартового адреса для EEPROM MOVWF ADDR_INDEX READ_CHAR MOVF ADDR_INDEX,0; обращение к начальному адресу EEPROM MOVWF EEADR ; EEADR := ADDR_INDEX BSF STATUS,RP0 ; включение 1 банка BSF EECON1,RD ; Инициализировать чтение из EEPROM BCF STATUS,RP0 ; включение 0 банка MOVF EEDATA,0 MOVWF CHAR ; загрузка переменной из EEPROM в ; переменную W CALL WRITE_CHAR ; запись переменной в память LCD DISPLAY INCF ADDR_INDEX,1 INCF CHAR_COUNT,1 SUBLW 0x00 ; ОБНАРУЖИТЬ КУРСОР, ЕСЛИ CHAR = 00H, ЕСЛИ ТАК, ; ТО ВЫХОД LOOP BTFSS STATUS,2 ; выход при нулевом бите GOTO READ_CHAR SHIFTING MOVLW LCD_CAPACITY SUBWF CHAR_COUNT,0 MOVWF TEMP ;TEMP = CHAR_COUNT - LCD_CAPACITY COMF TEMP,1 ;получение отрицательного результата MOVLW 0x02 ;добавить сброс ADDWF TEMP,1 SHIFTRIGHT MOVLW 0x1C ;SHIFT RIGHT INSTRUCTION TO LCD CALL MOVE_CURSOR_SHIFT_DISPLAY DECFSZ TEMP,1 GOTO SHIFTRIGHT MOVLW LCD_CAPACITY SUBWF CHAR_COUNT,0 MOVWF TEMP ;TEMP = CHAR_COUNT - LCD_CAPACITY COMF TEMP,1 ;TAKE THE COMPLEMENT OF THE NEGATIVE VALUE MOVLW 0x02 ;ADD OFFSET ADDWF TEMP,1 SHIFTLEFT MOVLW 0x18 ;SHIFT LEFT INSTRUCTION TO LCD CALL MOVE_CURSOR_SHIFT_DISPLAY DECFSZ TEMP,1 GOTO SHIFTLEFT GOTO SHIFTING ; FUNCTIONS CLEAR_DISPLAY MOVLW 0x01 MOVWF PORTB BCF PORTA,1 ; R/S = 0 R/W = 0 BCF PORTA,0 CALL TOGGLE RETURN ENAB_DISPLAY_CURSOR MOVLW 0x0D MOVWF PORTB BCF PORTA,1 ; R/S = 0 R/W = 0 BCF PORTA,0 CALL TOGGLE RETURN MOVE_CURSOR_SHIFT_DISPLAY MOVWF PORTB ; THE VALUE PASSED IN W IS SET TO PORTB BCF PORTA,1 ; R/S = 0 R/W = 0 BCF PORTA,0 CALL TOGGLE RETURN WRITE_CHAR MOVF CHAR,0 ; отправка значений в порт В MOVWF PORTB BSF PORTA,1 ; R/S = 1 R/W = 0 BCF PORTA,0 CALL TOGGLE RETURN TOGGLE BSF PORTA,2 ; SET ENABLE BIT BCF PORTA,2 ; CLEAR ENABLE BIT RETURN END Машинный код программы: :020000040000FA :100000008316803081000030850000308600831226 :1000100000308D003020362000308E000E08890020 :1000200083160814831208088C0041208E0A8D0A5A :10003000003C031D0E2850300D0290009009023044 :1000400090071C303C20900B212850300D0290006E :1000500090090230900718303C20900B2B281B2869 :100060000130860085100510472008000D308600FD :1000700085100510472008008600851005104720D0 :1000800008000C0886008514051047200800051597 :04009000051108004E :040094000034003400 :00000001FF Эта программа последовательно считывает из памяти EEPROM предварительно записанное туда сообщение и выводит его на дисплей. Затем выполняется перемещение этого сообщения по экрану. Логика работы программы понятна из комментарием и полностью определяется правилами работы с LCD-дисплеем, примененным в схеме. Дисплей имеет собственную систему команд, которая описана в справочной системе Multisim, а также в документации на LCD-дисплей Hitachi 44780, аналогом которого является дисплей, использованный в схеме. Задание 2. Перемещение символа по экрану. Используем следующую схему:  Для управления движением символа используются кнопки A и D. При нажатии кнопки А символ движется влево, при нажатии кнопки D – вправо. Если не нажата ни та, ни другая – символ стоит на месте. Одновременное нажатие кнопок не обрабатывается. Микроконтроллер управляется следующей программой: ;ЛР7. Задание 2. Перемещение символа по экрану ;Реализовано только перемещение вправо-влево. ;Управление: A - движение влево (канал RA3); D - движение вправо (канал RA4) ;Контроль границ экрана и обработка нажатия A + D не производится #include "p16f84a.inc" ;PIC16F84A definitions for MPASM assembler errorlevel -302 ; Отключить предупреждение 302 (о выборе ;банка памяти) SCounter EQU 0x0C ;Счетчик цикла для печати пустой строки ChrSpace EQU 0x00 ;Символ " " ChrStar EQU 0x2A ;Символ "*" ORG 0 ; Инициализация портов BSF STATUS, RP0 ;Выберем банк 1 MOVLW B'00011000' ;RA0...RA2 - на выход; RA3, RA4 - на вход. MOVWF TRISA MOVLW 0x00 ;назначение портов В на выход MOVWF TRISB BCF STATUS, RP0 ;Выберем банк 0 CALL Display_ON_Cursor_OFF ;Включим дисплей, выключим ;курсор ;Напечатаем звездочку в центре дисплея. ;Для этого предварительно напечатаем 16 + 8 = 24 пробела MOVLW .16 + .8 MOVWF SCounter MOVLW ChrSpace WriteNext CALL WriteChar DECFSZ SCounter, f GOTO WriteNext MOVLW ChrStar CALL WriteChar ;Главный цикл. Предполагается, что нажимается либо А, либо D. ;Одновременное нажатие не обрабатывается. ;Взаимная блокировка клавиш не выполняется. MainLoop BTFSS PORTA, 3 ;Нажата 'A'? GOTO Check_D ;Нет, проверим нажатие 'D' ;Нажата "A" ;Затираем предыдущий символ - на его месте печатаем пробел MOVLW B'00000110' ;06h - Команда LCD "Направление сдвига курсора - ВПРАВО" CALL SetCursorDirection MOVLW ChrSpace CALL WriteChar ;Меняем направление движения курсора MOVLW B'00000100' ;04h - Команда LCD "Направление сдвига ;курсора - ВЛЕВО" CALL SetCursorDirection ;Возвращаем курсор на прежнее место MOVLW ChrSpace CALL WriteChar ;Печатаем звездочку... MOVLW ChrStar CALL WriteChar GOTO MainLoop ;Опрашиваем дальше... Check_D BTFSS PORTA,4 ;Нажата 'D'? GOTO MainLoop ;Нет, опрашиваем дальше... ;Нажата "D" ;Затираем предыдущий символ - на его месте печатаем пробел MOVLW B'00000100' ;04h - Команда LCD "Направление сдвига ;курсора - ВЛЕВО" CALL SetCursorDirection MOVLW ChrSpace CALL WriteChar ;Меняем направление движения курсора MOVLW B'00000110' ;06h - Команда LCD "Направление сдвига ;курсора - ВПРАВО" CALL SetCursorDirection ;Возвращаем курсор на прежнее место MOVLW ChrSpace CALL WriteChar ;Печатаем звездочку... MOVLW ChrStar CALL WriteChar GOTO MainLoop ;Реализация команд управления LCD (см. справку Mulisim) ;Включить LCD, выключить курсор Display_ON_Cursor_OFF MOVLW B'00001100' MOVWF PORTB BCF PORTA,1 ;R/S := 0 BCF PORTA,0 ;R/W := 0 CALL Clock RETURN ;Сдвинуть курсор в заданном направлении ;Соответствующая комaанда - в регистре W SetCursorDirection MOVWF PORTB BCF PORTA,1 ;R/S := 0 BCF PORTA,0 ;R/W := 0 CALL Clock RETURN ;Вывести символ на экран в текущей позиции курсора ;Код выводимого символа должен быть в регистре W WriteChar MOVWF PORTB BSF PORTA,1 ;R/S := 1 BCF PORTA,0 ;R/W := 0 CALL Clock RETURN ;Команда Clock. Запускает передачу данных в LCD Clock BSF PORTA,2 ; SET ENABLE BIT BCF PORTA,2 ; CLEAR ENABLE BIT RETURN END Машинный код программы: :020000040000FA :1000000083161830850000308600831229201830AE :100010008C00203034208C0B0A282A303420851D97 :100020001C2806302F202030342004302F20203090 :1000300034202A3034200F28051E0F2804302F20AA :100040002030342006302F20203034202A30342035 :100050000F280C3086008510051039200800860016 :1000600085100510392008008600851405103920F8 :08007000080005150511080048 :04007800003400341C :00000001FF Логика работы программы полностью описана в комментариях и в дальнейших пояснениях не нуждается. |