Přerušení z RX po INT

Ahoj všichni.
Mám skromný dotaz na nefunkční přerušení z RX po INIT. Po resetu napájení vše jede jak má, ale pokud reset provedu tlačítkem (mám ho na jiném pinu než defaultně HW) nebo příkazem z RX, proběhne reset, tj. skok na INIT, kde se resetují všechny registry a vlastně se vše nastaví jako po připojení napájení, ale přerušení není funkční. Koukám do toho už několik dní a nejsem to schopen rozběhnout. Konkrétně je to slave jednotka s PIC16F648A.
Děkuji za odpovědi
Mikop

PS. Nejde mi sem vložit zdroják ??? Error 500

Asi sa všetko nenastavi, a druha možnosť pozri Errdatasheet. Alebo si daj na par dni pauzu :smiley:

Ahoj.
V INIT resetuji všechny registry, tj. jak pevné, tak proměné.
V simulaci to samozřejmě chodí.
Asi si dám pauzu…

Skok na INIT není RESET… Tj. musíš v INIT nastavit na default všechny použité periferie, co v programu následně používáš. Když jsem potřeboval udělat pomocí SW reset (na AVR, ale něco z toho by asi principiálně šlo využít i u PICu), jsem to řešil v podstatě dvěma různými způsoby. Buď jsem fyzicky (přes tranzistor) ovládal přímo RESET pin procesoru nebo jsem vypnul všechny přerušení, vypnul výstupy pro LEDky, nastavil WatchDog na reset procesoru v nejkratším čase a skončil v nekonečné smyčce

STOP: rjmp STOP

nebo

While(1);

Procesor AVR a jeho periferie se WatchDogem resetují stejně jako při HW resetu nebo Power On resetu, jen se nastaví jiný příznak v registru. Podle toho se pak pozná, jaký reset nastal.

Tak ten reset HW tlačítkem na pinu MCLR vyzkouším. Nyní tam mám SW pin adresace. Ale jak jsem psal výše, přepsal jsem to jen jedno přerušení při příjmu prvního byte z RX. Vypnu při příjmu přerušení v INTCON a PIE1, RCIE a dále testuji jen PIR1,RCIF, kde načtu požadované byty. Po úspešném příjmu všech bytů, zpracuji byty dle pozadavku a zapnu opět přerušení. Všechno jede v pořádku dále. Pokud jsou byte pro jiný slave nebo nevyjde CRC nebo nedojdou všechny, resetuje se příjem a jeho byty a příznaky a zase se obnoví přerušení. Vše jede v pořádku zase dál. Pokud přijde příkaz na reset (INIT), přerušení je již vypnuté a všechny byty přišli správně. Provedu skok na INIT (adresa 0000). Zde se resetují (CLRF) všechny registry vytvořené SW a zároveň všechny HW dané pro vybraný MCU.

PS. Jak připojím zdroják?

PICy neznám, takže úplně přesně Ti nejsem schopný poradit. Jen jsem nastínil, co používám já u AVR procesorů, pokud by PIC takovou možnost měl.

Vložení zdrojáku:

  1. Vezmeš soubor se zdrojákem a přetahneš ho do okénka, kam píšeš …
    main.asm (6.3 kB)

  2. zkomprimuješ projekt a přetahneš sem ten zip :
    main.zip (1.6 kB) - no dobře - tohle moc použitelné nebude, protože 32kB ZIP to nezvládlo nahrát - jen zazipovanou kopii toho “main.asm”. Jak velký ZIP může být jsem nezkoušel.

  • zkopíruješ zdroják (CTRL-C)
  • klikneš na znak </>
  • Napíše Ti to 3 speciální horní čárky, “zde napište nebo vložte kód” a tři speciální horní čárky (nejsou to apostrofy - je to ten znak, co má klávesnice před 1 pod ESC)
  • Tady stiskneš CTRL-V
;
; Test_CTC_Timeru.asm
;
; Created: 13.6.2018 17:30:27
; Author : uzivatel
;


;==============================================================================
; Init_file AtMega48(88,168,328)A
; XX.XX.XXXX
; Popis programu
;==============================================================================
#message __DATE__ ,__TIME__
#message __FILE__

