В прикрепленных файлах находятся программы портов ввода-вывода (считывание значение через буфер с задатчиков и выдача их через регистр на светодиоды) и матричной клавиатуры. При записи программы портов ввода-вывода в МК пятый светодиод всегда выключен (светодиоды управляются нулем, с РА4 подходит +5 В -> светодиод не горит), программа матричной клавиатуры на стенде работает нормально.
Код: Выделить всё
;***********************************************************************
; Программ один раз в секунду считывает данные с входов и выводит их
;без изменений на выходы.
;***********************************************************************
.include "8515def.inc" ; Подключение внешней библиотеки с описанием
; символических имен и определением адресов
; регистров микроконтроллера
.cseg
.org 0
rjmp init ; Вектор прерывания по включению питания,
.org $0d ;
.include "MyLib.inc" ; Подключение файла с описанием символических
; имен портов и подпрограммами
;****** Формирование задержки 1с **************************************
delay1:
ldi temp2, 25 ;
d0: ser temp1 ;
d1: ldi temp, 209 ;
d2: dec temp ;
brne d2 ;
dec temp1 ;
brne d1 ;
dec temp2 ;
brne d0 ;
ret
;****** Инициализация контроллера ****************************************
; выполняется при включении питания, сбросу RESET, или от
; сторожевого таймера
;*************************************************************************
init:
;****** Инициализация МК **********************************
ldi temp, low(RAMEND) ; Инициализация указателя стека
out SPL, temp ; в конце внутреннего ОЗУ
ldi temp, high(RAMEND);
out SPH, temp ;
rcall Config_Port ; Вызов подпрограммы конфигурирования портов
;
;****** Основная программа ***********************************************
main:
clr temp ; Устанавливаем линии порта А как входы
out ddra, temp ;
out porta, temp ; Отключаем подтягивающие резисторы
cbi portc, adr1 ; Устанавливаем адрес первого буфера
sbi portc, adr0 ;
cbi portd, RD ; Разрешение передачи данных в порт А
in inl, pina ; Читаем содержимое первого буфера
sbi portd, RD ; Запрет передачи данных в порт А
cbi portc, adr0 ; Устанавливаем адрес второго буфера
sbi portc, adr1 ;
cbi portd, RD ; Разрешение передачи данных в порт А
in inh, pina ; Читаем содержимое второго буфера
sbi portd, RD ; Запрет передачи данных в порт А
ser temp ; Устанавливаем линии порта А как входы
out ddra, temp ;
mov outh, inh ;
mov outl, inl ;
cbi portc, adr1 ; Устанавливаем адрес первого регистра
sbi portc, adr0 ;
out porta, outl ; Выставляем данные на линии порта А
cbi portd, WR ; Стробирующий сброс команды записи
sbi portd, WR ;
cbi portc, adr0 ; Устанавливаем адрес второго регистра
sbi portc, adr1 ;
out porta, outh ; Выставляем данные на линии порта А
cbi portd, WR ; Стробирующий сброс команды записи
sbi portd, WR ;
rcall delay1 ; Вызов подпрограммы формирования задержки 1с
rjmp main ; Код: Выделить всё
;******************************************************
.include "8515def.inc" ;файл определений AT90S8515
.def temp=r16 ;временная переменная
.def cols=r18 ;номер сканируемого ряда
;клавиатуры
.def rots=r21 ;номер строки клавиатуры
.def key=r19 ;номер кнопки
.def scancode=r20 ;сканирующий код
.cseg ; CODE segment
.org 0
rjmp init ; Вектор прерывания по включению питания,
; сбросу RESET или от сторожевого таймера
rjmp scankeys ; Int 0 - Прерывание от клавиатуры
.org $0d
;Подпрограмма обработки клавиатуры
scankeys:
clr key
clr scancode
ldi cols,2
sec
scan: rol scancode ;формирование очередного скан-кода
out PORTD,scancode ;вывод на клавиатуру
clc
ldi rots,4
in temp,PIND ;ввод состояния клавиатуры
mm: rol temp
brcc nn ;проверка замыкания кнопки
rjmp press ;переход при замыкании (С=0)
nn: inc key ;увеличение номера кнопки
dec rots ;уменьшение номера строки
brne mm
dec cols ;уменьшение номера ряда
brne scan
press: cpi key,8
breq f1 ;выход при отсутствии замыканий
rcall outkey ;вывод на дисплей
f1: reti
outkey:
cpi key,0
breq case1
cpi key,1
breq case2
cpi key,2
breq case3
cpi key,3
breq case4
cpi key,4
breq case5
cpi key,5
breq case6
cpi key,6
breq case7
cpi key,7
breq case8
case1:
ldi temp,0b01111111
out PORTA,temp
reti
case2:
ldi temp,0b10111111
out PORTA,temp
reti
case3:
ldi temp,0b11011111
out PORTA,temp
reti
case4:
ldi temp,0b11101111
out PORTA,temp
reti
case5:
ldi temp,0b11110111
out PORTA,temp
reti
case6:
ldi temp,0b11111011
out PORTA,temp
reti
case7:
ldi temp,0b11111101
out PORTA,temp
reti
case8:
ldi temp,0b11111110
out PORTA,temp
reti
reti
;Инициализация
init:
ldi temp,low(RAMEND) ;Инициализация
out spl,temp ;указателя стека
ldi temp,high(RAMEND)
out sph,temp
;Инициализация портов
ser temp
out DDRA,temp ;порт РА на вывод
ldi temp,$03 ;линии порта PD0-PD3 на вывод,
out DDRD,temp
ldi temp,$F0 ;PD4-PD7 на ввод
out PORTD,temp
;Инициализация таймера 0
ldi temp,$05
out TCCR0,temp ;коэффициент деления 1024
ldi temp, (1<<TOIE0)
out TIMSK, temp ;разрешение прерываний от таймера
sei ;разрешение прерываний
loop: rjmp loop

