PDA

View Full Version : RB0 interrupt and toggle issue



Macgman2000
- 29th April 2009, 04:31
Hello,
I am running a hardware interrupt on RB0 (rising edge trigger). I use RB0 to interrupt the micro which is (I assume) sitting at a DEBUGIN waiting for serial data.

The inline assembly code (as listed in the datasheets 16F877A) to take care of house keeping going in and coming out of the interrupt is present. During an interrupt I jump to a "call routine" which jumps out and runs some code in Picbasic, then returns. The problem I have is in this routine called from within the interrupt is supposed to toggle port bits (1 through 8, bitwise) written in Picbasic. The problem is it does not toggle. It seems to only go HIGH but will not go LOW.

Anyone run into this issue where toggle does not work? I will post the code tomorrow for reference...I have been trying to figure this out for over 1.5 days now.

Thanks!
Nick

Archangel
- 29th April 2009, 07:11
Hello,
I am running a hardware interrupt on RB0 (rising edge trigger). I use RB0 to interrupt the micro which is (I assume) sitting at a DEBUGIN waiting for serial data.

The inline assembly code (as listed in the datasheets 16F877A) to take care of house keeping going in and coming out of the interrupt is present. During an interrupt I jump to a "call routine" which jumps out and runs some code in Picbasic, then returns. The problem I have is in this routine called from within the interrupt is supposed to toggle port bits (1 through 8, bitwise) written in Picbasic. The problem is it does not toggle. It seems to only go HIGH but will not go LOW.

Anyone run into this issue where toggle does not work? I will post the code tomorrow for reference...I have been trying to figure this out for over 1.5 days now.

Thanks!
Nick
Hi Nick, yeah I have had toggle not work and never figured out why. BTW Call as I understand it is for use in ASM and gosub for PBP. When you post your code we can all chew on it a while, see what we can learn. I bet the BIG GUNS here CAN answer this problem.

Macgman2000
- 29th April 2009, 15:38
OK...here it is. The stuff in the mainloop is waiting for serial data to update the port bits which each control the activation of a relay (8 relays). The interrupt port RB0 is tied to 8 button inputs, the idea is to push any of the 8 buttons and interrupt out of the DEBUGIN to decode key presses. It goes through the interrupt, loads payload in the interrupt (it works). Where it is not working is in the CALL outside of the interrupt. It does NOT toggle the port bits. I saw something strange that I could not replicate, when it did toggle it undid the logic of any bits that were set high. Anyway...here it is, I would appreciate the help!

Nick


INCLUDE "Modedefs.Bas"
@ device HS_OSC, LVP_OFF, WDT_OFF
; @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF

DEFINE OSC 20



DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
DEFINE DEBUG_BAUD 2400 ' Set bit rate
DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted

DEFINE INTHAND myint ' Setup interrupt handler button presses




; initialize Interrupts
OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
INTCON = %10010000 ; Enable INTE RB0 interrupt $90


;set ports to input
TRISD = %11111111 ; 8 button press inputs + RB0 interrupt for all off


;set ports to output
TRISA = %00000000 ; set port A to outputs for relays
TRISE = %00000000 ; set port E to outputs for relays

;set port initializations
PORTA = %00000000
PORTE = %00000000

' Configure internal registers

wsave VAR BYTE $70 system ' Saves W
ssave VAR BYTE bank0 system ' Saves STATUS
psave VAR BYTE bank0 system ' Saves PCLATH
fsave VAR BYTE bank0 system ' Saves FSR

payload VAR byte bank0 system ' data location for selecting relays
payload1 var byte bank0 system ' previous good data
chksum var byte bank0 system ' check sum calculated at the TX side and sent over RF link


payload = 0



goto mainloop


asm

; Save W, STATUS and PCLATH registers, if not done previously
myint
; bsf INTCON, 1
movwf wsave ; these commands are necessary to preserve registers to prevent
swapf STATUS, W ; corruption
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave


movf portd, w ; 8 momentary button press value
movwf payload ; move portd value into payload to handoff to update_keys2
call _keys2

; Restore saved registers
bsf porte,0
movf psave, W ; reload system register to previous values before interrupt was called
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W
retfie ; Return from interrupt

endasm




keys2: ; called by interrupt to update relay
if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif

return


mainloop:
INTCON = %10010000 ; Enable INTE RB0 interrupt $90
; receive data packets and check sum, throwing out sync byte (255)
debugin [wait (255),payload,chksum]
if chksum != payload then ; verify good packets by comparing check sums
goto mainloop ; check sum does not match transmitted data
endif

