- Код: Выделить всё
;Листинг программы
;Описание переменных
.def scancode=r16
.def schscan=r17
.def schopr=r18
.def code=r19
.def keycode=r20
.def temp=r21
.def frec=r22
.def dlit=r23
.def zader=r24
.def zader1=r25
;Основная программа
;Определение таблицы переходов
.ORG $0 ;Начало таблицы переходов
reset:
rjmp Start ;Переход на метку Start основной программы
.ORG $6 ;Вектор прерывания при переполнении таймера T0
rjmp IntT0
.ORG $7 ;Начальный адрес основной пpогpаммы
Start: ldi temp,$DF ;Определение стека
out SP,temp
rcall Scan ;Вызвать процедуру работы с клавиатурой
Frec: out TCNT0,frec ;Установить заданную частоту сигнала
ldi temp,$3 ;Запустить таймер T0, fck/64
out TCCR0,temp
out OCR1L,dlit ;Установить заданную длительность сигнала
ldi temp,$81 ;Настроить таймер T1, PWM 8 бит
out TCCR1A,temp
ldi temp,$1 ;Запустить таймеp T1, fck/1
out TCCR1B,temp
ldi temp,$2 ;Разрешить прерывания от таймера Т0
out TIMSK,temp
ldi temp,$3 ;Конфигурирование линий PB0 и PB1 на ;вывод
out DDRB,temp
sei ;Разрешить все пpеpывания
Work: rjmp Work ;Рабочий цикл пpогpаммы, ничего не делаем
;Процедура cканирования клавиатуры
Scan: clr scancode ;Сброс scancode
ldi temp,$0F ;Конфигурирование 4-х выводов порта D на вывод
out ddrd,temp ;и 4-х выводов на ввод
Stklav: sec ;Установить флаг переноса
ldi temp,$1 ;Назначить кл. S1 число 1
ldi schscan,$4 ;Загрузка счетчика сканирования
ldi code,$FE ;Загрузка исходного байта сканирования
Schs: out portd,code ;Вывод байта сканирования в порт D
rol code ;Сдвиг байта сканирования
in keycode,pind ;Ввод байта сканирования
swap keycode ;Поменять местами 4-е разряда байта возврата
ldi schopr,$3 ;Загрузка счетчика опросов
Scho: ror keycode ;Сдвиг байта возврата
brcc Oprkl ;Выход из прочедуры при обнаружении нажатой ;клав.
If0: inc temp ;Инкремент scancode
dec schopr ;Уменьшить счетчик опросов
brne Scho ;Если schopr=0, то перейти на метку Sсho
dec schscan ;Уменьшить счетчик сканирований
brne Schs ;Если schscan=0, то перейти на метку Sсhs
rjmp Stklav ;иначе перейти на метку Klav
Oprkl: cpi temp,$C ;При обнаружении нажатой кл. "Ввод"
breq Delay ;перейти на процедуру устранения дребезга контактов
mov scancode,temp ;иначе сохранить значение нажатой кл.в ;scancode
rjmp If0 ;и продолжить сканирование клавиатуры
;Процедура устранения дребезга контактов клавиш
;Задержка около 10 мс
Delay: clr zader
ldi zader1,$96
Delay1: dec zader
brne Delay1
dec zader1
brne Delay1
;Процедура задания сигналам частоты и длительности
Setkl: cpi scancode,$0 ;Если нажата только кл. "Ввод", то
breq If0 ;снова сканировать клавиатуру
cpi scancode,$1
ldi frec,$D9 ;Задать частоту сигнала 800 Гц
ldi dlit,$18 ;и длительность импульса ШИМ-сигнала 12 мкс
breq Endkl
cpi scancode,$2
ldi frec,$ED ;Задать частоту сигнала 1600 Гц
ldi dlit,$30 ;и длительность импульса ШИМ-сигнала 24 мкс
breq Endkl
cpi scancode,$3
ldi frec,$F3 ;Задать частоту сигнала 2400 Гц
ldi dlit,$48 ;и длительность импульса ШИМ-сигнала 36 мкс
breq Endkl
cpi scancode,$4
ldi frec,$F7 ;Задать частоту сигнала 3200 Гц
ldi dlit,$60 ;и длительность импульса ШИМ-сигнала 48 мкс
breq Endkl
cpi scancode,$5
ldi frec,$F9 ;Задать частоту сигнала 4000 Гц
ldi dlit,$78 ;и длительность импульса ШИМ-сигнала 60 мкс
breq Endkl
cpi scancode,$6
ldi frec,$FA ;Задать частоту сигнала 4800 Гц
ldi dlit,$90 ;и длительность импульса ШИМ-сигнала 72 мкс
breq Endkl
cpi scancode,$7
ldi frec,$FB ;Задать частоту сигнала 5600 Гц
ldi dlit,$A8 ;и длительность импульса ШИМ-сигнала 84 мкс
breq Endkl
cpi scancode,$8
ldi frec,$FC ;Задать частоту сигнала 6400 Гц
ldi dlit,$C0 ;и длительность импульса ШИМ-сигнала 96 мкс
breq Endkl
cpi scancode,$9
ldi frec,$FD ;Задать частоту сигнала 7200 Гц
ldi dlit,$D8 ;и длительность импульса ШИМ-сигнала 108 мкс
breq Endkl
ldi frec,$FE ;Задать частоту сигнала 8000 Гц
ldi dlit,$F0 ;и длительность импульса ШИМ-сигнала 120 мкс
Endkl: ret
;Пpоцедуpа пpеpывания по пеpеполнению таймеpа T0
IntT0: push temp ;Сохранить temp в стеке
out TCNT0,frec ;Пеpезагpузить таймер Т0
in temp,SREG ;Сохранить SREG
sbis pinb,0 ;Если на PB0 был "0", то установить "1"
rjmp Ust1 ;и наоборот
cbi portb,0
rjmp EndT0
Ust1: sbi portb,0
EndT0: out SREG,temp ;Восстановление SREG
pop temp ;Выгрузить данные из стека
reti ;Выйти из процедуры
- Код: Выделить всё
;листинг проектного фйайла
; Micro + software running
; ------------------------------------------------------------
.MICRO "AT90S4433"
.PROGRAM "23.asm"
.TARGET "23.hex"
.TRACE ; Activate micro trace
; Following lines are optional; if not included
; exactly these values are taken by default
; ------------------------------------------------------------
.POWER VDD=5 VSS=0 ; Power nodes
.CLOCK 4meg ; Micro clock
.STORE 250m ; Trace (micro+signals) storage time
; Micro nodes: RESET, AREF, PB0-PB5, PC0-PC5, PD0-PD7, ACO, TIM1OVF
; Define here the hardware around the micro
; ------------------------------------------------------------
K0 PD0 n1 ;Подсоединить клавишу "0" между выводом PD0 и точкой n1
K1 PD0 n2 ;Подсоединить клавишу "1" между выводом PD0 и точкой n2
K2 PD0 n3 ;Подсоединить клавишу "2" между выводом PD0 и точкой n3
K4 PD1 n1 ;Подсоединить клавишу "4" между выводом PD1 и точкой n1
K5 PD1 n2 ;Подсоединить клавишу "5" между выводом PD1 и точкой n2
K6 PD1 n3 ;Подсоединить клавишу "6" между выводом PD1 и точкой n3
K8 PD2 n1 ;Подсоединить клавишу "8" между выводом PD2 и точкой n1
K9 PD2 n2 ;Подсоединить клавишу "9" между выводом PD2 и точкой n2
KA PD2 n3 ;Подсоединить клавишу "A" между выводом PD2 и точкой n3
KC RESET GND ;Подсоединить клавишу "C" между выводом RESET и GND
KD PD3 n2 ;Подсоединить клавишу "D" между выводом PD3 и ;точкой n2
KE PD3 n3 ;Подсоединить клавишу "E" между выводом PD3 и ;точкой n3
R1 PD4 n1 0.001k ;Замкнуть вывод PD4 и точку n1
R2 PD5 n2 0.001k ;Замкнуть вывод PD5 и точку n2
R3 PD6 n3 0.001k ;Замкнуть вывод PD6 и точку n3
R4 n1 VDD 5k ;Соединить резистор R4 между точкой n1 и VDD
R5 n2 VDD 5k ;Соединить резистор R5 между точкой n2 и VDD
R6 n3 VDD 5k ;Соединить резистор R6 между точкой n3 и VDD
.PLOT v(PB0) v(PB1)
Программа ждет задания с кнопки (1-С), дальше ожидает ввода кнопкой E ну и выводится ШИМ.
Заранее благодарен.