PIC16F627 code issue, need some help

Thread Starter

David5093

Joined Apr 23, 2009
19
Hi,

I am trying to write some code that will give me two different outputs
depending on what sequence of buttons (inputs) are pressed but it doesn't
seem to work, keeps going to the fail routine no mater what button I press.
Can anyone provide some assistance as to where or what i'm doing wrong?

Regards

David

;**************************************************************************
;* VELLEMAN High-Q KIT K8048/VM111 SAMPLE SOFTWARE *
;**************************************************************************
;* Microchip PIC(tm) Programmer & experiment board *
;* DEMO2 program for testing K8048 with PIC16F627(A)! *
;* Generate 4 LED light effects, you can select these with SW1..4 *
;**************************************************************************
;* (C) VELLEMAN Components,2003 All rights reserved *
;**************************************************************************
;* Hardw. Rev: P8048'1 Softw. Rev: 1.21 *
;* OSC.......: XT 4MHz Max. POWER.....: 12V DC *
;**************************************************************************
W EQU H'0000'
F EQU H'0001'
;----- Register Files------------------------------------------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
INTCON EQU H'000B'
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
CMCON EQU H'001F'
;----- STATUS Bits --------------------------------------------------------
IRP EQU H'0007'
RP1 EQU H'0006'
RP0 EQU H'0005'
NOT_TO EQU H'0004'
NOT_PD EQU H'0003'
Z EQU H'0002'
DC EQU H'0001'
C EQU H'0000'
;==========================================================================
;
; RAM Definition
;
;==========================================================================
__MAXRAM H'01FF'
__BADRAM H'07'-H'09', H'0D', H'13'-H'14', H'1B'-H'1E'
__BADRAM H'87'-H'89', H'8D', H'8F'-H'91', H'93'-H'97', H'9E'
__BADRAM H'105', H'107'-H'109', H'10C'-H'11F', H'150'-H'16F'
__BADRAM H'185', H'187'-H'189', H'18C'-H'1EF'
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
_BODEN_ON EQU H'3FFF'
_BODEN_OFF EQU H'3FBF'
_CP_ALL EQU H'03FF'
_CP_75 EQU H'17FF'
_CP_50 EQU H'2BFF'
_CP_OFF EQU H'3FFF'
_DATA_CP_ON EQU H'3EFF'
_DATA_CP_OFF EQU H'3FFF'
_PWRTE_OFF EQU H'3FFF'
_PWRTE_ON EQU H'3FF7'
_WDT_ON EQU H'3FFF'
_WDT_OFF EQU H'3FFB'
_LVP_ON EQU H'3FFF'
_LVP_OFF EQU H'3F7F'
_MCLRE_ON EQU H'3FFF'
_MCLRE_OFF EQU H'3FDF'
_ER_OSC_CLKOUT EQU H'3FFF'
_ER_OSC_NOCLKOUT EQU H'3FFE'
_INTRC_OSC_CLKOUT EQU H'3FFD'
_INTRC_OSC_NOCLKOUT EQU H'3FFC'
_EXTCLK_OSC EQU H'3FEF'
_LP_OSC EQU H'3FEC'
_XT_OSC EQU H'3FED'
_HS_OSC EQU H'3FEE'
__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC
;==========================================================================
; Variable Definition
;==========================================================================
;INPUTS
SW1 EQU H'00' ;SW1 is triggering RA0
SW2 EQU H'01' ;SW2 is triggering RA1
SW3 EQU H'02' ;SW3 is triggering RA2
SW4 EQU H'03' ;SW4 is triggering RA3
TIMER1 EQU H'20' ;Used in delay routine
TIMER2 EQU H'21' ; " " "
PATERN EQU H'22' ;Pattern data for effect's

ORG 0 ;Reset vector address
GOTO RESET ;goto RESET routine when boot.

; *********************************************
; * Example of a delay routine *
; *********************************************
DELAY_ROUTINE MOVLW D'255'
MOVWF TIMER2
DEL_LOOP1 MOVLW D'255'
MOVWF TIMER1
DEL_LOOP2 DECFSZ TIMER1,F
GOTO DEL_LOOP2
DECFSZ TIMER2,F
GOTO DEL_LOOP1
RETLW 0