update_keys:

if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif

goto mainloop

Archangel
- 29th April 2009, 19:31
Hi Macgman2000,
I didn't analyze your code too closely, because frankly I am not smart enough to understand all the assembly code, and it compiled with too many errors here for me to sort out, so I did the next best thing, I tossed out the assembly interrupts and installed Darrel's DT_INTS, and recompiled. Please try it as you have the breadboard already set up. MPASM Required.


'http://www.picbasic.co.uk/forum/showthread.php?p=73542#post73542
'Macgman2000.bas
'************************************************* *******************







INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

INCLUDE "Modedefs.Bas"
;@ device HS_OSC, LVP_OFF, WDT_OFF
; @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF
@ __config _HS_OSC & _BODEN_OFF & _PWRTE_ON & _WDT_ON
DEFINE OSC 20



DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
DEFINE DEBUG_BAUD 2400 ' Set bit rate
DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted

;DEFINE INTHAND myint ' Setup interrupt handler button presses

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _keys2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


; initialize Interrupts
OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
INTCON = %10010000 ; Enable INTE RB0 interrupt $90


;set ports to input
TRISD = %11111111 ; 8 button press inputs + RB0 interrupt for all off


;set ports to output
TRISA = %00000000 ; set port A to outputs for relays
TRISE = %00000000 ; set port E to outputs for relays

;set port initializations
PORTA = %00000000
PORTE = %00000000

' Configure internal registers



payload VAR byte bank0 system ' data location for selecting relays
payload1 var byte bank0 system ' previous good data
chksum var byte bank0 system ' check sum calculated at the TX side and sent over RF link


payload = 0



goto mainloop





keys2: ; called by interrupt to update relay
if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif

@ INT_RETURN



mainloop:
INTCON = %10010000 ; Enable INTE RB0 interrupt $90
; receive data packets and check sum, throwing out sync byte (255)
debugin [wait (255),payload,chksum]
if chksum != payload then ; verify good packets by comparing check sums
goto mainloop ; check sum does not match transmitted data
endif

update_keys:

if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif

goto mainloop

Macgman2000
- 29th April 2009, 21:33
Hello Joe,

Is it possible to send me the include files?

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

Also, Why is MPASM needed if the files are .bas ? I haven't used this interrupt module before. I need a tad bit hand holding through this. I appreciate your help!!!!!!

Nick

Archangel
- 29th April 2009, 22:55
http://darreltaylor.com/DT_INTS-14/intro.html
http://darreltaylor.com/DT_INTS-14/downloads.htm
http://darreltaylor.com/DT_INTS-18/home.html

Darrel's include files Require MPASM to work. Darrel Requires you not to copy paste the code into your code, rather use them as include files as I did. They exist in versions for the 14 bit core and for the 18F series. He has generously made these available to us, and I am grateful to him. THANKS DARREL !



Also, Why is MPASM needed if the files are .bas ?
Nick
If you need help switching assemblers let me know, it's pretty easy.

EDIT:
Nick I think I set your code up with the wrong interrupt, I set it up as RBC_INT and that would be for on change interrupt whereas you want interrupt on portB.0 which should be INT_INT in the assy statement for INT_Handler .

Macgman2000
- 29th April 2009, 23:18
I am getting a lot of errors. I unzipped the files in the PBP directory (same as PBP.exe). It shows up in the compiler includes column on the left side of microcode. I am using compiler 2.47.

Errors in microcode studio:

1). _config
2). local directive use only in macro
3). undefinded symbol 'iflagreg'
4). numeric constant or symbol name expected
5). ')' expected
6). too many errors

I am clueless as to why it is doing that. The include files from Darrel do not need any special modifications or set up....right?

Nick

Darrel Taylor
- 29th April 2009, 23:30
Like Joe said ... you must be using MPASM as the assembler.
<br>

Macgman2000
- 30th April 2009, 01:19
Switched over to MPASM....now I have these errors:

@ _config _HS_OSC & _BODEN_OFF & _PWRTE_ON & _WDT_ON

For whatever reason it does not like the syntax of the above. Once I comment them out and compile, it has no errors. Putting them in produces errors specific to the items after the @. Is this the correct syntax?

Nick

Archangel
- 30th April 2009, 01:43
Switched over to MPASM....now I have these errors:

@ _config _HS_OSC & _BODEN_OFF & _PWRTE_ON & _WDT_ON

For whatever reason it does not like the syntax of the above. Once I comment them out and compile, it has no errors. Putting them in produces errors specific to the items after the @. Is this the correct syntax?

Nick2 things, The config statement requires TWO UNDERSCORES __ without spaces between them,Like this @ __config and you will need to open the 16F877A.inc file (if that is the chip you are using), in the PBP Root directory and put a semicolon ; just prior to the MPASM DEFAULT CONFIG STATEMENT. This will cause PBP to ignore it as a comment, because your program can only use the one.

Macgman2000
- 30th April 2009, 16:18
OK it compiled but still does not work. Meaning....A key press yeilds no toggling of ports. It gets to the interrupt (I placed a porta.0 = 1 flag) so I know that part is working just like the PBP interrupt handler when any key is pressed. The problem is nothing toggles or the payload value of the keypress is corrupted. I inserted pause 1000 for debounce but that didn't work either. It seems to be blasting right by the conditional statements and exiting the interrupt.

Man this is frustrating!

Archangel
- 1st May 2009, 01:01
OK it compiled but still does not work. Meaning....A key press yeilds no toggling of ports. It gets to the interrupt (I placed a porta.0 = 1 flag) so I know that part is working just like the PBP interrupt handler when any key is pressed. The problem is nothing toggles or the payload value of the keypress is corrupted. I inserted pause 1000 for debounce but that didn't work either. It seems to be blasting right by the conditional statements and exiting the interrupt.

Man this is frustrating!As I said before I have had toggle not work. Perhaps you can use a bitwise ^ to flip the bit. Try looking at the variables contents using a serout or debugout and see if it contains the value it is supposed to have. I will look at this tonight after I come home from dinner.

mister_e
- 1st May 2009, 01:14
Toggle doesn't work because you have'nt disable the ADCs.

Archangel
- 1st May 2009, 01:24
Toggle doesn't work because you have'nt disable the ADCs.
Hahaha I just stumbled across one of Melanies posts mentioning that, http://www.picbasic.co.uk/forum/showthread.php?t=977
This chip has CCP module on portC. Good call Steve.

Macgman2000
- 1st May 2009, 02:13
It shouldn't affect portE which is where 2 of my relay pins are. I will try it anyway and let you know. Thanks for the suggestion!

Nick

Ioannis
- 1st May 2009, 12:12
Where is the PIC populated? Is it on any Microchip board?

Ioannis

mister_e
- 1st May 2009, 16:57
It shouldn't affect portE which is where 2 of my relay pins are. I will try it anyway and let you know. Thanks for the suggestion!

Nick
Sure enough it will as PORTE<2:0> are multiplexed with AN<7:5>
http://www.sxlist.com/images/www/hobby_elec/gif/pic6_h04_411.gif

Macgman2000
- 2nd May 2009, 03:02
I went through and disabled everything and then some on portA and PortE. No dice. portA and PortE change from low to high but does not toggle. In fact it undoes any set pins on portA and E. It does not alter them at the bit level individually. My desired function is to latch individual pins in either 1 or 0 condition to energize a relay or de-energize it, through the decoding of local switch presses. I need to take a step back or something....thanks for your help guys.

Nick

Ioannis
- 2nd May 2009, 17:13
I repeat my question. Do you have any dev. kit or use your own PCB design?

Ioannis

Macgman2000
- 3rd May 2009, 20:18
The micro is on a circuit board. It uses a 20Mhz resonator and I am using in-circuit-programming. All ports are on header pins and not tied to anything, except for the button switches which are pulled low via 10k resistors. I have physical jumpers to put the hardware into ICP mode and then back to normal mode. I can set ports when the interrupt routine is called on any button press, but it does not decode the content of the variable I place the key press in to. IE, it blasts through conditional statements.

I can set bit wise port A and Port E within the interrupt. If within the interrupt I set portA (your bit of choice) and then use a conditional statement to reset portA (your chosen bit) if the bit is set...it does nothing....the port bit stays set. Toggle does nothing to alter the port logic level output.

Very strange.

Archangel
- 4th May 2009, 01:29
OK i have had an eintesy bit of success with your code.
To your config statement add _DEBIG_ON and ADD TRISB = %00000001 so the B.0 interrupt will work. I am not saying this will fix it, but it needs those fixes, gotta run, Gotta Barbeque.