;#include <m48Adef.inc>
;#include <m88Adef.inc>
;#include <m168Adef.inc>
#include <m328def.inc>
#include <makra.inc>

;------------------------------------------------------------------------------
; Definice registrových proměnných

.def Temp=R16				; Pomocná proměnná

;------------------------------------------------------------------------------
; Tabulka skoků

.org 0
#if defined(_M168ADEF_INC_) || defined(_M168DEF_INC_) || defined(_M168PDEF_INC_) || defined(_M168PADEF_INC_) || \
	defined(_M328ADEF_INC_) || defined(_M328DEF_INC_) || defined(_M328PDEF_INC_) || defined(_M328PADEF_INC_)
		jmp RESET 			; External Pin, Power-on Reset, Brown-out Reset and Watchdog System Reset
		jmp INT0_INT		; External Interrupt Request 0
		jmp INT1_INT		; External Interrupt Request 1
		jmp PCINT0_INT		; Pin Change Interrupt Request 0
		jmp PCINT1_INT		; Pin Change Interrupt Request 1
		jmp PCINT2_INT		; Pin Change Interrupt Request 2
		jmp WDT 			; Watchdog Time-out Interrupt
		jmp TIM2_COMPA 	; Timer/Counter2 Compare Match A
		jmp TIM2_COMPB 	; Timer/Counter2 Compare Match B
		jmp TIM2_OVF 	; Timer/Counter2 Overflow
		jmp TIM1_CAPT 	; Timer/Counter1 Capture Event
		jmp TIM1_COMPA 	; Timer/Counter1 Compare Match A
		jmp TIM1_COMPB 	; Timer/Coutner1 Compare Match B
		jmp TIM1_OVF 	; Timer/Counter1 Overflow
		jmp TIM0_COMPA 	; Timer/Counter0 Compare Match A
		jmp TIM0_COMPB 	; Timer/Counter0 Compare Match B
		jmp TIM0_OVF 	; Timer/Counter0 Overflow
		jmp SPI_STC 		; SPI Serial Transfer Complete
		jmp USART_RXC 		; USART Rx Complete
		jmp USART_UDRE 	; USART, Data Register Empty
		jmp USART_TXC 		; USART, Tx Complete
		jmp ADC_INT 		; ADC Conversion Complete
		jmp EE_READY 		; EEPROM Ready
		jmp ANA_COMP ; Analog Comparator Handler
		jmp TWI ; 2-wire Serial Interface Handler
		jmp SPM_RDY ; Store Program Memory Ready Handler
#else
		rjmp RESET 			; External Pin, Power-on Reset, Brown-out Reset and Watchdog System Reset
		rjmp INT0_INT		; External Interrupt Request 0
		rjmp INT1_INT		; External Interrupt Request 1
		rjmp PCINT0_INT		; Pin Change Interrupt Request 0
		rjmp PCINT1_INT		; Pin Change Interrupt Request 1
		rjmp PCINT2_INT		; Pin Change Interrupt Request 2
		rjmp WDT 			; Watchdog Time-out Interrupt
		rjmp TIM2_COMPA 	; Timer/Counter2 Compare Match A
		rjmp TIM2_COMPB 	; Timer/Counter2 Compare Match B
		rjmp TIM2_OVF 	; Timer/Counter2 Overflow
		rjmp TIM1_CAPT 	; Timer/Counter1 Capture Event
		rjmp TIM1_COMPA 	; Timer/Counter1 Compare Match A
		rjmp TIM1_COMPB 	; Timer/Coutner1 Compare Match B
		rjmp TIM1_OVF 	; Timer/Counter1 Overflow
		rjmp TIM0_COMPA 	; Timer/Counter0 Compare Match A
		rjmp TIM0_COMPB 	; Timer/Counter0 Compare Match B
		rjmp TIM0_OVF 	; Timer/Counter0 Overflow
		rjmp SPI_STC 		; SPI Serial Transfer Complete
		rjmp USART_RXC 		; USART Rx Complete
		rjmp USART_UDRE 	; USART, Data Register Empty
		rjmp USART_TXC 		; USART, Tx Complete
		rjmp ADC_INT 		; ADC Conversion Complete
		rjmp EE_READY 		; EEPROM Ready
		rjmp ANA_COMP ; Analog Comparator Handler
		rjmp TWI ; 2-wire Serial Interface Handler
		rjmp SPM_RDY ; Store Program Memory Ready Handler
