...will that allow me to know which actual switch changed over[?] - I need the pulse to go to 1 of 4 outputs.
;***** VARIABLE DEFINITIONS (examples)
; Assume switches are on portb, switch1-4 specify the bits
switchport equ PORTB
switch1 equ 0x0
switch2 equ 0x1
switch3 equ 0x2
switch4 equ 0x3
; example of using Shared Uninitialized Data Section
INT_VAR UDATA_SHR
hold RES 1 ; Place to store last polled switch position
;**********************************************************************
RESET_VECTOR CODE 0x0000 ; processor reset vector
goto start ; go to beginning of program
INT_VECTOR CODE 0x004 ; interrupt vector location
INTERRUPT
; put interrupt handling code here (there's none in this example)
retfie ; return from interrupt
MAIN_PROG CODE
start
movfw switchport ; Get initial switch positions
movwf hold ; and place them in the hold area
loop
movfw switchport ; Get current switch positions
xorwf hold,w ; Exclusive-OR with hold area to get changed bits
andlw 0x0f ; mask out unused bits
btfsc STATUS, Z ; If no bits changed, loop
goto loop
movwf hold ; put W into hold area so we can btfsc it
btfsc hold,switch1 ; If switch 1 flipped, call pulse1
call pulse1
btfsc hold, switch2 ; If switch 2 flipped, call pulse2
call pulse2
btfsc hold, switch3 ; If switch 3 flipped, call pulse3
call pulse3
btfsc hold, switch4 ; If switch 4 flipped, call pulse4
call pulse4
goto start ;Reset hold area and poll switches again
pulse1 nop ; Generate pulse for switch1
return
pulse2 nop ; Generate pulse for switch2
return
pulse3 nop ; Generate pulse for switch3
return
pulse4 nop ; Generate pulse for switch4
return
END ; directive 'end of program'
The best way to know is to look at the datasheet for the particular PIC you're using. Probably 10-20 mA depending on the PIC and how many of its internal features you use. Clock speed is a factor too, a lower clock speed will generally draw less power, and for a simple application like yours, you don't need the PIC running at 20 MHz.Also how much does a pic guzzle (mA) when it’s just running the code and not actually pulsing? As this project has to run on batteries. I was recently shocked when I found out a 9v battery has a much lower mAH capacity than AA batteries. Trouble with AA batteries is that you need 4 which take up more room.
marcbarker: how long do you think the switches will last before playing up? Assuming they are switched no more than 4 times per day? We talking months or years?
Also how much does a pic guzzle (mA) when it’s just running the code and not actually pulsing? .
The RES command (which is a directive to the assembler, not an actual PIC opcode) reserves a space in memory (the file registers). Instead of having to assign addresses (file registers in PIC land) to each variable, you give your variable a name ("hold" in my case) and how many bytes it needs, and the compiler handles the details of assigning an available file register location.
that Exclusive-OR trick .
The PIC can be configured to use microwatts of power, it can spend most of its time asleep and waking up just long enough to sniff the inputs and go back to sleep again.
LIST P=PIC16F628A
#include <p16F628A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF &_INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
; __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF &_INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF
org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
;this is where the program starts running
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
STATUS equ 03h
TRISA equ 85h
PORTA equ 05h
TRISB equ 86h
PORTB equ 06h
COUNT1 equ 0Ch ;First counter for our delay
COUNT2 equ 0Fh
TEN equ 3Ch
COUNT3 equ 0Eh
MEM equ 2Ch
clrf PORTA ;all of porta low
clrf PORTB ;all of portb low
;----------------------------------------------------------------------------------
bsf 03h,5 ;BANK 1
movlw b'11111111'
movwf TRISB
bcf 81h,7 ;pull ups on
bsf 8Bh,7 ;global interrupts on
bsf 8Bh,3 ;RB port change on
movlw b'00000000'
movwf TRISA
bcf 03h,5 ;BANK 0
start
movfw PORTB ;READ THE INITIAL SWITCH POSITIONS
movwf MEM ;SAVE THEM TO MEM
loop
;call delay
movfw PORTB ;READ CURRENT SW POSTIONS
xorwf MEM,w ;ex-OR with mem save to w. Any change will give a 1
andlw b'00001111' ;masks last 4 ports (affects status)
btfsc STATUS,Z ;if any bits have changed z will flag causing jump
;Z: Zero bit
;1 = The result of an arithmetic or logic operation is zero
;0 = The result of an arithmetic or logic operation is not zero
bcf 0Bh,0 ;RB port change flag clear
sleep
goto loop ;keeps looping till there is a change
movwf MEM ;move what's in the working register to mem
btfsc MEM,0
call pulse0
btfsc MEM,1
call pulse1
btfsc MEM,2
call pulse2
btfsc MEM,3
call pulse3
goto start
pulse0 movlw b'00000001' ;RA0
call pulse
return
pulse1 movlw b'10000000' ;RA7
call pulse
return
pulse2 movlw b'01000000' ;RA6
call pulse
return
pulse3 movlw b'00001000' ;RA3
call pulse
return
pulse movwf PORTA
call setten
call delay
movlw b'00000000'
movwf PORTA
return
delay decfsz COUNT1,1 ;Subtract 1 from 255
goto delay
decfsz COUNT2,1 ;Subtract 1 from 255
goto delay ;Go back to the start of our loop.
decfsz COUNT3,1 ;This delay counts down from ;255 to zero, 255 times
goto delay
return
setten movlw 8
movwf COUNT3
Return
end
No, only pins (bits) 7-4 on PORTB will trigger an interrupt and wake on change. Just put your switch inputs on those pins and you'll be good to go.The data sheet says ‘when at least one of the RB<7:4> change state What does RB<7:4> mean? Pin 7,6,5,4?? I set my inputs on 0,1,2,3 will it still work?
You're better off using the declarations in the include file for the registers and bits instead of constants.Was my use of
bsf 8Bh,7 ;global interrupts on
bsf 8Bh,3 ;RB port change on
bcf 0Bh,0 ;RB port change flag clear
correct?
bsf INTCON,GIE ; global interrupts on
bsf INTCON,RBIE ; RB port change interrupt on
bcf INTCON,RBIF ; port change flag clear
movlw b'10001000' ; Set GIE, RBIE, and clear all others
movwf INTCON
LIST P=PIC16F628A
radix dec
#include <p16F628A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF &_INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
; __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF &_INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF
swnew equ 0x20 ; new switch press bits
swold equ 0x21 ; switch state latch
delayhi equ 0x22 ; DelayCy() sub-system variable
;******************************************************************
; K8LH DelayCy() subsystem macro generates four instructions *
;******************************************************************
radix dec
clock equ 4 ; 4, 8, 12, 16, 20 (MHz), etc.
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ clock/4*1000 ; cycles/millisecond multiplier
DelayCy macro delay ; 11..327690 cycle range
movlw high((delay-11)/5)+1
movwf delayhi
movlw low ((delay-11)/5)
call uDelay-((delay-11)%5)
endm
;******************************************************************
; main program *
;******************************************************************
org 0x0000
v_reset
movlw 0x07 ; |B0
movwf CMCON ; comparators off |B0
clrf PORTA ; clear port A output latches |B0
clrf PORTB ; clear port B output latches |B0
bsf STATUS,RP0 ; bank 1 |B1
movlw b'11111111' ; |B1
movwf TRISB ; port B all inputs |B1
movlw b'00000000' ; |B1
movwf TRISA ; port A all outputs |B1
bcf OPTION_REG,7 ; weak pull-ups on |B1
bcf STATUS,RP0 ; bank 0 |B0
bsf INTCON,RBIE ; IOC interrupt enable |B0
clrf swold ; clear switch state latch |B0
;
; main program loop
;
suspend
movf PORTB,W ; clear IOC mismatch condition |B0
bcf INTCON,RBIF ; clear IOC interrupt flag bit |B0
sleep ; sleep, wait for IOC interrupt |B0
nop ; |B0
dbounce
DelayCy(24*msecs) ; sample at 24 msec intervals |B0
;
; swnew __---___---___---___---___ fresh switch sample
; swold ___---___---___---___---__ switch state latch
; swnew __-__-__-__-__-__-__-__-__ changes, press or release
; swnew __-_____-_____-_____-_____ new press bits
;
comf PORTB,W ; sample active low switches |B0
andlw b'11110000' ; on RB7..RB4 pins |B0
xorwf swold,W ; changes, press or release? |B0
bz dbounce ; no, branch, else |B0
xorwf swold,F ; update switch state latch |B0
andwf swold,W ; filter out new release bits |B0
bz suspend ; branch for new release, else |B0
movwf swnew ; save "new press" bits |B0
;
; optional 32-msec 500-Hz "new press" beep (spkr on RA4, 6, or 7)
;
; movlw 32 ; |B0
; movwf beepctr ; |B0
;beep movf PORTA,W ; |B0
; xorlw 1<<spkr ; |B0
; movwf PORTA ; |B0
; DelayCy(1*msecs-6) ; interval for 500-Hz tone |B0
; decfsz beepctr,F ; done? yes, skip, else |B0
; goto beep ; |B0
swapf swnew,W ; swap new press bits in WREG |B0
xorwf PORTA,F ; toggle output (pulse on) |B0
DelayCy(100*usecs-2) ; pulse width minus 2 cycles |B0
swapf swnew,W ; swap new press bits in WREG |B0
xorwf PORTA,F ; toggle output (pulse off) |B0
; goto dbounce ; debounce release before sleep |B0
goto suspend ; debounce release after sleep |B0
;******************************************************************
; K8LH DelayCy() subsystem 16-bit uDelay(11..327690 cycle) sub' *
; *
; 9 words, 1 RAM variable, 14-bit core *
;******************************************************************
nop ; entry for (delay-11)%5 == 4 |B0
nop ; entry for (delay-11)%5 == 3 |B0
nop ; entry for (delay-11)%5 == 2 |B0
nop ; entry for (delay-11)%5 == 1 |B0
uDelay addlw -1 ; subtract 5 cycle loop time |B0
skpc ; borrow? no, skip, else |B0
decfsz delayhi,F ; done? yes, skip, else |B0
goto uDelay ; do another loop |B0
return ; |B0
;******************************************************************
end
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?