Macgman2000
- 4th May 2009, 19:20
Ok for my own sanity, I would like confirmation on my understanding of how RB0 interrupt works or any interrupt for that matter. Once an interrupt condition happens, the interrupt flag is set, then the code is vectored to the interrupt start location.

In my code, I do the customary saving status, pclath..etc. Then I run my code, then repack status and pclath.
Retfie statement at the end of the interrupt clears the interrupt flag so now it is enabled to recieve interrupts. So during the time I am running my code in the interrupt, it shouldn't be retriggering the interrupt based on switch bounce until it sees Retfie....or does it? Somewhere, somehow the contents of the variable that I am passing to the case statements is getting hosed (I assume). The variable is specfied as bank0 System, so content must be common across banks.....or is it?

Lots of questions, I guess I am second guessing everything now.

Nick

Archangel
- 4th May 2009, 20:56
It is still a little buggy but it works after a fashion



DEFINE OSC 20

DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
DEFINE DEBUG_BAUD 2400 ' Set bit rate
DEFINE DEBUG_BIT 6
DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
DEFINE DEBUGIN_MODE 0 ' Set Debugin mode: 0 = true, 1 = inverted

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _keys2, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
ADCON0 = 0 ' Kill analog Functions
ADCON1 = 7
CMCON = 7
CVRCON = 0
CCP1CON = 0
CCP2CON = 0

; initialize Interrupts
OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
INTCON = %11010000 ; Enable INTE RB0 interrupt $90




;set port initializations
PORTA = %00000000
PORTE = %00000000


TRISA = %00000000 ; set port A to outputs for relays
TrisB = %00000001 ' b0 input for interrupt
TRISC = %10000000 'set 7 as input debugin
TRISD = %00000000 ; 8 button press inputs + RB0 interrupt for all off Made outputs as unused
TRISE = %00000000 ; set port E to outputs for relays
' Configure internal registers


payload VAR byte ; bank0 system ' data location for selecting relays
'payload1 var byte ; bank0 system ' previous good data
chksum var byte ; bank0 system ' check sum calculated at the TX side and sent over RF link


payload = 0
CHKSUM = 0


goto mainloop





keys2: ; called by interrupt to update relay

if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif

@ INT_RETURN



mainloop:
INTCON = %11010000 ; Enable INTE RB0 interrupt $90
; receive data packets and check sum, throwing out sync byte (255)
debugin [payload,chksum]
debug payload,chksum
if chksum != payload then ; verify good packets by comparing check sums
goto mainloop ; check sum does not match transmitted data
endif

update_keys:

if payload = 0 then
portE = 0
portA = 0
endif
if payload = 1 then
toggle portA.0
endif
if payload = 2 then
toggle portA.1
endif
if payload = 4 then
toggle portA.2
endif
if payload = 8 then
toggle portA.3
endif
if payload = 16 then
toggle portA.4
endif
if payload = 32 then
toggle portA.5
endif
if payload = 64 then
toggle portE.0
endif
if payload = 128 then
toggle portE.1
endif
PAYLOAD = 0 ' Zero here or loaded variable will turn on port next loop after INT
CHKSUM = 0
goto mainloop

Here is what I don't get . . if yoy turn on portE.0 and PortE.1 toggling either, toggles both. ???? I have in the past written code to do what this code does and had the same problem, only I think it was on portA.

Macgman2000
- 5th May 2009, 04:39
Great I am not the only one experiencing the weirdness of trying to use toggle! Thanks for verifying I am not going nuts!!!!! I have a version of the code written where the ports work in terms of toggling...but here is the kicker and I don't know why......I add pauses with in the Call routine, this allows the port to change and even toggle. But Only PortA.0......lol...... If rapid press for a few seconds eventually I get portA.1 but if PortA.0 is set, portA.1 change resets PortA.0.....man am I ready to throw this thing against the wall!

I want to eventually, when I calm down try to run a timer interrupt fast enough to look at the input port status. I don't know if I am just going to see the same problem or not.

Darrel Taylor
- 5th May 2009, 05:08
Ok for my own sanity, I would like confirmation on my understanding of how RB0 interrupt works or any interrupt for that matter. Once an interrupt condition happens, the interrupt flag is set, then the code is vectored to the interrupt start location.

In my code, I do the customary saving status, pclath..etc. Then I run my code, then repack status and pclath.

This HINT, was also a comment from your first code ...