#endif
;
;------------------------------------------------------------------------------
; Rutiny obsluhy přerušení

INT0_INT:             ; IRQ0 Handler
		reti
INT1_INT:             ; IRQ1 Handler
		reti
PCINT0_INT:           ; PCINT0 Handler
		reti
PCINT1_INT:           ; PCINT1 Handler
		reti
PCINT2_INT:           ; PCINT2 Handler
		reti
WDT:                  ; Watchdog Timer Handler
		reti
TIM2_COMPA:           ; Timer2 Compare A Handler
		reti
TIM2_COMPB:           ; Timer2 Compare B Handler
		reti
TIM2_OVF:             ; Timer2 Overflow Handler
		reti
TIM1_CAPT:            ; Timer1 Capture Handler
		reti
TIM1_COMPA:           ; Timer1 Compare A Handler
		reti
TIM1_COMPB:           ; Timer1 Compare B Handler
		reti
TIM1_OVF:             ; Timer1 Overflow Handler
		reti
TIM0_COMPA:           ; Timer0 Compare A Handler
		reti
TIM0_COMPB:           ; Timer0 Compare B Handler
		reti
TIM0_OVF:             ; Timer0 Overflow Handler
		reti
SPI_STC:              ; SPI Transfer Complete Handler
		reti
USART_RXC:            ; USART, RX Complete Handler
		reti
USART_UDRE:           ; USART, UDR Empty Handler
		reti
USART_TXC:            ; USART, TX Complete Handler
		reti
ADC_INT:              ; ADC Conversion Complete Handler
		reti
EE_READY:               ; EEPROM Ready Handler
		reti
ANA_COMP:             ; Analog Comparator Handler
		reti
TWI:                  ; 2-wire Serial Interface Handler
		reti
SPM_RDY:              ; Store Program Memory Ready Handler
		reti
;

;------------------------------------------------------------------------------
; Hlavní program - inicializace

RESET:  ldi temp,high(RAMEND); Main program start
        out SPH,temp ; Set Stack Pointer to top of RAM
        ldi temp,low(RAMEND)
        out SPL,temp

        ldi XH, high(SRAM_SIZE)
        ldi XL, low(SRAM_SIZE)
        ldi YH, high(SRAM_START)
        ldi YL, low(SRAM_START)
        clr temp
Init_RAM:
        st Y+, temp
        sbiw XL, 1
        brne Init_RAM

		clr r0
	    clr r1
		movw r2:r3, r0:r1
		movw r4:r5, r0:r1
		movw r6:r7, r0:r1
		movw r8:r9, r0:r1
		movw r10:r11, r0:r1
		movw r12:r13, r0:r1
		movw r14:r15, r0:r1
		movw r16:r17, r0:r1
		movw r18:r19, r0:r1
		movw r20:r21, r0:r1
		movw r22:r23, r0:r1
		movw r24:r25, r0:r1
		movw r26:r27, r0:r1
		movw r28:r29, r0:r1
		movw r30:r31, r0:r1

		stsi OCR1BH, high(0x0010)
		stsi OCR1BL, low(0x0010)
		stsi OCR1AH, high(0x0040)
		stsi OCR1AL, low(0x0040)
		stsi ICR1H, high(0x0110)
		stsi ICR1L, low(0x0110)
		stsi TIMSK1, (1<<ICIE1)|(1<<OCIE1A)|(1<<OCIE1B)|(1<<TOV1)
		stsi TCCR1C, 0
		stsi TCCR1A, 0
		stsi TCCR1B, (1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10)

		sei


;------------------------------------------------------------------------------
; Hlavní program

Hlavni_Smycka:

		rjmp Hlavni_Smycka

