PDA

View Full Version : PIC16F684 Program question



Nicholas
- 27th December 2006, 22:43
Below I've included the program that I have a question about. Essentially the program is meant to interrupt operation of a transmitter when a switch is turned from ON to OFF position. The switch in this case is a reed relay which turns ON and OFF using a magnet. The switch is connected to PORTA1 of my PIC however when the switch is turned OFF the interrupt does not work.
I tried to write an interrupt routine the easy way by using loops in all my subroutines to make sure that am testing the PORTA1 value at least once a second. HOwever this has not solved the issue.
Therefore mine is a two part question: the major part is how come when the voltage on PORTA1 drops from 2.8V to 0.3V is the program not executing like its supposed to. During program execution, if I ground PORTA1, the program works as supposed to.
The second part is I'd like to use Interrupts instead of adding the loops to my program and how can I make that part work. I have included the interrupt at the bottom of the code. Any assistance will be greatly appreciated.





'************************************************* ********
'* Notes : This test makes sure that the interrupt is working *
'* '************************************************* ****
; Define statements.
define OSC 20 ;every MPU used is 20mhz
DEFINE INTHAND ReedIntHandler

;Assembly Language Interrupt storage
wsave VAR BYTE $70 system ;addresses $70-$7F are the same for all banks
ssave VAR BYTE bank0 system
psave VAR BYTE bank0 system

'Port operation configurations
CMCON0=%00000111
VRCON=%00000000 'CVref turned off
OPTION_REG=%10000111 'Disable PORTA pullups, set timer0 scaler to 1:256
ANSEL=%00000000

; Program Variables
Loop VAR BYTE ;general loop counter for LED flashing

; Constant definitions
Outp CON 0
Inp CON 1

'Assign Ports to simple name
LowVoltage VAR PortA.0 'Battery low voltage detection port
ReedSwitchState VAR PORTA.1 'Reed Switch ON and OFF state line
LED VAR PORTA.2 'Turn LED ON and OFF
HoldTxON VAR PORTC.0 'Hold Tx ON when water contacts activated
Tx_Data VAR PORTC.1 'Transmit Data Line
Tx1_Enable VAR PORTC.2 'Transmit 121.5Mhz Line
Tx2_Enable VAR PORTC.3 'Tranmit 156MHz Line
MotorControl_1 VAR PORTC.5 'Activate Release Mechanism
MotorControl_2 VAR PORTC.4 'Activate Latch Mechanism

'Initialize port states
TrisA.0=Inp 'set batt low voltage detection to input
TrisA.1=Inp 'set Reedswitchstate to input
TrisA.2=Outp 'set led transmission to output
TrisC.0=Outp 'set HoldTxLine ON to output
TrisC.1=Outp set Transmit data line to output

Goto Main

Main:
low HoldTxON ; Initialize by turning clearing all the outputs
low LED
low Tx_Data

if reedswitchstate then
gosub lowvoltagecheck
else
pause 1000 ;Wait for a second to make sure the switch
high holdtxon ;is not being held HIGH
high reedswitchstate
gosub Lowvoltagecheck
endif

gosub turnontransmitter
gosub dtmftransmission
end

;************************************************* **********************
; Subroutine to check for battery voltage at the beginning and end of
; transmission flashing to signify low voltage or high voltage (to be defined)

LowVoltageCheck:
If lowVoltage = 1 then ; If the battery voltage is OK
high led
for loop = 1 to 10 ; turn on the LED for 5 seconds
pause 500
gosub checkreedswitch
next
LOw LEd
else
for loop = 1 to 10 ; If the battery voltage is low
high led ; Flash the LED 10 times
Pause 250 ; at a rate discernable from the
low led ; transmit LED flash rate
pause 250
gosub checkreedswitch
next
endif
return
'************************************************* ******************************
CheckReedSwitch:
if reedswitchstate then
return
else
gosub turnofftransmitter
endif
Return
;************************************************* ******************************
TurnOnTransmitter:
high holdtxon ; Makes sure the Tx stays on after activation
gosub checkreedswitch
return
;************************************************* ******************************
DTMFTransmission:
' DTMF transmission @ 121.5
High Tx1_enable
for loop =1 to 30
DTMFOUT TX_DATA,1000,0,[9]
gosub checkreedswitch
next
Low Tx1_enable ;Stop transmission

gosub dtmftransmission

return
;************************************************* ******************************
Blink:
for loop=0 to 20
high led
pause 100
low led
pause 100
next
return
'************************************************* ******************************
'This section is called by the reed switch interrupt

TurnOffTransmitter:

gosub blink
low holdtxon
End

'************************************************* *****************************

;*********Place Interrupt routines after here********************
asm
ReedIntHandler
; Save W, STATUS, and PCLATH registers
movwf wsave
swapf STATUS, W
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave

; debounce reed switch .01 seconds @20mhz
clrf TMR0 ; CLEAR timer 0
Debounce movlw 0xff ; move 255 into w reg
subwf TMR0,w ; subtract current count of TMR0 from w
btfss STATUS,Z ; if status is not zero yet
goto Debounce ; then continue loop
bcf INTCON,T0IF ; clear timer0 interrupt flag

clrf TMR0 ; CLEAR timer 0
Debounce2 movlw 0xff ; move 255 into w reg
subwf TMR0,w ; subtract current count of TMR0 from w
btfss STATUS,Z ; if status is not zero yet
goto Debounce2 ; then continue loop
bcf INTCON,T0IF ; clear timer0 interrupt flag

btfss _ReedSwitchState ; skip next line if the reed switch is high
goto _TurnOffTransmitter
bcf INTCON,RAIF ; reset/clear interrupt

; Restore PCLATH, STATUS, and W Registers
movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W
retfie ; return and reset GIF
endasm

skimask
- 27th December 2006, 23:05
At first glance (and it was a quick one), shouldn't the interrupt subroutines be at the beginning of the program, at the top, in Bank 0 if possible?

And...right here...

if reedswitchstate then
gosub lowvoltagecheck
else
pause 1000 ;Wait for a second to make sure the switch
high holdtxon ;is not being held HIGH
----------------------<<<<<<<<<<
high reedswitchstate
----------------------<<<<<<<<<<
gosub Lowvoltagecheck
endif

You're manually holding reedswitchstate (an input pin) with a command for an output pin. Did you actually mean to do something else here? It just doesn't look right to me.

Nicholas
- 28th December 2006, 14:30
The program was copied and pasted twice and thats why the interrupt routine is at the bottom. The interrupt program: ASM to ENDASM is right below the "GOTO Main" title in the real program.
I was trying to manually change the pin to HIGH to check the logic of the code so that part is not in the actual program. Thanks for looking into this for me. Am going to be working on it some more today and I'll post any progress I make.