Форум по микроконтроллерам: PIC16F688 прерывания по изменению PORTA - Форум по микроконтроллерам

Перейти к содержимому

Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

PIC16F688 прерывания по изменению PORTA неправильно переходит по goto - не пойму, что не так делаю

#1 Пользователь офлайн   AlonsoBV 

  • Прибывший
  • Группа: Пользователи
  • Сообщений: 4
  • Регистрация: 05 Сентябрь 18

Отправлено 25 Февраль 2020 - 15:27

Доброго времени суток Всем!Неожиданно заткнулся при переходе на прерывания (по изменению состояния PORTA). Пересматриваю код ужу много раз, даже в ЕЕПРОМ записывал результаты - вроде всё правильно, вот только не получаю нужного перехода по окончании действий. Коротко описание и дальше кусочки кода:- PIC управляет блоком питания одноплатника и периферии- к нему подключены две кнопки компа: power и reset- PIC может программно нажимать эти кнопки, но хочу добавить и отслеживание внешних аппаратных нажатий (чтобы была обратная связь: нажали кнопку извне - PIC отрубил периферию)- и вот тут возможны ДВА варианта: если нажатие короткое - то это "сон", и потом периферию нужно подключать через 6 секунд (комп просыпается быстро). А если нажатие длинное - то это полное выключение, и периферию потом нужно включать через 36 секунд (загрузка компа)- на последнее место и не попадаю от слова никак.
cblock 0x20
w_temp 			; для сохранения рабочего регистра
status_temp	; для сохранения текущего состояния
flag_box			; различные программные флаги (различные признаки состояний и вычислений)
endc

#define KEY_PRESS   flag_box, 2		; флаги кнопок: - нажата кнопка (сам факт нажатия в принципе, любая кнопка)
#define KEY_POWER   flag_box, 3		; - нажата "power"
#define PRESS_LONG   flag_box, 7		; - длинное нажатие кнопки "power" (выключение VIM2)

#define	PIN_RES   PORTA, 1		; вход: внешнее нажатие кнопки "reset"
#define	PIN_OFF   PORTA, 2		; вход: внешнее нажатие кнопки "power"

ORG 	0x004   						; вектор прерываний
   bcf		INTCON, RAIE
   movwf   w_temp          		; сохранение состояния контроллера
   movf	STATUS, w   	
   movwf	status_temp		
   clrwdt
   btfsc	PIN_OFF
   btfss	PIN_RES
   bsf		KEY_PRESS		; здесь взводим необходимые флаги нажатия для дальнейшего использования (что нажали кнопку вообще, и какую именно в частности)
   btfss	KEY_PRESS
   goto	end_keys
   btfss	PIN_OFF
   bsf		KEY_POWER
end_keys
   movf	PORTA, w
   bcf		INTCON, RAIF
   movf	status_temp, w	; восстановление состояния контроллера
   movwf	STATUS 			
   swapf   w_temp,f
   swapf   w_temp,w		
   retfie   								; выход из прерываний
 ...

 off_start
	bcf 	STATUS,RP0 			; банк 0
	movlw	d'150' 					; пауза 30 сек 
	call	delay_sec
	bcf	PRESS_LONG
	
sleep_start
	bcf 	STATUS,RP0 			; банк 0
	movlw	d'30'   					; пауза 6 сек 
	call	delay_sec
	bsf 	PIN_PWR_HUB   	; включаем периферию
	bsf 	PIN_PWR_HUB2
	call	clear_keys
	clrf	flag_box   					; очистим регистр флагов перед началом работы	

 ;***** ОСНОВНОЙ РАБОЧИЙ ЦИКЛ *****************************************************
 system_work
	bcf 	STATUS,RP0 			; банк 0
	...
	btfsc	KEY_PRESS			; проверим - не нажали ли кнопку выключения снаружи (минуя БП)
	goto	ext_press
    ...   	
	goto	system_work