; **********************************
; ** RESET : main boot routine **
; **********************************
RESET MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU
;
MENU CLRF PORTB
;
BTFSC PORTA,SW1
GOTO FAILURE
BTFSC PORTA,SW2
GOTO FAILURE
BTFSC PORTA,SW3
GOTO FAILURE
BTFSC PORTA,SW4
GOTO SEQ_1
GOTO MENU
SEQ_1 BTFSC PORTA,SW2 ; Wait for Switch 2 to release
GOTO SEQ_2 ; If so wait for Switch 3
BTFSC PORTA,SW1 ; If Switch 1 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW3 ; If Switch 3 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO FAILURE
SEQ_2 BTFSC PORTA,SW3 ; Wait for switch 3 to release
GOTO SEQ_3 ; If so wait for Switch 1
BTFSC PORTA,SW1 ; If Switch 1 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW2 ; If Switch 2 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO FAILURE
SEQ_3 BTFSC PORTA,SW1 ; Wait for Switch 1 to release
GOTO PASS ; If so you have Passed
BTFSC PORTA,SW2 ; If Switch 2 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW3 ; If Switch 3 is pressed, Fail
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO FAILURE

PASS MOVLW B'00100000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111111' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
GOTO PASS

FAILURE MOVLW 0x3F ; Moves (63 decimal, 111111 binary) into the W register
MOVWF PORTA ; Set all bits on
MOVWF PORTB ; LEDs on
NOP ; The 'nop' make up the time taken by the goto
NOP ; giving a square wave output
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
MOVLW 0x00 ; Moves (00 decimal, 000000 binary) into the W register
MOVWF PORTA ; Set all bits off
MOVWF PORTB ; LEDs off
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
GOTO FAILURE ; Repeat
END
 

n9352527

Joined Oct 14, 2005
1,198
The intended key sequence seems to be 4-2-3-1. The code only checks for switches being pressed, without checking for releases, despite the comments saying otherwise.

So, when a right switch is pressed, the code moves to the next sequence and checks for the next switch press. However, because the micro is far faster than a human can release the switch, that first switch is not yet released. The code then thinks that a wrong switch is pressed and jumps to fail routine.

To wait for a switch release, use this code:

btfsc PORTA, SWx
goto $ - 1 ; not released, check again
... ; released, do the next thing
 

thatoneguy

Joined Feb 19, 2009
6,359
Add debouncing, either in software or hardware. The uC is probably "Seeing" 4-4-4-3-3-2-2-2-1-1-1-1 when 4-3-2-1 are pressed.

Debouncing can be "x of y" sampling, where a variable is incremented each time through the loop and the switch is active. Every 10 "loops", variable is checked, and if > 8, the switch is debounced, variable is set to zero, and 'switch pressed' routine is called.

Don't use a long delay routine for debouncing, as they cause the processor to miss non-interrupt events, such as LCD updating, other keypresses, etc. This makes the end application "feel kludgy", even when the delays are 1mS (they add up).

Whenever you need a delay, build it into the "main loop". This uses two variables and a couple lines of code in the main loop. One variable as a counter, another as a "flag", or however it's easier to think of. When time needs to be spent, set the "flag", the rest of the code runs, and unless the desired delay is reached, the flag isn't reset. At the start of the procedure needing the delay, test the flag, and continue if true. Similar to ADC procedures.

The above is a bit difficult in assembly. The simplest would be a hardware RC network, 10k pullup and 0.1uF cap to ground, with the input where the R and C connect. This also gives the benefit of reducing interference if using wires rather than a PCB trace to connect the switches.
 

Thread Starter

David5093

Joined Apr 23, 2009
19
orry guys,
I spoke too soon when I said it was working.
Yeah, the sequence I want is 4-2-3-1 = Pass routine, anything else = Fail routine.
When I switch on and press buttons 1, 2 or 3 it goes to the fail routine which is what I want, however
when I press button 2 it automatically goes to Pass (for some reason) when i want it to wait for the
next input.
Any ideas?
The code below:

;==========================================================================
; Variable Definition
;==========================================================================
;INPUTS
SW1 EQU H'00' ;SW1 is triggering RA0
SW2 EQU H'01' ;SW2 is triggering RA1
SW3 EQU H'02' ;SW3 is triggering RA2
SW4 EQU H'03' ;SW4 is triggering RA3
TIMER1 EQU H'20' ;Used in delay routine
TIMER2 EQU H'21' ; " " "
PATERN EQU H'22' ;Pattern data for effect's

ORG 0 ;Reset vector address
GOTO RESET ;goto RESET routine when boot.

; *********************************************
; * Example of a delay routine *
; *********************************************
DELAY_ROUTINE MOVLW D'255'
MOVWF TIMER2
DEL_LOOP1 MOVLW D'255'
MOVWF TIMER1
DEL_LOOP2 DECFSZ TIMER1,F
GOTO DEL_LOOP2
DECFSZ TIMER2,F
GOTO DEL_LOOP1
RETLW 0

; **********************************
; ** RESET : main boot routine **
; **********************************
RESET MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU
;
MENU CLRF PORTB
;
BTFSC PORTA,SW1
GOTO FAILURE
BTFSC PORTA,SW2
GOTO FAILURE
BTFSC PORTA,SW3
GOTO FAILURE
BTFSC PORTA,SW4
GOTO SEQ_1
GOTO MENU
SEQ_1 BTFSC PORTA,SW2 ; Wait for Switch 2 to release
GOTO $-1 ; Not released, check again
GOTO SEQ_2 ; If so wait for Switch 3
BTFSC PORTA,SW1 ; If Switch 1 is pressed, Fail
GOTO $-1 ; Not released, check again
GOTO FAILURE
BTFSC PORTA,SW3 ; If Switch 3 is pressed, Fail
GOTO $-1 ; Not released, check again
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO $-1 ; Not released, check again
GOTO FAILURE
SEQ_2 BTFSC PORTA,SW3 ; Wait for switch 3 to release
GOTO $-1 ; Not released, check agin
GOTO SEQ_3 ; If so wait for Switch 1
BTFSC PORTA,SW1 ; If Switch 1 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE
BTFSC PORTA,SW2 ; If Switch 2 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE
SEQ_3 BTFSC PORTA,SW1 ; Wait for Switch 1 to release
GOTO $-1 ; Not released, check agin
GOTO PASS ; If so you have Passed
BTFSC PORTA,SW2 ; If Switch 2 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE
BTFSC PORTA,SW3 ; If Switch 3 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE
BTFSC PORTA,SW4 ; If Switch 4 is pressed, Fail
GOTO $-1 ; Not released, check agin
GOTO FAILURE

PASS MOVLW B'00100000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111111' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
GOTO PASS

FAILURE MOVLW 0x3F ; Moves (63 decimal, 111111 binary) into the W register
MOVWF PORTA ; Set all bits on
MOVWF PORTB ; LEDs on
NOP ; The 'nop' make up the time taken by the goto
NOP ; giving a square wave output
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
MOVLW 0x00 ; Moves (00 decimal, 000000 binary) into the W register
MOVWF PORTA ; Set all bits off
MOVWF PORTB ; LEDs off
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
GOTO FAILURE ; Repeat
END
 

thatoneguy

Joined Feb 19, 2009
6,359
This Part:

Rich (BB code):
SEQ_1  BTFSC PORTA,SW2 ; Wait for Switch 2 to release
  GOTO $-1  ; Not released, check again
  GOTO SEQ_2  ; If so wait for Switch 3
  BTFSC PORTA,SW1 ; If Switch 1 is pressed, Fail
Executes right after the First checks.

It should only run if a flag stating switch 2 has been pressed is set, otherwise it will trigger when it isn't pressed on every "loop".
 

Thread Starter

David5093

Joined Apr 23, 2009
19
I tried another way but still it doesn't work, any idea why?

