Jump to content

    

pic16f873a прерывание по i2C вопрос

не могу сообразить, что не так.

есть простое устройство-слэйв на F873a . которое принимает несколько байтов от мастера
и выводит их на индикатор.

ловля данных происходит по прерыванию.

пишу на asme

и вроде всё хорошо, но напрягает момент, который не могу себе объяснить.
если в основной программе не сделать повторно 

bsf		INTCON,7			;разрешение всех прерываний
bsf		INTCON,6			;разрешение внешних прерываний

, то после возвращения из прерывания в основную программу прерывания больше не возникнут.

насколько я понимаю, INTCON при прерывании не изменяется, если его не трогать.

 Пытался этот код вписывать в модуль прерывания перед retfie, но ситуацию это не поменяло.

Почему такое происходит ?

 

Share this post


Link to post
Share on other sites

Вы исходите из того, что все написали правильно, но код почему то работает совсем не так, как Вы написали... )))

Иначе бы Вы привели этот самый код.

Вход в прерывания АВТОМАТИЧЕСКИ запрещает прерывания путем гашения GIE (того самого INTCON, 7 - не стоит писать не именованные константы, ибо не все знают номер бита глобального разрешения прерываний).

Выход из прерывания с помощью retfie АВТОМАТИЧЕСКИ разрешает прерывания путем взведения того же GIE.

То есть управлять глобальным разрешением в обработчике нельзя/нет необходимости.

Бит PEIE (INTCON, 6) в выше описанной процедуре участия не принимает и дергать его совершенно бессмысленно.

 

Share this post


Link to post
Share on other sites

спасибо за ответ.
в принципе , я так себе и представляю ситуацию, но , к сожалению, где-то совершаю промах.

вот код модуля прерывания. в общем, всё стандартно.

;подпрограмма обработки прерывания
int_SSP	;org 0x04	
	
	movf		STATUS,W
	movwf		_STAT				;сохранение статуса
	BANKSEL		PIE1
	bcf		PIE1,SSPIE		;запрет прерываний 
	BANKSEL		PIR1
	bcf		PIR1,SSPIF		;сбросить бит прерывания от SSP

	BANKSEL		SSPSTAT
	movf		SSPSTAT,W		; SMP   CKE   D/#A   P   S   R/#W   UA  BF
	andlw		b'00101101'		;маска проверяемых битоа
	BANKSEL		TEMP_RG
	movwf		TEMP_RG

test1
	movlw		0x29
	xorwf		TEMP_RG,W
	btfss		STATUS,Z		;DATA ?
	goto		test2	

StateDSWB
	BANKSEL		SSPBUF
	movf		SSPBUF,W
	movwf		INDF
	incf		FSR,F
	goto		out

test2
	movlw		0x09
	xorwf		TEMP_RG,W
	btfss		STATUS,Z		;ADDRESS ?
	goto		out
StateAB
	BANKSEL		SSPBUF
	movf		SSPBUF,W
	
out	
	BANKSEL		PIE1
	bsf		PIE1,SSPIE
	movf		_STAT,W
	movwf		STATUS

	retfie

для того, чтоб разобраться в ситуации, я основной модуль упростил .

в итоге он выглядит не совсем реалистичным ( момент прерывания я задаю вручную, осуществляя посылку от другого устройства по i2c),

но мне важно понять проблему.


в пустом цикле жду прерывания.
по нажатию  кнопки, осуществляется некий вывод из буфера ( не показано).

затем возврат.

так вот без установки пресловутых GIE,PEIE почему-то дальнейшие прерывания не наблюдаются.

;  .............................. 

	clrf		SSPSTAT
		
	bsf		INTCON,GIE		;разрешение прерываний
	bsf		INTCON,PEIE			;разрешение внешних прерываний
	BANKSEL PIE1
	bsf		PIE1,SSPIE

wait_int
				; ожидаем прерывания по i2с
	
key_down
	BANKSEL		PORTC	;ожидание нажатия кнопки
	btfsc		PORTC,2
	goto		key_down
key_up
	btfss		PORTC,2	
	goto	 	key_up	

VYVOD					;вывод информации
;......................
	bsf		INTCON,GIE	;без этих двух строк не будет прерывания
	bsf		INTCON,PEIE	;
	

	goto		`wait_int	;возврат к ожиданию

 

Share this post


Link to post
Share on other sites
11 hours ago, balk said:

в общем, всё стандартно.


;подпрограмма обработки прерывания
int_SSP	;org 0x04

Где сохранение аккумулятора?	
	
	movf		STATUS,W              аккумулятор благополучно испорчен
	movwf		_STAT				;сохранение статуса

Зачем запрещать прерывания от модуля, если в конце Вы их разрешаете, а глобальное разрешение все равно запрещено?
Флаги прерываний будут установлены ВНЕ ЗАВИСИМОСТИ ОТ РАЗРЕШЕНИЙ. Это действие вообще не имеет никакого смысла.

	BANKSEL		PIE1
	bcf		PIE1,SSPIE		;запрет прерываний 


	BANKSEL		PIR1
	bcf		PIR1,SSPIF		;сбросить бит прерывания от SSP

.......................
.......................


	BANKSEL		PIE1
	bsf		PIE1,SSPIE
	movf		_STAT,W
	movwf		STATUS

	retfie

 

Мои комментарии в коде выделены цветом, как и сам странный код.

У Вас, мягко говоря, все нестандартно...

Share this post


Link to post
Share on other sites

спасибо,My504 ! Ободряющее замечание.

ляпы свои убрал.

тем не менее, пока ничего в голове у меня не проясняется.

попробую ещё тщательно всё проверить.

Share this post


Link to post
Share on other sites

У вас где-то непреднамеренно (ошибочно) запрещается прерывание. Косвенная адресация портит. 

Share this post


Link to post
Share on other sites

похоже, что подобрался  к проблеме

обнаружил, что фактически ( на осциллографе) у меня не происходит принятия адреса моим слэйвом

-на девятом синхроимпульсе единица.

если из цикла ожидания выскочить (например , через кнопку) и попасть на пресловутые bsf GIE и PEIE,

то мой слэйв оживает и начинает отвечать на адрес и принимать данные.

получается , косяк в инициализации модуля ?

вот код инициализации . не понимаю, что не так

	BANKSEL		TRISC
	movlw		b'00011111'		;RC1-RC0 -входы генератора TMR1
								;RC2 -кнопка
								;RC3-RC4 -I2C
	movwf		TRISC
;------настройка I2C ---------
	BANKSEL		SSPCON
	movlw		0x36
	movwf		SSPCON ;установка слэйв-режима
	BANKSEL 	SSPADD
	movlw		0x18
	movwf		SSPADD; устанавливаем адрес слэйва
	clrf		SSPSTAT
;-----настройка прерываний----------------
	bsf			INTCON,GIE		
	bsf			INTCON,PEIE		
	BANKSEL 	PIE1
	bsf			PIE1,SSPIE

Share this post


Link to post
Share on other sites

c инициализацией всё в порядке оказалось.

нашёл в подпрограмме работы с таймером ( она участвовала в выводе информации) операцию с INTCON.

после правки, всё стало на места.

спасибо, уважаемые коллеги, Ваша поддержка очень помогла!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this