За материал спасибо. Я на самом деле не знал где правильно рыть.
Итак (выдержка из документации):
При выполнении команды SLEEP происходит предвыборка следующей инструкции (PC+1). Если прерывание должно выводить микроконтроллер из режима SLEEP, соответствующий бит разрешения прерывания устанавливается в '1'. Микроконтроллер выходит из режима SLEEP независимо от состояния бита GIE. Если GIE=0, выполняется следующая инструкция после SLEEP без перехода по вектору прерывания. Если GIE=1, исполняется следующая инструкция после SLEEP и происходит переход на подпрограмму обработки прерываний (адрес 0004h). Когда выполнение какой-либо команды при выходе из режима SLEEP нежелательно, необходимо после команды SLEEP использовать инструкцию NOP.
Нас не интересует переход на подпрограмму обработки прерываний. Нужно заснуть, по прерыванию проснуться, и работать дальше после команды Sleep. Я сделал всё как положено. Однако, теперь микроконтроллер не засыпает, выполняет команду Sleep и по непонятным причинам просыпается и "молотит" дальше (WDT отключен; сделан внешний подтягивающий резистор к кнопке).
Помогите разобраться!!!
LIST P=PIC16F84A
__CONFIG H'3FF1'
STATUS EQU H'0003'
PORTB EQU H'0006'
TRISB EQU H'0006'
OPTION_REG EQU H'0001' ; внимание! регистр из 2го банка
INTCON EQU H'000B' ; т.н. регистр запросов и масок
Reg_1 EQU H'000C'
Reg_2 EQU H'000D'
Reg_3 EQU H'000E'
org 0 ; начало программы
; подготовительные моменты
bsf STATUS,5 ; переход в Банк 1
; нам нужна нога RB0/INT для внешнего прерывания (согл. документации)
movlw b'00000001' ; RB0/INT на вход, остальные на выход
movwf TRISB
; включение подтягивающих резисторов, в частности для ноги RB0/INT
; т.к. управляющий бит инверсный, используем команду bcf
;bcf OPTION_REG,7
bcf STATUS,5 ; переход назад в Банк 0
clrf PORTB ; очистка порта
; работа
Start
bsf PORTB,7 ; подали сигнал на RB7
; короткая задержка, чтобы успеть отпустить кнопку после выхода из сна
call Pause
; здесь могут быть и др строчки,
; касающиеся, работы "вне сна"
; отслеживание нажатия кнопки на ноге RB0 (для входа в "сон")
m1 btfsc PORTB,0 ; бит-проверка ножки RB0/INT
goto m1
bcf PORTB,7 ; выключили сигнал на RB7 перед сном
; короткая задержка, чтобы успеть отпустить кнопку перед входом в сон
call Pause
; определение разрешений прерываний
bsf INTCON,4 ; разрешили прерывание по ноге RB0/INT
; настройка прерывания на "спадающий" фронт на ножке RA0/INT,
; т.к. она ч.з. внутренний резистор "подтянута" к плюсу
bsf STATUS,5 ; переход в Банк 1
bcf OPTION_REG,6
bcf STATUS,5 ; переход назад в Банк 0
sleep
; сегмент для контроля выполнения команды sleep
bsf PORTB,6 ; выключили сигнал на RB6
call Pause
bcf PORTB,6 ; выключили сигнал на RB6
goto Start
;delay = 1'000'000 machine cycles
Pause movlw .173
movwf Reg_1
movlw .19
movwf Reg_2
movlw .6
movwf Reg_3
wr decfsz Reg_1, F
goto wr
decfsz Reg_2, F
goto wr
decfsz Reg_3, F
goto wr
return
end ; конец программы
Прикрепленный файл:
9092381.zip