;**************************************************************************
;* VELLEMAN High-Q KIT K8048/VM111 SAMPLE SOFTWARE *
;**************************************************************************
;* Microchip PIC(tm) Programmer & experiment board *
;* DEMO2 program for testing K8048 with PIC16F627(A)! *
;* Generate 4 LED light effects, you can select these with SW1..4 *
;**************************************************************************
;* (C) VELLEMAN Components,2003 All rights reserved *
;**************************************************************************
;* Hardw. Rev: P8048'1 Softw. Rev: 1.21 *
;* OSC.......: XT 4MHz Max. POWER.....: 12V DC *
;**************************************************************************
W EQU H'0000'
F EQU H'0001'
;----- Register Files------------------------------------------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
INTCON EQU H'000B'
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
CMCON EQU H'001F'
;----- STATUS Bits --------------------------------------------------------
IRP EQU H'0007'
RP1 EQU H'0006'
RP0 EQU H'0005'
NOT_TO EQU H'0004'
NOT_PD EQU H'0003'
Z EQU H'0002'
DC EQU H'0001'
C EQU H'0000'
;==========================================================================
;
; RAM Definition
;
;==========================================================================
__MAXRAM H'01FF'
__BADRAM H'07'-H'09', H'0D', H'13'-H'14', H'1B'-H'1E'
__BADRAM H'87'-H'89', H'8D', H'8F'-H'91', H'93'-H'97', H'9E'
__BADRAM H'105', H'107'-H'109', H'10C'-H'11F', H'150'-H'16F'
__BADRAM H'185', H'187'-H'189', H'18C'-H'1EF'
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
_BODEN_ON EQU H'3FFF'
_BODEN_OFF EQU H'3FBF'
_CP_ALL EQU H'03FF'
_CP_75 EQU H'17FF'
_CP_50 EQU H'2BFF'
_CP_OFF EQU H'3FFF'
_DATA_CP_ON EQU H'3EFF'
_DATA_CP_OFF EQU H'3FFF'
_PWRTE_OFF EQU H'3FFF'
_PWRTE_ON EQU H'3FF7'
_WDT_ON EQU H'3FFF'
_WDT_OFF EQU H'3FFB'
_LVP_ON EQU H'3FFF'
_LVP_OFF EQU H'3F7F'
_MCLRE_ON EQU H'3FFF'
_MCLRE_OFF EQU H'3FDF'
_ER_OSC_CLKOUT EQU H'3FFF'
_ER_OSC_NOCLKOUT EQU H'3FFE'
_INTRC_OSC_CLKOUT EQU H'3FFD'
_INTRC_OSC_NOCLKOUT EQU H'3FFC'
_EXTCLK_OSC EQU H'3FEF'
_LP_OSC EQU H'3FEC'
_XT_OSC EQU H'3FED'
_HS_OSC EQU H'3FEE'
__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC
;==========================================================================
; Variable Definition
;==========================================================================
;INPUTS
SW1 EQU H'00' ;SW1 is triggering RA0
SW2 EQU H'01' ;SW2 is triggering RA1
SW3 EQU H'02' ;SW3 is triggering RA2
SW4 EQU H'03' ;SW4 is triggering RA3
TIMER1 EQU H'20' ;Used in delay routine
TIMER2 EQU H'21' ; " " "
PATERN EQU H'22' ;Pattern data for effect's

ORG 0 ;Reset vector address
GOTO RESET ;goto RESET routine when boot.

; *********************************************
; * Example of a delay routine *
; *********************************************
DELAY_ROUTINE MOVLW D'255'
MOVWF TIMER2
DEL_LOOP1 MOVLW D'255'
MOVWF TIMER1
DEL_LOOP2 DECFSZ TIMER1,F
GOTO DEL_LOOP2
DECFSZ TIMER2,F
GOTO DEL_LOOP1
RETLW 0

; **********************************
; ** RESET : main boot routine **
; **********************************
RESET MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU
;
MENU CLRF PORTB
;
BTFSC PORTA,SW1
GOTO FAILURE
BTFSC PORTA,SW2
GOTO FAILURE
BTFSC PORTA,SW3
GOTO FAILURE
BTFSC PORTA,SW4
GOTO RESET_1
GOTO MENU
RESET_1 MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU_1
;
MENU_1 CLRF PORTB
;
BTFSC PORTA,SW1
GOTO FAILURE
BTFSC PORTA,SW2
GOTO RESET_2
BTFSC PORTA,SW3
GOTO FAILURE
BTFSC PORTA,SW4
GOTO FAILURE
GOTO MENU_1
RESET_2 MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU_2
;
MENU_2 CLRF PORTB
;
BTFSC PORTA,SW1
GOTO FAILURE
BTFSC PORTA,SW2
GOTO FAILURE
BTFSC PORTA,SW3
GOTO RESET_3
BTFSC PORTA,SW4
GOTO FAILURE
GOTO MENU_2