`

500 error

` jsem taky získal, když jsem se snažil můj předchozí příspěvek ještě upravit. Řekl bych, že jsou stránky nějaké nemocné … :face_with_thermometer: :thinking:

Tak jsem nastavil v programu zpět MCLR pin na reset a když ho přizemním, tak proběhne reset správně. Budu zkoušet…

Skúšal si urobiť nejaký podprogram v ktorom postupne povypinas prerušenia a nepotrebné veci az nasledne po nejakej dobe prevedies posledný skok na reset. Sisi istý ze nevypinas aj niečo čo nemáš? Eer datashete si pozrel?

Proč to nevyřešíš přes WD?

Díval jsem se do toho Errata strana 3, ale nejsem z toho moc moudrý. UART proste po INIT zapnu (jak TX, tak RX) a zapnu přerušení pouze na RX.
WD jsem zatím nezapínal. Jediné přerušení je pouze pro příjem. Časování je z neefektivních čekacích smyček, protože mám v programu na všechno dost času.
Stále mi nejde přetáhnout či jinak vložit ten zdroják. Má cca 23kb a nejde mi vložit ani jako TXT. Tak alespoň nějaké kousky …
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CBLOCK 0x20		; blok promenych 
TMP0			; temp casovacu 
TMP1			; temp casovacu
TMP2			; temp casovacu
TMP3			; temp casovacu
TMP5			; priznaky
CAS1_BYTE		; max cas prijmu dalsiho byte
CAS2_BYTE		; max cas prijmu dalsiho byte
TMP10			; stav prijmu byte 
ADRESA			; adresa modulu po nacteni pinu
CISLO			; pomocne cislo
CAS1			; pomocny pro blik a adresy
CAS3
CAS4			; cas drzeni stavu byte_2 po stisku tlacitka
CAS5			; cas drzeni stavu byte_2 po stisku tlacitka
BYTE_START
BYTE_ADRESA
BYTE_1
BYTE_2
BYTE_CRC
CRC
BYTE_TLACITKA
CAS5_EE
ENDC

;---------------
CBLOCK 0x70 ; blok promenych pro vsechny banky
W_SAVE ; temp ulozeni pri preruseni
STA_SAVE ; temp ulozeni pri preruseni
PCL_SAVE ; temp ulozeni pri preruseni
FSR_SAVE ; temp ulozeni pri preruseni
ENDC
;*************************************************************
;**************************************************************

; DEFINICE PRIZNAKU

#define P_BYTE0 TMP10,0 ; priznak prijmu BYTE0
#define P_BYTE_START TMP10,1 ; priznak prijmu BYTE1 = START_BYTE
#define P_BYTE_ADRESA TMP10,2 ; priznak prijmu BYTE2 = ADRESA
#define P_BYTE_1 TMP10,3 ; priznak prijmu BYTE3 = ADRESA OD KOHO
#define P_BYTE_2 TMP10,4 ; priznak prijmu BYTE4 = HODNOTA
#define P_BYTE_CRC TMP10,5 ; priznak prijmu BYTE7 = CRC
#define BLIK_3 TMP10,6 ; priznak pro blik z dotazu RX

#define STISKNUTO TMP5,0 ; priznak, ze bylo stisknuto tlacitko

;*************************************************************

; DEFINICE PINU

#define SMER PORTB,0 ; vystup SMER pro RS485
#define RX PORTB,1 ; vstup RX data pro RS485
#define TX PORTB,2 ; vystup TX data pro RS485
#define LED1 PORTB,3 ; vystup LED1, beh programu a stavy
#define TL1 PORTB,4 ; vstup TL1
#define TL2 PORTB,5 ; vstup TL2
#define TL3 PORTB,6 ; vstup TL3
#define TL4 PORTB,7 ; vstup TL4

#define TLRST PORTA,0 ; vstup TLRST
#define LED2 PORTA,1 ; vystup LED2, stavova pokoj
#define ADR1 PORTA,2 ; vstup ADRESA1
#define ADR2 PORTA,3 ; vstup ADRESA2
#define ADR4 PORTA,4 ; vstup ADRESA4
#define ADR8 PORTA,5 ; vstup ADRESA8
;#define X1 PORTA,6 ; vstup X-tal
;#define X2 PORTA,7 ; vstup X-tal