; Save W, STATUS and PCLATH registers, if not done previously
Since a 16F877A has more than 2K of code space,
It was "done previously", and automatically by PBP.
Doing it again saves/restores the wrong values, which makes everything go Wacko.

However, you are also trying to CALL basic language routines from an ASM interrupt handler.

You can't do that.
At least, not the way your trying.
<br>

mister_e
- 5th May 2009, 06:00
try this one

@ __CONFIG _HS_OSC & _LVP_OFF
DEFINE OSC 20

INCLUDE ".\INCLUDE_ROUTINES\DT_INTS-14.bas"
INCLUDE ".\INCLUDE_ROUTINES\ReEnterPBP.bas"

;set port initializations
PORTA = %00000000
PORTE = %00000000

TRISA = %00000000 ; set port A to outputs for relays
TrisB = %00000001 ' b0 input for interrupt
TRISC = %10000000 'set 7 as input debugin
TRISD = %00000000 ; 8 button press inputs + RB0 interrupt for all off Made outputs as unused
TRISE = %00000000 ; set port E to outputs for relays

' Configure internal registers
ADCON1 = 7
CMCON = 7

DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
DEFINE DEBUG_BAUD 2400 ' Set bit rate
DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted
'DEFINE DEBUG_REG PORTC 'Debug pin port
'DEFINE DEBUG_BIT 6 'Debug pin bit
'DEFINE DEBUG_MODE 1 'Debug mode: 0 = True, 1 = Inverted

; initialize Interrupts
OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _keys2, PBP, yes
endm

INT_CREATE ; Creates the interrupt processor
ENDASM

NewPayload var Byte
payload VAR byte ' data location for selecting relays
chksum var byte ' check sum calculated at the TX side and sent over RF link
INT0IF var INTCON.1

CLEAR
pause 50 ' settle time
@ INT_CLEAR INT_INT ; make sure INT0IF is cleared
@ INT_ENABLE INT_INT ; Enable Interrupt

mainloop:
; receive data packets and check sum, throwing out sync byte (255)
DEBUGIN [wait(255),NewPayload, chksum]
'DEBUG NewPayload, chksum
if chksum != newpayload then MainLoop
payload=NewPayload
goto updatePort


keys2: ; Called by Interrupt update relay

pause 20 ' small debounce delay
if !PORTB.0 then GetOut ' button up?
' If so, getout of here... no need for noise call
UpdatePort:
select case payload
case 0
PORTE = 0
PORTA = 0
CASE 1
toggle portA.0
CASE 2
toggle portA.1
CASE 4
toggle portA.2
CASE 8
TOGGLE PORTA.3
CASE 16
toggle portA.4
CASE 32
toggle portA.5
CASE 64
toggle portE.0
CASE 128
toggle portE.1
END SELECT
GetOut:
If INT0IF THEN ' called by Interrupt?
@ INT_RETURN
' - Yes, clear the flag and getout
ELSE '
GOTO MAINLOOP
' - No, return to Mainloop
ENDIF

Make sure you transmit the right way from your PC...

Macgman2000
- 5th May 2009, 15:34
mister_e, I copied and pasted the code, I made one slight modification to the Include statements. I don't have them in the directories you have them in, but instead in the main PBP file. I switched over my assembler to MPASM. I get the following error when I compile.

"Error [118] c:\pbp\RX_New.asm 103: overwriting previous address contents 2007"

Ioannis
- 5th May 2009, 15:51
http://www.picbasic.co.uk/forum/showpost.php?p=14582&postcount=12

Ioannis

Macgman2000
- 5th May 2009, 16:24
Thanks Ioannis and mister_e, for your help!!!! I appreciate your patience, I feel like a fish out of water on this project.

The code is not responsive to button presses. I changed the port configuration from output to input on portD. enclosed is my button arrangment, the idea is any button press will also trigger the RB0 interrupt along with the key momentarily held on portD. Also, the code is attached for reference.

@ __CONFIG _HS_OSC & _LVP_OFF
DEFINE OSC 20

INCLUDE ".\DT_INTS-14.bas"
INCLUDE ".\ReEnterPBP.bas"



;set port initializations
PORTA = %00000000
PORTE = %00000000

TRISA = %00000000 ; set port A to outputs for relays
TrisB = %00000001 ' b0 input for interrupt
TRISC = %10000000 'set 7 as input debugin
TRISD = %11111111 ; 8 button press inputs + RB0 interrupt for all off Made outputs as unused
TRISE = %00000000 ; set port E to outputs for relays