ext_press
	bcf 	STATUS,RP0 				; банк 0
	bcf 	PIN_PWR_HUB		; при нажатии на кнопки VIM2 в любом случае отключаем периферию, потом разбираемся
	bcf   	PRESS_LONG
	btfss   KEY_POWER			; если нажали "reset" - обнуляем нажатые кнопки и на старт системы
	goto	off_start                		; иначе - обрабатываем кнопку "power"
	movlw   d'5' 							; пауза 1 сек
	call  	delay_sec
	btfss	PIN_OFF
	bsf   	PRESS_LONG 		; длинное нажатие (выключили VIM2) - взводим флаг, обнуляем кнопки и ждем...
	call  	clear_keys
wait_key
	bcf 	STATUS,RP0              ; банк 0
	btfss	PIN_ACC      			; пока ждем - следим за включенным зажиганием (вдруг так не включив VIM2 заглушили авто)
	goto 	system_off_total 	; если зажигание выключили - переход на полное выключение системы, поскольку Хадас и так уже выключен/спит
	call 	measure_vcc			; измерим напряжение бортсети (этого никто не отменял)
	btfss	VCC_LOW
	btfsc	VCC_HIGH   			; если норма - ждем дальше, нет - выключаемся
	goto	vcc_error
	btfss	KEY_POWER   		; проверим - не нажали ли кнопку "power" снаружи (минуя БП), нажали...	
	goto	wait_key
	btfsc	PRESS_LONG 		; ...проверим предыдущее нажатие (на предмет в какое место возвращаться - включение, или выход из сна)
	goto	off_start
 	goto	sleep_start

 clear_keys
	bcf 	STATUS,RP0
	bcf 	KEY_PRESS
	bcf 	KEY_POWER
	movf 	PORTA, w
	bcf 	INTCON, RAIF
	bsf	INTCON, RAIE
	return
 


И вот с этой писаниной у меня есть всё, кроме последнего перехода "goto off_start" - периферия включается через 6 секунд в любом случае, хотя при длинном нажатии на кнопку в ЕЕПРОМ пишется PRESS_LONG = лог1
Ткните носом, плиз, чего я не вижу? Что делаю не так? Ума не приложу... :-(

Сообщение отредактировал AlonsoBV: 25 Февраль 2020 - 15:43

0

#2 Пользователь офлайн   nick14 

  • Группа: Администраторы
  • Сообщений: 1 479
  • Регистрация: 15 Февраль 11
  • ГородРыбинск

Отправлено 26 Февраль 2020 - 21:22

Не очень понял обработку прерывания... По логике при событии прерывания необходимо проверить какая кнопка нажата и это вроде как определяется, а вот как длительность нажатия контролируете не понимаю.
0

#3 Пользователь офлайн   MAZ 

  • Консерватор - до мозга костей и суставов
  • Группа: Администраторы
  • Сообщений: 1 471
  • Регистрация: 15 Февраль 11
  • ГородРоссия

Отправлено 26 Февраль 2020 - 22:15

Мне кажется Вы просто запутались. Ваши прерывания ни как не связаны с временными циклами. Вообще в прерываниях флаги ставить можно, но лучше не надо. :D
Да, бросается в глаза, что Вы сбрасываете флаг прерывания, до сохранения контекста в прерывании.
На мой взгляд, лучше в прерывании считать определенное время, по прерыванию таймера, ну там 5.10... мс, а кнопки проверять в промежутках между прерываний. Там же можно проверять и порты и прочие условия. Соответственно простым счетам прерываний можно получать нужное время, секунды, часы, годы.)), задержки для дребезга, и много еще чего полезного.
Могу подробней рассказать, если так непонятно.
Если бы Бог не был консерватором, вместо десяти заповедей мы имели бы десять предложений
0

#4 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 903
  • Регистрация: 15 Февраль 11

Отправлено 27 Февраль 2020 - 00:58

Вам, для задачи, прерывание нужно - как собаке пятая нога.
Нет ничего проще обычного опроса вывода и измерения времени состояния на этом выводе. Этого вполне достаточно для всех мыслимых и немыслимых функций любой кнопки.
А с прерываниями вы просто запутаете себя.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

Поделиться темой:


Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей