Author Topic: Interrupts, variables, and increments  (Read 2866 times)

Offline kronosslayer

  • ½ Pint
  • *
  • Posts: 36
  • Post quality +6/-0
  • Gender: Male
  • Acidmods User
Interrupts, variables, and increments
« on: July 01, 2011, 12:06:04 AM »
Hello acidmodz!!
I have a few question id like to lay down and see if i can get an answer. I have been spending most of my summer learning to program PIC's in ASM...currently the 12f683, but i'm having trouble finding explanations on things that are probably quite simple for others(PLEASE.. i understand theres a datasheet, and good tutorials at gooligum, but im still stumped which is why i have come here).

 My programming style may be a bit messy so bare with me. Here's my current code. A few things i'm unsure about is initializing variables  [MODE EQU 0x70] not sure about the proper technique. Then, I believe that i have the bare template for an interrupt but am not having too much luck(i still need to incorporate debouncing my switch). I'm trying to use the interrupt as a way to catch button input from GP5 and increment a variable[MODE] and test the mode(I thought that INCF would work but it didnt?!?), then do the corresponding loop.
Using XORWF to compare number for the correct mode seemed to be buggy for me and not work correctly, but most of my questions tie back into if my method of variable declarations is valid.
Any feedback is Greatly Appreciated...  :dntknw: :yess:
Kronosslayer
Code: [Select]
list p=12f683
include <p12f683.inc>

__config 0x0FB4
errorlevel -302


MODE EQU 0x70
INNER EQU 0x71
OUTER EQU 0x72
w_temp EQU 0x73
status_temp EQU 0x74
MODE_temp EQU 0x75

ORG 0x0000
GOTO Main

ORG 0x0004 ;;INTERRUPT
BCF INTCON,GPIF ;;GPIO interrupt flag
MOVWF w_temp
MOVF STATUS,w
MOVWF status_temp
MOVF MODE,w
MOVWF MODE_temp

MOVLW 0x00
MOVWF GPIO
CALL delay_256ms

INCF MODE

MOVF status_temp,w
MOVWF STATUS
SWAPF w_temp,f
SWAPF w_temp,w
RETFIE





Main
CLRF MODE ;;Set mode to zero
CLRF INNER ;;Set inner to zero
CLRF OUTER ;;Set outer to zero

BSF STATUS,RP0 ;;Bank 1
CLRF ANSEL ;;Digital I/O
MOVLW b'10001000'
MOVWF INTCON
MOVLW b'100000'
MOVWF IOC ;;GP5 interrupt
MOVLW b'101000'
MOVWF TRISIO ;;GP3,5 inputs

BCF STATUS,RP0 ;;Bank 0
CLRF GPIO
MOVLW 0x07
MOVWF CMCON0
GOTO Main_LOOP

delay_256ms
NOP
DECFSZ INNER,f
GOTO delay_256ms
DECFSZ OUTER,f
GOTO delay_256ms
RETURN

Main_LOOP

MOVLW 0x00 ;;if mode 0
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP0

MOVLW 0x01 ;;if mode 1
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP1

MOVLW 0x02 ;;if mode 2
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP2

MOVLW 0x03 ;;if mode 3
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP3

MOVLW 0x04 ;;if mode 4
XORWF MODE,f
BTFSC STATUS,Z
GOTO Sub_LOOP_RESET

GOTO Main_LOOP

Sub_LOOP0 ;;MODE 0 loop
CLRF GPIO
MOVLW 0xFF
MOVWF GPIO ;;GPIO to HIGH
CALL delay_256ms
GOTO Main_LOOP

Sub_LOOP1 ;;MODE 1 loop
CLRF GPIO
MOVLW b'010110'
MOVWF GPIO
CALL delay_256ms
GOTO Main_LOOP

Sub_LOOP2 ;;MODE 2 loop
CLRF GPIO
MOVLW b'010010'
MOVWF GPIO
CALL delay_256ms
MOVLW b'000101'
MOVWF GPIO
CALL delay_256ms
GOTO Main_LOOP

Sub_LOOP3 ;;MODE 3 loop
CLRF GPIO
MOVLW 1<<GP0
MOVWF GPIO
CALL delay_256ms
MOVLW 1<<GP4
MOVWF GPIO
CALL delay_256ms
MOVLW 1<<GP2
MOVWF GPIO
CALL delay_256ms
MOVLW 1<<GP1
MOVWF GPIO
CALL delay_256ms
GOTO Main_LOOP

Sub_LOOP_RESET
CLRF MODE

END
I'm a java developer, Graphic Designer, and an a**hole.

Offline hyper999

  • Acidmods Alumni
  • Millennium Poster
  • *
  • Posts: 1158
  • Post quality +544/-3
  • Research and Development
Re: Interrupts, variables, and increments
« Reply #1 on: July 01, 2011, 01:09:23 AM »
Ok well first off well done for making it this far! most people have given up by now :P

Right well I skimmed through and your variables look fine. I didn't see anything else that looked really wrong, but I recomend you try the DECFSZ instruction instead of INCF as it eliminates the need for XOR'ing stuff. Also you may want to try using the debugger to step through your code in mplab.

(sorry if i missed anything, its very early in the morning here)

Offline kronosslayer

  • ½ Pint
  • *
  • Posts: 36
  • Post quality +6/-0
  • Gender: Male
  • Acidmods User
Re: Interrupts, variables, and increments
« Reply #2 on: July 01, 2011, 01:24:39 AM »
Thank you for the reply! it's 4AM here :faint:
Yes Mplab Sim is what i usually use to check my programs

Ok well my variables are fine...my interrupt seems to be whats holding me up ( i think it isnt exiting the interrupt properly but i;m unsure)

As for the DECFSZ

im a bit more comfortable with XOR, but how would i be able to use DECFSZ to check MODE's value.
or am i just decrementing instead of incrementing the value of MODE


Im sure something can be figured out if my interrupt problem was fixed?!?  :confused:
I'm a java developer, Graphic Designer, and an a**hole.

Offline Hazer

  • x4675636B4E7574
  • Acidmods Alumni
  • Acid Modder
  • *
  • Posts: 583
  • Post quality +59/-0
Re: Interrupts, variables, and increments
« Reply #3 on: July 01, 2011, 03:40:11 AM »
The code looks good to me. I know what the problem is.

Quote
For enabled interrupt-on-change pins, the values are
compared with the old value latched on the last read of
GPIO. The ‘mismatch’ outputs of the last read are OR’d
together to set the GPIO Change Interrupt Flag bit
(GPIF) in the INTCON register (Register 2-3).
The
user, in the Interrupt Service Routine, clears the
interrupt by:
a) Any read or write of GPIO. This will end the
mismatch condition, then,
b) Clear the flag bit GPIF.
A mismatch condition will continue to set flag bit GPIF.
Reading GPIO will end the mismatch condition and
allow flag bit GPIF to be cleared.

To clear IOC interupt, you have to first read GPIO, then clear the flag.

You should also realize that when you release the button, a second interupt will occur.

Also, at the start of your interupt the lines to move your STATUS and WORK register should always be first. By placing the BCF and MVF instructions before storing the STATUS and WREG, you are changing them before they get stored, and your main code gets messed up when the interupt occurs. You should always clear the source of theinterupt at the very end of you interupt service routine. And you dont need to do anything to GPIO other than read it.

Lastly, I would remove the last compare (XORWF w/ 0x04) and just let the code goto sub_loop_reset at that point. If your MODE register has a value other then 0x00-0x04, then the main loop will just loop forever. Remove the last compare, because if you have any vlaue other than 0x00-0x03, you want to reset the value.

Good work so far, I like peope who try.
[Quote from Gamermodz via Viking forums]
Don't be jealous your not half as smart. I hate ****tards like you. An ignorant redneck. Your nothing but a posing ******. Get the **** out of here, really, your claim to fame is an open source rapid fire code? You make me laugh. You think you have control over the modding market?  You couldn't create what I can and do. You are too ignorant with your outrageous assumptions and accusations. [/Quote]

Offline hyper999

  • Acidmods Alumni
  • Millennium Poster
  • *
  • Posts: 1158
  • Post quality +544/-3
  • Research and Development
Re: Interrupts, variables, and increments
« Reply #4 on: July 01, 2011, 07:39:55 AM »
Thank you for the reply! it's 4AM here :faint:
Yes Mplab Sim is what i usually use to check my programs

Ok well my variables are fine...my interrupt seems to be whats holding me up ( i think it isnt exiting the interrupt properly but i;m unsure)

As for the DECFSZ

im a bit more comfortable with XOR, but how would i be able to use DECFSZ to check MODE's value.
or am i just decrementing instead of incrementing the value of MODE


Im sure something can be figured out if my interrupt problem was fixed?!?  :confused:

Ignore my comment about DECFSZ stick with INCF I wasn't very awake earlier on :P

Offline kronosslayer

  • ½ Pint
  • *
  • Posts: 36
  • Post quality +6/-0
  • Gender: Male
  • Acidmods User
Re: Interrupts, variables, and increments
« Reply #5 on: July 01, 2011, 04:16:08 PM »
Yeah allowing the final check to call Sub_LOOP_RESET is like an ELSE statement closing a conditional branch...Gotcha

For my tactile switch would it be better to add a debounce time or disable GP5's IOC as soon as the interrupt is called?

Sorry for the noobish question, but could i just save the value GPIO in a temp variable in my interrupt, then before the interrupt ends just replace the current GPIO with the temp one? Would that be counted as reading?

*EDIT*
This is my new code. I have added instructions within my sub loop for debugging... where i have 1 being added mode. This is what i find odd... either adding one or using INCF, My code goes to Sub_LOOP0, then adds, goes to Sub_LOOP1, then adds but keeps returning to Sub_LOOP1?? Again this happens with both "MOVLW  0x01, ADDWF  MODE" and "INCF  MODE,f".
I;m doing this in MPlab Sim, so the interrupt is not called. This is for the soul purpose of checking my incrementing methods. Which appear to be invalid.

If my interrupt code is needed i can post that as well.   
Code: [Select]
Main_LOOP

MOVLW 0x00 ;;if mode 0
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP0

MOVLW 0x01 ;;if mode 1
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP1

MOVLW 0x02 ;;if mode 2
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP2

MOVLW 0x03 ;;if mode 3
XORWF MODE,F
BTFSC STATUS,Z ;;If MODE == W
GOTO Sub_LOOP3

GOTO Sub_LOOP_RESET ;;If MODE != 0,1,2,3

Sub_LOOP0 ;;MODE 0 loop
CLRF GPIO
MOVLW 0xFF
MOVWF GPIO
MOVLW 0x01
ADDWF MODE ;;GPIO to HIGH
GOTO Main_LOOP

Sub_LOOP1 ;;MODE 1 loop
CLRF GPIO
MOVLW b'010110'
MOVWF GPIO
MOVLW 0x01
ADDWF MODE
GOTO Main_LOOP

Sub_LOOP2 ;;MODE 2 loop
CLRF GPIO
MOVLW b'010010'
MOVWF GPIO
;CALL delay_256ms
MOVLW b'000101'
MOVWF GPIO
;CALL delay_256ms
MOVLW 0x01
ADDWF MODE
GOTO Main_LOOP

Sub_LOOP3 ;;MODE 3 loop
CLRF GPIO
MOVLW 1<<GP0
MOVWF GPIO
;CALL delay_256ms
MOVLW 1<<GP4
MOVWF GPIO
;CALL delay_256ms
MOVLW 1<<GP2
MOVWF GPIO
CALL delay_256ms
;MOVLW 1<<GP1
MOVWF GPIO
;CALL delay_256ms
MOVLW 0x01
ADDWF MODE
GOTO Main_LOOP

Sub_LOOP_RESET
CLRF MODE

