Pagina 1 di 3

Accendere LED con interrupt

MessaggioInviato: 12 feb 2014, 21:56
da rudj
ciao, sto seguendo un corso di PIC e così per esercizio volevo far accendere 4 led collegati alle porte RA0,RA1,RA2 e RA3 dopo la pressione di un interruttore e farli spegnere con una seconda pressione usando gli interrupt, provando con il debugger va tutto bene fino al momento di mandare i segnali di ALTO allle 4 porte RA, non si attivano, gli interrupt funzionano ma la parte "accendi" di questo codice non funziona :

Codice: Seleziona tutto
PROCESSOR 16F84
RADIX DEC
INCLUDE "P16F84.INC"
ERRORLEVEL -302
__CONFIG 0x3FF1

LED0 EQU 0
LED1 EQU 1
LED2 EQU 2
LED3 EQU 3
SWITCH EQU 0

CBLOCK 0x0c
Count:2
ENDC

ORG 0x00

goto start

ORG 0x04

btfsc INTCON,RBIF
goto tastoPremuto

start

bsf STATUS,RP0

movlw B'00011111'
movwf TRISA

movlw B'11111110'
movwf TRISB

bcf STATUS,RP0

movlw B'00000000'
movwf PORTA

movlw B'10001000'
movwf INTCON

mainloop

call Delay
bsf Count,0
goto mainloop

tastoPremuto

bcf STATUS,RP0
movf PORTB
btfss PORTA,0
goto accendi

btfsc PORTA,0
goto spegni



accendi
bsf PORTA,0 ;arriva fin qui ma non attiva le porte
bsf PORTA,1
bsf PORTA,2
bsf PORTA,3
goto mainloop

spegni
movlw B'00000000'
movwf PORTA
goto mainloop

movlw B'10001000'
movwf INTCON

goto mainloop

Delay
clrf Count
clrf Count+1
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
return

END


dove sbaglio?

Re: Accendere LED con interrupt

MessaggioInviato: 12 feb 2014, 22:14
da Candy
Intanto mi sembra che manchino un poche di cose nella gestione degli interrupt: dal salvataggio e ripristino dei registri comuni, fino all'ultima istruzione che deve essere una "RETFIE". Come minimo, senza poi considerare altri aspetti. La chiamata dell'interrupt viene fatta con una istruzione di CALL e, mi sembra di capire che quel codice sia facile all'overflow dello stack pointer.

Hai già provato a vedere con un oscilloscopio cosa fanno le uscite? Sei certo che il tutto non finisca in loop e faccia ciclicamente accendi/spegni?
Per usare gli interrupt devi essere certo di non avere rimbalzi nel modo più assoluto. Come hai eliminato i rimbalzi del segnale d'ingresso?
L'interrupt di PORTB deve essere resettato a livello software? Hai controllato?

In tutta onesta quel codice così scritto è illeggibile, seppur semplice.
Se ti interesse che altri collaborino e ti aiutino, prima di tutto, bisogna dare leggibilità al codice.

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 12:03
da rudj
scusa, hai ragione, era illeggibile :mrgreen: .. ora ho modificato un po' il codice per renderlo più leggibile e ho rimediato ad alcuni errori, ho anche aggiunto retfie ma il problema rimane, PORTA rimane a 0x00.

Codice: Seleziona tutto
PROCESSOR 16F84
RADIX DEC
INCLUDE "P16F84.INC"
ERRORLEVEL -302
__CONFIG 0x3FF1

LED0 EQU 0
LED1 EQU 1
LED2 EQU 2
LED3 EQU 3
SWITCH EQU 0

CBLOCK 0x0c ;dichiarazione variabili
Count:2
ENDC

ORG 0x00
goto start

ORG 0x04 ;interrupt handler
btfsc INTCON,RBIF
goto tastoPremuto

start
bsf STATUS,RP0
movlw B'00011111' ;imposto gli I/O
movwf TRISA
movlw B'11111110'
movwf TRISB

bcf STATUS,RP0  ;spengo i led
movlw B'00000000'
movwf PORTA

movlw B'10001000' ;interrupt enable
movwf INTCON

mainloop ;attesa dell'interrupt

call Delay
bsf Count,0
goto mainloop

tastoPremuto

bcf STATUS,RP0
movf PORTB
btfss PORTA,LED0 ;controlla se i led sono accesi
goto accendi ;se sono spenti li accende...

btfsc PORTA,0
goto spegni ;...altrimenti li spegne



accendi
bsf PORTA,LED0
bsf PORTA,LED1
bsf PORTA,LED2
bsf PORTA,LED3
movlw B'10001000' ;ripristino interrupt
movwf INTCON
retfie

spegni
movlw B'00000000'
movwf PORTA
movlw B'10001000' ;ripristino interrupt
movwf INTCON
retfie

Delay ; delay software
clrf Count
clrf Count+1
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
return

END


Hai già provato a vedere con un oscilloscopio cosa fanno le uscite? Sei certo che il tutto non finisca in loop e faccia ciclicamente accendi/spegni?

devo ancora passarlo nel PIC, sto ancora provando con il simulatore/debugger, controllo PORTA negli watch e vedo che non si muove...
L'interrupt di PORTB deve essere resettato a livello software? Hai controllato?


sì, penso di averlo resettato qui:
Codice: Seleziona tutto
movlw B'10001000' ;ripristino interrupt
movwf INTCON

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 12:20
da Paolino
Per avere le porte come output, devi impostare il valore dei bit a 0 e non a 1:

Codice: Seleziona tutto
movlw B'00000000' ;imposto gli I/O
movwf TRISA


Ciao.

Paolo.

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 12:36
da rudj
ops, devo aver fatto un po' di confusione quando ho spostato i led da una linea all'altra.. grazie, ora funziona, resta solo un problema.. perché quando collego l'alimentazione capita che trovo i led già accesi? ho anche aggiunto il comando clrf PORTA, va meglio ma ogni tanto accendo e li trovo accesi... :(

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 12:57
da Paolino
Lavori con breadboard?

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 12:58
da Paolino
Oppure hai un problema con gli interrupt che si innescano per qualche motivo.
Controlla bene le connessioni.

Potresti mostrarci lo schema impiegato? Usa FIDOCADJ per disegnare.

Ciao.

Paolo.

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 13:18
da rudj
sì, con breadboard, questo è solo un esercizio per imparare a programmare i PIC, ma mi interessa sapere dove sbaglio per creare un programma migliore fin da subito quando inizierò il progetto vero (un antifurto), sarebbe brutto che appena accendo il circuito suona l'allarme di casa :mrgreen:
ecco lo schema:

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 13:34
da Candy
E cos'è questo? Un saggio per una futura opera da esporre in qualche museo di arte moderna?

Re: Accendere LED con interrupt

MessaggioInviato: 13 feb 2014, 13:48
da rudj


scusate ero un po' di fretta :D

R1-R2=470
R3-R4=10k
I=interruttore
Q=4Mhz
C1-C2=22pF