;*************************************************************

; org 0x2007 ; adresa konfigurace PIC16F628A
LIST P=16F648A;R=DEC
#include “P16F648A.INC” ; Include header file

; Pro 4MHz krystal
__CONFIG _CP_OFF & _PWRTE_ON & _BODEN_ON & _WDT_OFF & _XT_OSC & _LVP_OFF & _MCLRE_OFF

;*************************************************************
ORG 0x0000 ; zacatek programu
GOTO INIT ; skok na pocatecni inicializaci

ORG		0x0004
GOTO	PRERUS

;*************************************************************
; INICIALIZACE
;*************************************************************
INIT

; ------------------------
BSF STATUS,RP0 ; nastaven BANKY 1

MOVLW	b'11111101'	; portA vstupy a vystupy
MOVWF	TRISA
MOVLW	b'11110010'	; portB vstupy a vystupy
MOVWF	TRISB
MOVLW	b'10000111'	; PULL-UPy ON, 1:256
MOVWF	OPTION_REG
MOVLW	b'00000000'	; preruseni OFF
MOVWF	INTCON
MOVLW	b'00001000'	; osc. 4 MHz, 
MOVWF	PCON

BCF	STATUS,RP0	; Bank 0

MOVLW	0x07		; vypni komparatory
MOVWF	CMCON

CLRF	PORTA
CLRF	PORTB	

CLRF	PCLATH
CLRF	FSR
CLRF	STATUS
CLRF	FSR

CLRF	W_SAVE			; temp ulozeni pri preruseni
CLRF	STA_SAVE		; temp ulozeni pri preruseni
CLRF	PCL_SAVE		; temp ulozeni pri preruseni
CLRF	FSR_SAVE		; temp ulozeni pri preruseni
CLRF	TMP0  			; casovaci smycky
CLRF	TMP1			; casovaci smycky
CLRF	TMP2			; casovaci smycky 
CLRF	TMP3			; casovaci smycky 
CLRF	TMP5			; priznaky
CLRF	CAS1_BYTE		; max cas prijmu dalsiho byte
CLRF	CAS2_BYTE
CLRF	TMP10			; stav prijmu byte 
CLRF	ADRESA			; adresa modulu po nacteni pinu
CLRF	CISLO			; pomocne cislo
CLRF	CAS1			; pomocny pro blik adresy
CLRF	CAS3
CLRF	CAS4			; 20 ms x 256 x 12 = 61,44 sec
CLRF	CAS5			; 

; CLRF POCET_BYTE
CLRF BYTE_START
CLRF BYTE_ADRESA
CLRF BYTE_1
CLRF BYTE_2
CLRF BYTE_CRC
CLRF CRC
CLRF BYTE_TLACITKA
CLRF CAS5_EE

CALL	NACTI_CAS5_EE
MOVF	CAS5_EE,W
MOVWF	CAS5

CALL	ADRESA_MODULU	; nacti adresu na jumperech 

MOVF	ADRESA,W
MOVWF	CAS1

MOVLW	.255			; nastav cas pro prijem
MOVWF	CAS1_BYTE		; 9us x 256 = 1,529	ms
MOVLW	.10				; nastav cas pro prijem
MOVWF	CAS2_BYTE		; 10 x 1,529 = 15,373ms

CALL	CEK1S

CLRW
XORWF	ADRESA,W
BTFSC	STATUS,Z
GOTO	INIT_0		; adresa 0

BLIKEJ_ADRESU

BSF	LED1		; zablika adresu
BSF	LED2
CALL	CEK500MS
BCF	LED1
BCF	LED2
CALL	CEK500MS

DECFSZ	CAS1,F
GOTO	BLIKEJ_ADRESU
GOTO	INIT_1	

INIT_0 ; adresa 0

BSF	LED1
BSF	LED2
CALL	CEK2S
BCF	LED1
BCF	LED2

INIT_1

CALL	NASTAV_CAS1

BSF	STATUS,RP0	; nastaven  BANKY 1