END
« Last Edit: July 01, 2011, 05:21:20 PM by kronosslayer »
I'm a java developer, Graphic Designer, and an a**hole.

Offline Hazer

  • x4675636B4E7574
  • Acidmods Alumni
  • Acid Modder
  • *
  • Posts: 583
  • Post quality +59/-0
Re: Interrupts, variables, and increments
« Reply #6 on: July 01, 2011, 06:59:14 PM »
I did not catch that earlier.

You do not want to use XORWF instructions. It will simply mask out everything except the first bit. You want to check if MODE = 0x01. So do the following instead:

Code: [Select]
              movlw   0x01
              subwf    MODE, w
              btfsc      STATUS, Z
              goto      Sub_Loop0

              movlw   0x02
              subwf    MODE, w
              btfsc      STATUS, Z
              goto      Sub_Loop1

You do not want the result of the subtraction to be the MODE register since you do not want to change it, but just check what it is. So instead of using the F destination operand, use the W destination operand.
[Quote from Gamermodz via Viking forums]
Don't be jealous your not half as smart. I hate ****tards like you. An ignorant redneck. Your nothing but a posing ******. Get the **** out of here, really, your claim to fame is an open source rapid fire code? You make me laugh. You think you have control over the modding market?  You couldn't create what I can and do. You are too ignorant with your outrageous assumptions and accusations. [/Quote]

Offline kronosslayer

  • ½ Pint
  • *
  • Posts: 36
  • Post quality +6/-0
  • Gender: Male
  • Acidmods User
Re: Interrupts, variables, and increments
« Reply #7 on: July 02, 2011, 02:02:45 AM »
As a result from all the help, I m able to present to you [insert catchy name for code]
My semi-final code for Light flashing modes.
Code: [Select]
list p=12f683
include <p12f683.inc>

__config 0x0CB4 ;Oscillator = Internal RC NO clock
;Watchdog    = OFF
;Power up timer = OFF
;MCE = EXTERNAL
;Configuration ;Code Protect = ON
;EE read protect = OFF
;BOD = BOTH OFF
;IESOM = ENABLED
;Monitor Clock safe = ENABLED

errorlevel -302 ;Block error in list file


MODE EQU 0x70 ;Mode counter
INNER EQU 0x71 ;Inner loop counter
OUTER EQU 0x72 ;Outer loop counter
w_temp EQU 0x73 ;Work temp
status_temp EQU 0x74 ;STATUS temp
BIT EQU 0x75 ;Interrupt Flag for incrementing
;OUTER128 EQU 0x76 ;Counter for 128ms delay
;OUTER64 EQU 0x077 ;Counter for 64ms delay

ORG 0x0000
GOTO Declarations ;To declare everything


ORG 0x0004 ;|=-INTERRUPT-=|
MOVWF w_temp ;WORK saved
MOVF STATUS,w ;STATUS saved
MOVWF status_temp

BTFSC GPIO,GP5
CALL Button_Pressed ;Executes interrupt code

MOVF status_temp,w
MOVWF STATUS ;Restore STATUS
SWAPF w_temp,f ;Restore WORK
SWAPF w_temp,w
BCF INTCON,GPIF
RETFIE



Declarations

CLRF MODE ;Set MODE to 0
CLRF INNER ;Set INNER to 0
CLRF OUTER ;Set OUTER to 0

BSF STATUS,RP0 ;Bank 1
CLRF ANSEL ;Digital I/O
MOVLW b'10001000'
MOVWF INTCON ;Global and GPIO interupt
MOVLW b'100000'
MOVWF IOC ;GP5 interrupt
MOVLW b'101000'
MOVWF TRISIO ;GP3,5 inputs

BCF STATUS,RP0 ;Bank 0
CLRF GPIO
MOVLW 0x07
MOVWF CMCON0 ;Comparators off
GOTO Main_Loop

delay ;Defaults to roughly 256ms unless value is moved into outer before call
NOP
DECFSZ INNER,f
GOTO delay ; ~1023 cycles = 1ms
DECFSZ OUTER,f
GOTO delay ; 1ms * 256 = 256ms
RETURN

MODE_INCREMENT ;Only called once the interrupt has, adds 1 to MODE, RETURNS to Main loop
INCF MODE
CLRF BIT
GOTO Main_Loop

Main_Loop
MOVLW 0x01
SUBWF BIT,w
BTFSC STATUS,Z ;if interrupt has been called increment MODE
GOTO MODE_INCREMENT

MOVLW 0x01
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==1
GOTO Sub_LOOP1

MOVLW 0x02
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==2
GOTO Sub_LOOP2

MOVLW 0x03
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==3
GOTO Sub_LOOP3

MOVLW 0x04
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==4
GOTO Sub_LOOP4

MOVLW 0x05
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==5
GOTO Sub_LOOP5

MOVLW 0x06
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==6
GOTO Sub_LOOP6

MOVLW 0x07
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==7
GOTO Sub_LOOP7

MOVLW 0x08
SUBWF MODE,w
BTFSC STATUS,Z ;IF MODE==8
GOTO Sub_LOOP8

GOTO Sub_LOOP_RESET


Sub_LOOP1
CLRF GPIO ;MODE 1 loop
GOTO Main_Loop

Sub_LOOP2 ;MODE 2 loop
MOVLW b'010111'
MOVWF GPIO
GOTO Main_Loop

Sub_LOOP3 ;MODE 3 loop
MOVLW b'010111'
MOVWF GPIO
CALL delay
CALL delay
CLRF GPIO
CALL delay
CALL delay
GOTO Main_Loop

Sub_LOOP4 ;MODE 4 loop
MOVLW 1<<GP0
MOVWF GPIO
CALL delay
MOVLW (1<<GP0|1<<GP4|1<<GP1)
MOVWF GPIO
CALL delay
MOVLW b'010111'
MOVWF GPIO
CALL delay
CLRF GPIO
CALL delay
GOTO Main_Loop

Sub_LOOP5 ;MODE 5 loop
MOVLW 1<<GP2
MOVWF GPIO
CALL delay
MOVLW (1<<GP2|1<<GP4|1<<GP1)
MOVWF GPIO
CALL delay
MOVLW b'010111'
MOVWF GPIO
CALL delay
CLRF GPIO
CALL delay
GOTO Main_Loop

Sub_LOOP6 ;MODE 6 loop
MOVLW b'000101'
MOVWF GPIO
CALL delay
MOVLW b'010010'
MOVWF GPIO
CALL delay
GOTO Main_Loop

Sub_LOOP7 ;MODE 7 loop
MOVLW 1<<GP0
MOVWF GPIO
MOVLW 0x80 ;128 in deciaml
MOVWF OUTER ;128ms
CALL delay
MOVLW 1<<GP4
MOVWF GPIO
MOVLW 0x80 ;128 in deciaml
MOVWF OUTER ;128ms
CALL delay
MOVLW 1<<GP2
MOVWF GPIO
MOVLW 0x80 ;128 in deciaml
MOVWF OUTER ;128ms
CALL delay
MOVLW 1<<GP1
MOVWF GPIO
MOVLW 0x80 ;128 in deciaml
MOVWF OUTER ;128ms
CALL delay
GOTO Main_Loop

Sub_LOOP8 ;MODE 8 loop
MOVLW 1<<GP4
MOVWF GPIO
CALL delay
MOVLW 1<<GP1
MOVWF GPIO
CALL delay
MOVLW 1<<GP0
MOVWF GPIO
CALL delay
MOVLW 1<<GP2
MOVWF GPIO
CALL delay
GOTO Main_Loop


Sub_LOOP_RESET
MOVLW 0x01
MOVWF MODE
CLRF GPIO
GOTO Main_Loop

Button_Pressed
MOVLW 0x01 ;Increment has been called BIT = 1
MOVWF BIT
RETURN

END
I'm a java developer, Graphic Designer, and an a**hole.

 

SMF spam blocked by CleanTalk
SimplePortal 2.3.5 © 2008-2012, SimplePortal