RESET_3 MOVLW B'00000111' ;Disable Comparator module's
MOVWF CMCON
;
BSF STATUS,RP0 ;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
MOVLW B'11010111' ;Set PIC options (See datasheet).
MOVWF OPTION_REG ;Write the OPTION register.
;
CLRF INTCON ;Disable interrupts
MOVLW B'11000000'
MOVWF TRISB ;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
MOVLW B'11111111' ;all RA ports are inputs
MOVWF TRISA
BCF STATUS,RP0 ;Switch Back to reg. Bank 0
CLRF PORTB
GOTO MENU_3
;

MENU_3 CLRF PORTB
;
BTFSC PORTA,SW1
GOTO PASS
BTFSC PORTA,SW2
GOTO FAILURE
BTFSC PORTA,SW3
GOTO FAILURE
BTFSC PORTA,SW4
GOTO FAILURE
GOTO MENU_3

PASS MOVLW B'00100000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111111' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111110' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111100' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00111000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
MOVLW B'00110000' ;
MOVWF PORTB
CALL DELAY_ROUTINE
GOTO PASS

FAILURE MOVLW 0x3F ; Moves (63 decimal, 111111 binary) into the W register
MOVWF PORTA ; Set all bits on
MOVWF PORTB ; LEDs on
NOP ; The 'nop' make up the time taken by the goto
NOP ; giving a square wave output
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
MOVLW 0x00 ; Moves (00 decimal, 000000 binary) into the W register
MOVWF PORTA ; Set all bits off
MOVWF PORTB ; LEDs off
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
CALL DELAY_ROUTINE
GOTO FAILURE ; Repeat
END
 

thatoneguy

Joined Feb 19, 2009
6,359
Sorry for absence. A "Flag" is simply a variable to test.

It can be a byte or a single bit, such as the STATUS register.

If you are tracking the state of 4 buttons, 2 bits would work, but you have the memory to simply use a byte.

If the variable is zero, it is waiting for the first keypress
If the variable is 1, the initial key was pressed, waiting for debounce, on continue, increment variable.
keys 2 and 3 do essentially the same as key 1
The 4th key performs the "Correct keys" function if correct, and sets the variable back to zero.
If any key is wrong, the variable is reset to zero as well.
 

gryskop

Joined Mar 1, 2008
26
Rich (BB code):
;************************************************* *************************
;* VELLEMAN High-Q KIT K8048/VM111 SAMPLE SOFTWARE *
;************************************************* *************************
;* Microchip PIC(tm) Programmer & experiment board *
;* DEMO2 program for testing K8048 with PIC16F627(A)! *
;* Generate 4 LED light effects, you can select these with SW1..4 *
;************************************************* *************************
;* (C) VELLEMAN Components,2003 All rights reserved *
;************************************************* *************************
;* Hardw. Rev: P8048'1 Softw. Rev: 1.21 *
;* OSC.......: XT 4MHz Max. POWER.....: 12V DC *
;************************************************* *************************
;
; -----> Making use of MPLAB IDE v8.x to run simulation
	radix	dec
	list p=16F627A
	include	"P16F627A.INC"
	ERRORLEVEL      -302
	ERRORLEVEL      -305


	__CONFIG _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC
;================================================= =========================
; Variable Definition
;================================================= =========================
;INPUTS
SW1		EQU	H'00' ;SW1 is triggering RA0
SW2		EQU	H'01' ;SW2 is triggering RA1
SW3		EQU	H'02' ;SW3 is triggering RA2
SW4		EQU	H'03' ;SW4 is triggering RA3
TIMER1		EQU	H'20' ;Used in delay routine
TIMER2		EQU	H'21' ; " " "
PATERN		EQU	H'22' ;Pattern data for effect's

		ORG	0 		;Reset vector address
		GOTO	RESET 		;goto RESET routine when boot.