; BCF TXSTA,BRGH ; BRGH=0
MOVLW b’00100010’ ; povoleni vysilani
MOVWF TXSTA ; vysilani povoleno
; MOVLW .12 ; 4 800 BPS PRI 4MHZ XTAL A BRGH=0
MOVLW .25 ; 2 400 BPS PRI 4MHZ XTAL A BRGH=0
; MOVLW .51 ; 1 200 BPS PRI 4MHZ XTAL A BRGH=0
; MOVLW .103 ; 600 BPS PRI 4MHZ XTAL A BRGH=0
; MOVLW .207 ; 300 BPS PRI 4MHZ XTAL A BRGH=1
MOVWF SPBRG ; vloz hodnotu rychlosti do BRGH
BCF STATUS,RP0 ; Bank 0

MOVLW	b'10010000'	; povoleni USART a asynchroniho rezimu ,
MOVWF	RCSTA		; 8bit, asynchron  mod

BSF	STATUS,RP0	; banka registru 1
MOVLW	b'00100000'
MOVWF	PIE1		; zapni preruseni z RX
BCF	STATUS,RP0	; banka registru 0

CLRF	TXREG		; vynuluj vysilaci registr
CLRF	RCREG		; vynuluj prijimaci registr

MOVLW	b'00010000'
MOVWF	PIR1		; vynuluj priznak prijmu

MOVLW	b'11000000'	; zapni globalni preruseni a z periferii
MOVWF	INTCON

GOTO	MAIN		; skoc na MAIN

;********************************************************************

PRERUS ; prerus, uloz registry

BCF	INTCON,GIE	; vypni globalni preruseni
BCF	INTCON,PEIE	; vypni preruseni z periferii
BSF	STATUS,RP0	; nastaveni BANKY 1
BCF	PIE1,RCIE	; vypni preruseni z RX
BCF	STATUS,RP0	; nastaven  BANKY 0 

MOVWF	W_SAVE		; zalohuj registry
MOVF	STATUS,W
CLRF	STATUS
MOVWF	STA_SAVE
MOVF	PCLATH,W
MOVWF	PCL_SAVE
MOVF	FSR,W
MOVWF	FSR_SAVE
BTFSS	PIR1,RCIF	; over, zda byl prijem
GOTO	KONEC_PRERUSENI	 ; nebyl

GOTO	PRIJEM

; ********************************************************************

KONEC_PRERUSENI ; konec preruseni, obnoveni registru

CLRF	TMP10
CLRF	BYTE_START
CLRF	BYTE_ADRESA
CLRF	BYTE_1
CLRF	BYTE_2
CLRF	BYTE_CRC
CLRF	STATUS
MOVF	FSR_SAVE,W
MOVWF	FSR
MOVF	PCL_SAVE,W
MOVWF	PCLATH
MOVF	STA_SAVE,W
MOVWF	STATUS
SWAPF	W_SAVE,F
SWAPF	W_SAVE,W

MOVLW	b'10010000'	; povoleni USART a asynchroniho rezimu ,
MOVWF	RCSTA		; 8bit, asynchron  mod
BSF	STATUS,RP0	; banka registru 1
MOVLW	b'00100000'
MOVWF	PIE1		; zapni preruseni z RX
BCF	STATUS,RP0	; banka registru 0
CLRF	RCREG		; vynuluj prijimaci registr
CLRF	TXREG
MOVLW	b'00010000'
MOVWF	PIR1		; vynuluj priznak prijmu

MOVLW	b'11000000'	; zapni globalni preruseni a z periferii
MOVWF	INTCON

RETFIE

;*************************************************************

Každopádně poslední stav je, že pokud se např. pošle rychle za sebou několik sekvencí těch 5 byte (posílám je z Herkulesu), tak se zřejmě nevrátí správně z přerušení a do HW resetu prostě přerušení na příjem nejede. Pokud však pošlu sekvenci za sebou se 100ms (tak to mám nastaveno), je to v pořádku. V příjmu se nastaví časovač na cca 15ms a pokud nedojdou správně všechny byte, tak se to zahodí a čeká se dál.