вопрос, корректно из подпрограммы rjmp-ом выпрыгивать?
Добавлено: Пн апр 28, 2014 00:27:53
вопрос господа гуру, можно из подпрограммы sled: rjmp-ом выпрыгивать?
Спойлер
Код: Выделить всё
; программа реализует следующие действия. при нажатии кнопки ( INT0) первый раз, загорается светодиод на ноге D0
; далее бегущий огонек бежит от С0 по С5 и так 2 цикла, далее бегущий огонек бежит в обратном порядке 2 цикла
; далее моргают все 6 светодиодов порта С 2 раза. При нажатии кнопки второй раз Порт С перестает моргать вообще
; и D0 тоже погашен. прога работает
;
; 865 байт имя программы в авр студии ---- zxc1 -----
;****************************************************************************************
.cseg
.include "m8Adef.inc"
;***********************************************************************
.org $000 rjmp RESET ;Reset Handler
.org $001 rjmp EXT_INT0 ;rjmp EXT_INT0 ; IRQ0 Handler
;.org $002 reti ;rjmp EXT_INT1 ; IRQ1 Handler
;.org $003 reti ;rjmp TIM2_COMP ; Timer2 Compare Handler
;.org $004 reti ;rjmp TIM2_OVF ; Timer2 Overflow Handler
;.org $005 reti ;rjmp TIM1_CAPT ; Timer1 Capture Handler
;.org $006 reti ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;.org $007 reti ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;.org $008 reti ;rjmp TIM1_OVF ; Timer1 Overflow Handler
;.org $009 reti ;rjmp TIM0_OVF ; Timer0 Overflow Handler
;.org $00a reti ;rjmp SPI_STC ; SPI Transfer Complete Handler
;.org $00b reti ;rjmp USART_RXC ; USART RX Complete Handler
;.org $00c reti ;rjmp USART_UDRE ; UDR Empty Handler
;.org $00d reti ;rjmp USART_TXC ; USART TX Complete Handler
;.org $00e reti ;rjmp ADC ; ADC Conversion Complete Handler
;.org $00f reti ;rjmp EE_RDY ; EEPROM Ready Handler
;.org $010 reti ;rjmp ANA_COMP ; Analog Comparator Handler
;.org $011 reti ;rjmp TWSI ; Two-wire Serial Interface Handler
;.org $012 reti ;rjmp SPM_RDY ; Store Program Memory Ready Handler
;***********************************************************************
RESET:
ldi r16,low(RAMEND) ;загрузка указателя стека
out SPL,r16
ldi r16,high(RAMEND)
out SPH,r16
ldi r16, 0b00000001
out DDRD, r16 ; D0 выход , D1-D7 входы
ldi r16, 0b11111110
out PORTD, r16 ; D1-D7 подтяжка резистором внутреним
ldi r16, 0b11111111
out DDRC, r16 ; С на вых
ldi r16, 0b00000000
out MCUCR, r16 ; регистр настроийки типа прерывания (INT0, сработают по логическому нулю)
ldi r16, 0b01000000
out GICR, r16 ; разрешение прерываний INT0, (регистр управления прерыв.)
ldi r16, 0b01000000
out GIFR, r16 ; разрешение прерываний INT0, (регист маски прерывания)
sei ; разрешаете прерывания
;***********************************************************************
start:
sbis PIND,0 ; считываем состояние ножки порта D , если горит, то пропускаем следующюю команду
rjmp start
rjmp main
;*****************************************************************************************************************
main:
rcall sled
ldi r16, 0b00000001
rcall zaderjka
ldi r16, 0b00000010
rcall zaderjka
ldi r16, 0b00000100
rcall zaderjka
ldi r16, 0b00001000
rcall zaderjka
ldi r16, 0b00010000
rcall zaderjka
ldi r16, 0b00100000
rcall zaderjka
ldi r16, 0b00000000
rcall zaderjka
;********************************************************************************************************************8
main1:
rcall sled
ldi r16, 0b00000001
rcall zaderjka
ldi r16, 0b00000010
rcall zaderjka
ldi r16, 0b00000100
rcall zaderjka
ldi r16, 0b00001000
rcall zaderjka
ldi r16, 0b00010000
rcall zaderjka
ldi r16, 0b00100000
rcall zaderjka
ldi r16, 0b00000000
rcall zaderjka
;************************************************************************************************************************
main2:
rcall sled
ldi r16, 0b00100000
rcall zaderjka
ldi r16, 0b00010000
rcall zaderjka
ldi r16, 0b00001000
rcall zaderjka
ldi r16, 0b00000100
rcall zaderjka
ldi r16, 0b00000010
rcall zaderjka
ldi r16, 0b00000001
rcall zaderjka
ldi r16, 0b00000000
rcall zaderjka
;**************************************************************************************************************************
main3:
rcall sled
ldi r16, 0b00100000
rcall zaderjka
ldi r16, 0b00010000
rcall zaderjka
ldi r16, 0b00001000
rcall zaderjka
ldi r16, 0b00000100
rcall zaderjka
ldi r16, 0b00000010
rcall zaderjka
ldi r16, 0b00000001
rcall zaderjka
ldi r16, 0b00000000
rcall zaderjka
;*************************************************************************************************************************
main4:
rcall sled
ldi r16, 0b11111111
out PORTC, r16
rcall zaderjka1
ldi r16, 0b00000000
out PORTC, r16
rcall zaderjka1
rcall sled
ldi r16, 0b11111111
out PORTC, r16
rcall zaderjka1
ldi r16, 0b00000000
out PORTC, r16
rcall zaderjka1
rjmp main
;***********************************************************************************************************************
zaderjka:
out PORTC, r16
ldi r16,0 ;задержка примерно 50 милисекунд
ldi r17,100
Loop1: dec r16
brne Loop1
dec r17
brne Loop1
ret
;*************************************************************************************************************************
zaderjka1:
ldi r16,0 ;задержка примерно 130 милисекунд
ldi r17,0
Loop2: dec r16
brne Loop2
dec r17
brne Loop2
ret
;***************************************************************************************************************************
EXT_INT0:
cli ; запретить прерывания
push r16 ; сохраняем используемые регистры r16 (этих пушей может быть много)
push r17 ; сохраняем используемые регистры r17 (этих пушей может быть много)
in r17, SREG ; сохраням флаги
push r17 ; и запихиваем их в стек
sbis PIND,0 ; считываем состояние ножки порта D , если горит, то пропускаем следующюю команду
rjmp KUKA ; перепрыгмваем на команду поджога светодиода
rcall KUKA1 ; вызываем подпрограмму гашения светодиода
rcall drebezg ; антидребезг (задержка 130 милисекунд)
pop r17 ; извлекаем из стека флаги в r17 (обратный порядок при извлечении из стека)
out SREG, r17 ; отправляем их обратно в регистр флагов
pop r17 ; восстанавливаем регистр r17
pop r16 ; восстанавливаем регистр r16
sei ; разрешить прерывания
reti ; возвращаемся из прерывания
;************************************************************************************************************************
KUKA1:
cbi PORTD, 0 ; погасить D0
ret
;**********************************************************************************************************************
KUKA:
sbi PORTD, 0 ; зажигаем D0
rcall drebezg ; антидребезг (задержка 130 милисекунд)
pop r17 ; извлекаем из стека флаги в r17 (обратный порядок при извлечении из стека)
out SREG, r17 ; отправляем их обратно в регистр флагов
pop r17 ; восстанавливаем регистр r17
pop r16 ; восстанавливаем регистр r16
sei ; разрешить прерывания
reti ; возвращаемся из прерывания
;*********************************************************************************************************************
drebezg:
ldi r16,0 ;задержка примерно 130 милисекунд
ldi r17,0
Loop7: dec r16
brne Loop7
dec r17
brne Loop7
ret
;*********************************************************************************************************************
sled:
sbis PIND,0 ; считываем состояние ножки порта D , если горит, то пропускаем следующюю команду
rjmp start ; на безделье
ret
;**********************************************************************************************************************