' Configure internal registers
ADCON1 = 7
CMCON = 7

DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
DEFINE DEBUG_BAUD 2400 ' Set bit rate
DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted
'DEFINE DEBUG_REG PORTC 'Debug pin port
'DEFINE DEBUG_BIT 6 'Debug pin bit
'DEFINE DEBUG_MODE 1 'Debug mode: 0 = True, 1 = Inverted

; initialize Interrupts
OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _keys2, PBP, yes
endm

INT_CREATE ; Creates the interrupt processor
ENDASM

NewPayload var Byte
payload VAR byte ' data location for selecting relays
chksum var byte ' check sum calculated at the TX side and sent over RF link
INT0IF var INTCON.1

CLEAR
pause 50 ' settle time
@ INT_CLEAR INT_INT ; make sure INT0IF is cleared
@ INT_ENABLE INT_INT ; Enable Interrupt

mainloop:
; receive data packets and check sum, throwing out sync byte (255)
DEBUGIN [wait(255),NewPayload, chksum]
'DEBUG NewPayload, chksum
if chksum != newpayload then MainLoop
payload=NewPayload
goto updatePort


keys2: ; Called by Interrupt update relay

pause 20 ' small debounce delay
if !PORTB.0 then GetOut ' button up?
' If so, getout of here... no need for noise call
UpdatePort:
select case payload
case 0
PORTE = 0
PORTA = 0
CASE 1
toggle portA.0
CASE 2
toggle portA.1
CASE 4
toggle portA.2
CASE 8
TOGGLE PORTA.3
CASE 16
toggle portA.4
CASE 32
toggle portA.5
CASE 64
toggle portE.0
CASE 128
toggle portE.1
END SELECT
GetOut:
If INT0IF THEN ' called by Interrupt?
@ INT_RETURN
' - Yes, clear the flag and getout
ELSE '
GOTO MAINLOOP
' - No, return to Mainloop
ENDIF ;Make sure you transmit the right way from your PC...

mister_e
- 5th May 2009, 16:39
Well it has to go to the ISR, but probably you want to refresh the Payload value with the PushButton?

In this case...


keys2: ; Called by Interrupt update relay

pause 20 ' small debounce delay
if !PORTB.0 then GetOut ' button up?
' If so, getout of here... no need for noise call

PayLoad = PORTD ' read PushButtons and update Payload Value
UpdatePort:


You could also use a timer interrupt and poll PORTD, this will allow you to remove all those diodes, and leave RB0 for something else. As it is user push-button, you'll probably never feel the latency of the Timer interrupt.

Ioannis
- 5th May 2009, 17:08
Also if the button is kept low for a while it will always loop through the ISR.

Maybe a check at the start or the end of the ISR is needed to assure that button is released.

Ioannis

mister_e
- 5th May 2009, 17:12
It shouldn't loop that much, as the ISR is called by a rising edge.

Ioannis
- 5th May 2009, 18:10
Oh yes Steve. I missed that.

Then I cannot explain this bizzare behaviour.

Ioannis

mister_e
- 5th May 2009, 18:23
Yesterday I tried my version and it seems to work properly here, the second addition above "should" cover what the OP need...

Fact is, when you're using push button and interrupts, things can sometimes pan-out in weird way due to the noise on the contact when you push/release them.

keys2: ; Called by Interrupt update relay

pause 20 ' small debounce delay
if !PORTB.0 then GetOut ' button up?
' If so, getout of here... no need for noise call


is one way to avoid problem, even thought, it's not always the best way ;)

Macgman2000
- 5th May 2009, 19:31
mister-e you are right on the money! I added PayLoad = PORTD and it works very well, it toggles the individual bits only and not reset the entire port. PortA.4 is not responding though....it stays low.

Thank you and everyone who helped. I think I will be using this new interrupt handler in the future.

Nick

mister_e
- 5th May 2009, 19:49
<table><tr><td>http://img.photobucket.com/albums/v197/kaeli/homer_woohoo.jpg</td><td>

PortA.4 is not responding though....it stays low

for PORTA.4... well... it's an open-collector output type on this one. So you may need to slightly modify your hardware and software.

http://www.picbasic.co.uk/forum/showthread.php?t=11116

In brief, connect your LED between Vdd and PORTA.4, and change those

PORTA = 0
to

PORTA = %00010000

That should work for LEDs. If you drive a transistor but then it's easier... not software modification are needed, just hardware.
</td></tr></table>