; *********************************************
; * Example of a delay routine *
; *********************************************
DELAY_ROUTINE 	MOVLW	D'255'
		MOVWF	TIMER2
DEL_LOOP1	MOVLW	D'255'
		MOVWF	TIMER1
DEL_LOOP2	DECFSZ	TIMER1,F
		GOTO	DEL_LOOP2
		DECFSZ	TIMER2,F
		GOTO	DEL_LOOP1
		RETLW	0

; **********************************
; ** RESET : main boot routine **
; **********************************
RESET		MOVLW	B'00000111'		;Disable Comparator module's
		MOVWF	CMCON
		BSF	STATUS,RP0		;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
		MOVLW	B'11010111'		;Set PIC options (See datasheet).
		MOVWF	OPTION_REG		;Write the OPTION register.
		CLRF	INTCON			;Disable interrupts
		MOVLW	B'11000000'
		MOVWF	TRISB			;RB7 & RB6 are inputs.
;RB5...RB0 are outputs.
		MOVLW	B'11111111'		;all RA ports are inputs
		MOVWF	TRISA
		BCF	STATUS,RP0		;Switch Back to reg. Bank 0
		CLRF	PORTB
		GOTO	MENU
;
MENU		CLRF	PORTB
						; ----------------------->
		BTFSC	PORTA,SW1		; No allowance made for button debounce timer
		GOTO	FAILURE			; Simulating an input will work, but in real 
		BTFSC	PORTA,SW2		; life you will battle to pick up if a switch
		GOTO	FAILURE			; was pressed
		BTFSC	PORTA,SW3		;	
		GOTO	FAILURE			;
		BTFSC	PORTA,SW4		;
		GOTO	RESET_1			;
		GOTO	MENU
RESET_1		MOVLW	B'00000111' 		;Disable Comparator module's
		MOVWF	CMCON
;
		BSF	STATUS,RP0 		;Switch to register bank 1
;Disable pull-ups
;INT on rising edge
;TMR0 to CLKOUT
;TMR0 Incr low2high trans.
;Prescaler assign to Timer0
;Prescaler rate is 1:256
		MOVLW	B'11010111' 		;Set PIC options (See datasheet).
		MOVWF	OPTION_REG 		;Write the OPTION register.
		CLRF	INTCON 			;Disable interrupts
		MOVLW	B'11000000'
		MOVWF	TRISB 			;RB7 & RB6 are inputs.
						;RB5...RB0 are outputs.
		MOVLW	B'11111111' 		;all RA ports are inputs
		MOVWF	TRISA
		BCF	STATUS,RP0 		;Switch Back to reg. Bank 0
		CLRF	PORTB
		GOTO	MENU_1
;
MENU_1		CLRF	PORTB
;
		BTFSC	PORTA,SW1
		GOTO 	FAILURE
		BTFSC	PORTA,SW2
		GOTO	RESET_2
		BTFSC	PORTA,SW3
		GOTO	FAILURE
		BTFSC	PORTA,SW4
		GOTO	FAILURE
		GOTO	MENU_1
RESET_2		MOVLW 	B'00000111' 		;Disable Comparator module's
		MOVWF 	CMCON
						;
		BSF	STATUS,RP0 		;Switch to register bank 1
						;Disable pull-ups
						;INT on rising edge
						;TMR0 to CLKOUT
						;TMR0 Incr low2high trans.
						;Prescaler assign to Timer0
						;Prescaler rate is 1:256
		MOVLW	B'11010111' 		;Set PIC options (See datasheet).
		MOVWF	OPTION_REG 		;Write the OPTION register.
						;
		CLRF	INTCON 			;Disable interrupts
		MOVLW	B'11000000'
		MOVWF	TRISB 			;RB7 & RB6 are inputs.
						;RB5...RB0 are outputs.
		MOVLW	B'11111111' 		;all RA ports are inputs
		MOVWF	TRISA
		BCF	STATUS,RP0 		;Switch Back to reg. Bank 0
		CLRF	PORTB
		GOTO	MENU_2
						;
MENU_2		CLRF	PORTB
						;
		BTFSC	PORTA,SW1
		GOTO	FAILURE
		BTFSC	PORTA,SW2
		GOTO	FAILURE
		BTFSC	PORTA,SW3
		GOTO	RESET_3
		BTFSC	PORTA,SW4
		GOTO	FAILURE
		GOTO	MENU_2

RESET_3		MOVLW	B'00000111' 		;Disable Comparator module's
		MOVWF	CMCON
						;
		BSF	STATUS,RP0 		;Switch to register bank 1
						;Disable pull-ups
						;INT on rising edge
						;TMR0 to CLKOUT
						;TMR0 Incr low2high trans.
						;Prescaler assign to Timer0
						;Prescaler rate is 1:256
		MOVLW	B'11010111' 		;Set PIC options (See datasheet).
		MOVWF	OPTION_REG 		;Write the OPTION register.
						;
		CLRF	INTCON 			;Disable interrupts
		MOVLW	B'11000000'
		MOVWF	TRISB 			;RB7 & RB6 are inputs.
						;RB5...RB0 are outputs.
		MOVLW	B'11111111' 		;all RA ports are inputs
		MOVWF	TRISA
		BCF	STATUS,RP0 		;Switch Back to reg. Bank 0
		CLRF	PORTB
		GOTO	MENU_3
						;
MENU_3		CLRF	PORTB
						;
		BTFSC	PORTA,SW1
		GOTO	PASS
		BTFSC	PORTA,SW2
		GOTO	FAILURE
		BTFSC	PORTA,SW3
		GOTO	FAILURE
		BTFSC	PORTA,SW4
		GOTO	FAILURE
		GOTO	MENU_3

PASS		MOVLW	B'00100000' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00110000' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111000' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111100' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111110' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111111' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111110' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111100' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00111000' 		;
		MOVWF	PORTB
		CALL	DELAY_ROUTINE
		MOVLW	B'00110000' 		;
		MOVWF	PORTB	
		CALL	DELAY_ROUTINE
		GOTO	PASS

FAILURE 	MOVLW	0x3F 			; Moves (63 decimal, 111111 binary) into the W register
		MOVWF	PORTA 			; Set all bits on
		MOVWF	PORTB 			; LEDs on
		NOP 				; The 'nop' make up the time taken by the goto
		NOP 				; giving a square wave output
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		MOVLW	0x00 			; Moves (00 decimal, 000000 binary) into the W register
		MOVWF	PORTA 			; Set all bits off
		MOVWF	PORTB 			; LEDs off
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		CALL	DELAY_ROUTINE
		GOTO	FAILURE 		; Repeat
		END
What software package are you using for programming?

If you use MPLAB IDE, you can get rid of register, bit, ram and configuration declarations in the beginning of the code. Simply add the line

include "P16F627A.INC"

I don’t see any debounce routines for the switches. Read up some more on debounce, but a typical button debounce time is between 5ms to 20ms. When using software simulators the code will work, but in an actual real life application you might have trouble.

Why do you keep on repeating the port setup with all the RESET routines? Unless the ports change function (i.e. from input to output) during the run of the software you only need to set it once. Usually that should happen in the beginning, i.e. it should be the first routine to be called and then never again, until the next reset or power failure.

The way your code is written is that will forever loop in any of the MENU_x routines and once a button is pressed it will go to FAILURE and then it will stay there forever. Was this your intention?
 

Thread Starter

David5093

Joined Apr 23, 2009
19
No, my intention is for the program to goto the pass routine when the sequence 4-2-3-1 is pressed, any deviation from this then it goes to the fail routine.

The reason i repeated the reset function was because the program is waiting for an input when i first run it so by pressing 4 i thought it would wait again for another input before reacting and so on but it doesn't work.

Is debounce routine the way to go?
 

Thread Starter

David5093

Joined Apr 23, 2009
19
Been reading up on de-bouncing and tried to incorporate it into the program. My programming knowledge consits of cut and paste of different routines so not really sure what i'm doing. What I want is for the program to wait for a sequence of inputs from buttons (4,2,3,1) which if pressed will goto the Pass routine, any deviation from this then the program will run the Failure routine. This seems fairly straight forward to me but cannot seem to get it to work correctly. Can someone have a look at my latest try and see if there are any glaring errors as I have no idea.

I have attached the program as a text document as the formatting is messed up when i paste it

Regards

David
 

Attachments

Top