Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

4x4 Keypad Interrupt on Change PORTB

Status
Not open for further replies.
I have a simple program... LCD, Keypad blah blah blah.

Im programming a pic to controll an ISD voice recorder chip.

I had it all working with no interrupts.
Comunication with the ISD chip via SPI no probs.

Now I want to put the keypad in an interrupt. Interrupt on PORTB change.

I've been trying for a few hours now and werid stuff keeps happening.

I get the right display at power-up on the LCD.
But nothin happens with my keypad when I press buttons.

Can anyone see anything obvious???

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     ISD 4002 Programmer                                          ;
;                                   Author: Jake Sutherland                                        ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        list            p=pic16f72
        include         "P16F72.INC"
       __config _BOREN_OFF & _CP_OFF & _PWRTEN_ON & _WDTEN_OFF & _WDT_OFF & _XT_OSC
       errorlevel      -302    ;Eliminate bank warning

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     PIC16F72 Microcontroller                                     ;
;                                            ____ ____                                             ;
;                                     MCLR -|    -    |- RB7  Keypad Column 1   I                  ;
;                    O     ISD4002 SS  RA0 -|         |- RB6  Keypad Column 2   I                  ;
;                    O    ISD4002 CLK  RA1 -|         |- RB5  Keypad Column 3   I                  ;
;                    O   ISD4002 MOSI  RA2 -|         |- RB4  Keypad Column 4   I                  ;
;                    I   ISD4002 MISO  RA3 -|         |- RB3  Keypad Row 1      O                  ;
;                    O        LCD R/S  RA4 -|         |- RB2  Keypad Row 2      O                  ;
;                    O          LCD E  RA5 -|         |- RB1  Keypad Row 3      O                  ;
;                                      VSS -|         |- RB0  Keypad Row 4      O                  ;
;                                     OSC1 -|         |- VDD                                       ;
;                                     OSC2 -|         |- VSS                                       ;
;                    O      LCD bit 0  RC0 -|         |- RC7  LCD bit 7         O                  ;
;                    O      LCD bit 1  RC1 -|         |- RC6  LCD bit 6         O                  ;
;                    O      LCD bit 2  RC2 -|         |- RC5  LCD bit 5         O                  ;
;                    O      LCD bit 3  RC3 -|_________|- RC4  LCD bit 4         O                  ;
;                                                                                                  ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Set EQU vales and registers
CBLOCK  0x20
GPR1    ; Countdown Reg
GPR2    ; For storing command codes
GPR3    ; Countdown Reg
GPR4    ; Countdown Reg
DELAYGPR1
DELAYGPR2
ENDC

; PORTA bits
SS      EQU     0
CLK     EQU     1
MOSI    EQU     2
MISO    EQU     3
RS      EQU     4
E       EQU     5

; PORTB bits
COL1    EQU     7
COL2    EQU     6
COL3    EQU     5
COL4    EQU     4
ROW1    EQU     3
ROW2    EQU     2
ROW3    EQU     1
ROW4    EQU     0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        ORG     0x00                ; Program starts at 0x00
        GOTO    START

        ORG     0x04                ; Interupt vector jumps here
        GOTO    ISR


; Interrupt Sevice Routine
ISR
        BCF     INTCON, GIE
; KEYPAD ROUTINES
; This routine scans the keypad for a button press
        BCF     PORTB,3
        BTFSS   PORTB, COL1         ; Scan COL 1
        CALL    BTN_POWERUP         ;
        BTFSS   PORTB, COL2         ; Scan COL 2
        CALL    BTN_STOP            ;
        BTFSS   PORTB, COL3         ; Scan COL 3
        CALL    BTN_STOPPOWERDOWN   ;
        BTFSS   PORTB, COL4         ; Scan COL 4
        CALL    BTN_READADDRESS     ;

        BSF     PORTB,3
        BCF     PORTB,2
        BTFSS   PORTB, COL1         ;
        CALL    BTN_PLAY            ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETPLAY         ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_SS              ;
        BTFSS   PORTB, COL4         ;
        CALL    BTN_ADDRESSINC      ;

        BSF     PORTB,2
        BCF     PORTB,1
        BTFSS   PORTB, COL1         ;
        CALL    BTN_RECORD          ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETRECORD       ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_CLK             ;
        BTFSS   PORTB, COL4         ;
        CALL    BTN_ADDRESSDEC      ;

        BSF     PORTB,1
        BCF     PORTB,0
        BTFSS   PORTB, COL1         ;
        CALL    BTN_MESSAGECUE      ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETMESSAGECUE   ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_MOSI            ;
        BTFSS   PORTB, COL4         ;
        GOTO    $+1                 ;
        CALL    DELAY_250mS

        BCF     INTCON, RBIF
        RETFIE

MAIN_PROGRAM
        CALL    INITIALISE_LCD
        CALL    CLEAR_DISPLAY       ; Clear Display
        CALL    MOVE_CURSOR_04      ; Move Cursor to Position 5 on Line 1
        CALL    TYPE_ISD4002        ; TYPE_ISD4002
        CALL    MOVE_CURSOR_43      ; Move Cursor to Position 4 on Line 2
        CALL    TYPE_PROGRAMMER     ; TYPE_PROGRAMMER
here
        BSF     INTCON, GIE
        BSF     INTCON, PEIE
        BSF     INTCON, RBIE
        BCF     OPTION_REG, NOT_RBPU
        BCF     INTCON, RBIF

        SLEEP
        NOP
        goto here


;        MOVLW   B'00000000'         ; OPTION_REG OPTION REGISTER CONTROL BYTE
;                                    ; <7> RBPU Enable week pull-ups
;                                    ; <6> INTEDG Interrupt on falling edge of INT pin
;                                    ; <5> Internal instruction cycle clock
;                                    ; <4> Increment on low-to-high transistion on T0CKI pin
;                                    ; <3> PSA Prescaler is assigned to the Timer0 module
;                                    ; <2:0> PS2:PS0 Prescaler set to 1:2
;        MOVWF   OPTION_REG
;
;        MOVLW   B'10001000'         ; INTCON INTTERRUPT CONTROL BYTE
;                                    ; <7> GIE Enable all interrupts
;                                    ; <6> PEIE Disable all peripherl interrupts
;                                    ; <5> T0IE Disable the TMR0 overflow interrupt
;                                    ; <4> INTE Disable the INT external interrupt
;                                    ; <3> RBIE Enable the RB port change interrupt
;                                    ; <2> T0IF Interrupt FLAG BIT
;                                    ; <1> INTF Interrupt FLAG BIT
;                                    ; <0> RBIF Interrupt FLAG BIT
;        MOVWF   INTCON





CHARATER_TABLE ; This routine holds all the words needed for the LCD display
       ADDWF   PCL,F
                               ;BAFGEDCx
       RETLW   A'I' ; 0
       RETLW   A'S' ; 1
       RETLW   A'D' ; 2
       RETLW   A' ' ; 3
       RETLW   A'4' ; 4
       RETLW   A'0' ; 5
       RETLW   A'0' ; 6
       RETLW   A'2' ; 7
       RETLW   A'P' ; 8
       RETLW   A'R' ; 9
       RETLW   A'O' ; 10
       RETLW   A'G' ; 11
       RETLW   A'R' ; 12
       RETLW   A'A' ; 13
       RETLW   A'M' ; 14
       RETLW   A'M' ; 15
       RETLW   A'E' ; 16
       RETLW   A'R' ; 17

       RETURN

START
SETIO  ; This rountine sets up the chips Inputs and Outputs
        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        CLRF    PORTA               ; Initialize PORTA by clearing output data latches
        CLRF    PORTB               ; Initialize PORTB by clearing output data latches
        CLRF    PORTC               ; Initialize PORTC by clearing output data latches
        BSF     STATUS,RP0          ; Bank 1
        BCF     STATUS,RP1          ; Bank 1
        MOVLW   0x06                ; Configure all pins
        MOVWF   ADCON1              ; as digital inputs
        MOVLW   B'00001000'         ; Value used to initialize data direction
        MOVWF   TRISA               ; Set RA<1:0> as outputs
                                    ; RA<3> as inputs
                                    ; RA<5:4> as outputs
                                    ; TRISA<7:6> are always
                                    ; read as ‘0’.

        MOVLW   B'11110000'         ; Value used to initialize data direction
        MOVWF   TRISB               ; Set RB<7:4> as outputs
                                    ; RB<3:0> as inputs

        MOVLW   B'00000000'         ; Value used to initialize data direction
        MOVWF   TRISC               ; Set RC<7:0> as outputs

        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        GOTO    MAIN_PROGRAM


; LCD ROUTINES
INITIALISE_LCD  ; This routine initialises the LCD so that it is ready to display charaters
        BSF     PORTA, E            ; Set E line
        BCF     PORTA, RS           ; LCD in Command mode
        CALL    DELAY_1mS

        MOVLW   B'00111000'         ; Command: 8-Bit Mode, 2 Line, 5x7 Dot Matrix
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS

        MOVLW   B'00001100'         ; Command: Display On, Cursor Underline Off, Blink Off
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        RETURN

TOGGLE_E  ; This routine is called when a command/charater is ready to be entered into the LCD
        BCF     PORTA, E
        CALL    DELAY_1mS
        BSF     PORTA, E
        RETURN

CLEAR_DISPLAY
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'00000001'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_04
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'10000100'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_43
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'11000011'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

TYPE_ISD4002  ; Word for LCD (ISD4002)
        MOVLW   D'0'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'7'                ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_PROGRAMMER  ; Word for LCD (PROGRAMMER)
        MOVLW   D'8'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'17'               ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_IT  ; This routine is for displaying charaters on the LCD. This routine is called only after data has been stored in the 2 countdown registers
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        CALL    CHARATER_TABLE      ; Call 'CHARATER_TABLE' to get charater
        MOVWF   PORTC               ; Move Working Register (which will have the ascii character stored in it) to PORTC
        CALL    TOGGLE_E            ; Enter into LCD
        CALL    DELAY_1mS           ; Wait
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        XORWF   GPR3,W              ; XOR the Table Line Number we are currently at with the finish Table Line Number we previously set (The 'XORWF' intruction affects the 'Zero' bit or the Status Register)
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+3                 ; If the test returns a 'zero', the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        INCF    GPR1                ; If the test does not return a 'zero', (meaning we have not reached the LAST Table Line Number we previously set), we do it again and print the next charater
        GOTO    TYPE_IT             ; Do it again after INC insruction (the INCrement is so we print the NEXT charater in the table)
        RETURN




; ISD4002 ChipCorder Commands
BTN_POWERUP  ; This routine sends a Power Up command to the ISD4002
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'00100'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_PLAY
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'11110'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_RECORD
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01101'            ; Move 'Record code' into Working Register
        GOTO    ENTERCOMMAND


BTN_MESSAGECUE
        SLEEP


BTN_STOP
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01100'            ; Move 'Stop' into Working Register
        GOTO    ENTERCOMMAND


BTN_SETPLAY
        SLEEP


BTN_SETRECORD
        SLEEP


BTN_SETMESSAGECUE
        SLEEP


BTN_STOPPOWERDOWN
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01000'            ; Move 'Stop Power Down' into Working Register
        GOTO    ENTERCOMMAND


BTN_SS
        BSF     PORTA,SS            ; Set Slave Select Line
        BCF     PORTA,SS            ; Clear Slave Select Line
        RETURN


BTN_CLK
        BSF     PORTA, CLK          ; Set Clock Line
        BCF     PORTA, CLK          ; Clear Clock Line
        RETURN


BTN_MOSI
        BTFSC   PORTA, MOSI         ;
        GOTO    $+3                 ;
        BSF     PORTA, MOSI         ; } This routine is simply to invert the MOSI Line
        GOTO    $+2                 ;
        BCF     PORTA, MOSI         ;
        RETURN


BTN_READADDRESS
        RETURN


BTN_ADDRESSINC
        RETURN


BTN_ADDRESSDEC
        RETURN



ENTERCOMMAND  ; This routine is to clock the data into the ISD4002
        MOVWF   GPR2                ; Move Working Register to General Purpose Register
AGAIN   BTFSS   GPR2, 0             ; Test bit 1 of GPR
        GOTO    $+2                 ; If Clear, goto here + 2
        GOTO    $+3                 ; If Set, goto here + 3
        BCF     PORTA, MOSI         ;
        GOTO    $+2                 ;
        BSF     PORTA, MOSI         ;

        BSF     PORTA, CLK          ;
        BCF     PORTA, CLK          ;

        RRF     GPR2                ;

        DECF    GPR1,F              ; Decrease Count Reg, Put value back into Count Reg (The 'DECF' intruction affects the 'Zero' bit or the Status Register
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+2                 ; If out Count Reg has reached Zero, the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        GOTO    AGAIN               ; Count Reg has not reached Zero, So we do it again

        BSF     PORTA,SS            ;
        BCF     PORTA,SS            ;
        RETURN





; DELAY ROUTINES
; Actual delay = 0.001 seconds = 1000 cycles
DELAY_1mS
        MOVLW    0xC6                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0x01                ;
        MOVWF    DELAYGPR2           ;
DELAY_1mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_1mS_0         ; 993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)


; Actual delay = 0.25 seconds = 250000 cycles
DELAY_250mS
        MOVLW    0x4E                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0xC4                ;
        MOVWF    DELAYGPR2           ;
DELAY_250mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_250mS_0         ; 249993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)

STOP    GOTO    STOP
END
 
You're not turning on the week pullups as the OPTION register is in bank 1.

Edit, you're also not saving the registers in your ISR which will cause all kinds of crashes.

Mike.
 
Last edited:
Oh yes.
ok I changed that line of code so it exectutes while in bank 1.
It is in the SETIO routine

But still, nothing happens when i press a key

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     ISD 4002 Programmer                                          ;
;                                   Author: Jake Sutherland                                        ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        list            p=pic16f72
        include         "P16F72.INC"
       __config _BOREN_OFF & _CP_OFF & _PWRTEN_ON & _WDTEN_OFF & _WDT_OFF & _XT_OSC
       errorlevel      -302    ;Eliminate bank warning

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     PIC16F72 Microcontroller                                     ;
;                                            ____ ____                                             ;
;                                     MCLR -|    -    |- RB7  Keypad Column 1   I                  ;
;                    O     ISD4002 SS  RA0 -|         |- RB6  Keypad Column 2   I                  ;
;                    O    ISD4002 CLK  RA1 -|         |- RB5  Keypad Column 3   I                  ;
;                    O   ISD4002 MOSI  RA2 -|         |- RB4  Keypad Column 4   I                  ;
;                    I   ISD4002 MISO  RA3 -|         |- RB3  Keypad Row 1      O                  ;
;                    O        LCD R/S  RA4 -|         |- RB2  Keypad Row 2      O                  ;
;                    O          LCD E  RA5 -|         |- RB1  Keypad Row 3      O                  ;
;                                      VSS -|         |- RB0  Keypad Row 4      O                  ;
;                                     OSC1 -|         |- VDD                                       ;
;                                     OSC2 -|         |- VSS                                       ;
;                    O      LCD bit 0  RC0 -|         |- RC7  LCD bit 7         O                  ;
;                    O      LCD bit 1  RC1 -|         |- RC6  LCD bit 6         O                  ;
;                    O      LCD bit 2  RC2 -|         |- RC5  LCD bit 5         O                  ;
;                    O      LCD bit 3  RC3 -|_________|- RC4  LCD bit 4         O                  ;
;                                                                                                  ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Set EQU vales and registers
CBLOCK  0x20
GPR1    ; Countdown Reg
GPR2    ; For storing command codes
GPR3    ; Countdown Reg
GPR4    ; Countdown Reg
DELAYGPR1
DELAYGPR2
ENDC

; PORTA bits
SS      EQU     0
CLK     EQU     1
MOSI    EQU     2
MISO    EQU     3
RS      EQU     4
E       EQU     5

; PORTB bits
COL1    EQU     7
COL2    EQU     6
COL3    EQU     5
COL4    EQU     4
ROW1    EQU     3
ROW2    EQU     2
ROW3    EQU     1
ROW4    EQU     0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        ORG     0x00                ; Program starts at 0x00
        GOTO    START

        ORG     0x04                ; Interupt vector jumps here
        GOTO    ISR


; Interrupt Sevice Routine
ISR
        BCF     INTCON, GIE
; KEYPAD ROUTINES
; This routine scans the keypad for a button press
        BCF     PORTB,3
        BTFSS   PORTB, COL1         ; Scan COL 1
        CALL    BTN_POWERUP         ;
        BTFSS   PORTB, COL2         ; Scan COL 2
        CALL    BTN_STOP            ;
        BTFSS   PORTB, COL3         ; Scan COL 3
        CALL    BTN_STOPPOWERDOWN   ;
        BTFSS   PORTB, COL4         ; Scan COL 4
        CALL    BTN_READADDRESS     ;

        BSF     PORTB,3
        BCF     PORTB,2
        BTFSS   PORTB, COL1         ;
        CALL    BTN_PLAY            ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETPLAY         ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_SS              ;
        BTFSS   PORTB, COL4         ;
        CALL    BTN_ADDRESSINC      ;

        BSF     PORTB,2
        BCF     PORTB,1
        BTFSS   PORTB, COL1         ;
        CALL    BTN_RECORD          ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETRECORD       ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_CLK             ;
        BTFSS   PORTB, COL4         ;
        CALL    BTN_ADDRESSDEC      ;

        BSF     PORTB,1
        BCF     PORTB,0
        BTFSS   PORTB, COL1         ;
        CALL    BTN_MESSAGECUE      ;
        BTFSS   PORTB, COL2         ;
        CALL    BTN_SETMESSAGECUE   ;
        BTFSS   PORTB, COL3         ;
        CALL    BTN_MOSI            ;
        BTFSS   PORTB, COL4         ;
        GOTO    $+1                 ;
        CALL    DELAY_250mS

        BCF     INTCON, RBIF
        RETFIE

MAIN_PROGRAM
        CALL    INITIALISE_LCD
        CALL    CLEAR_DISPLAY       ; Clear Display
        CALL    MOVE_CURSOR_04      ; Move Cursor to Position 5 on Line 1
        CALL    TYPE_ISD4002        ; TYPE_ISD4002
        CALL    MOVE_CURSOR_43      ; Move Cursor to Position 4 on Line 2
        CALL    TYPE_PROGRAMMER     ; TYPE_PROGRAMMER
here
        BSF     INTCON, GIE
        BSF     INTCON, PEIE
        BSF     INTCON, RBIE
        BCF     INTCON, RBIF

        SLEEP
        NOP
        goto here


;        MOVLW   B'00000000'         ; OPTION_REG OPTION REGISTER CONTROL BYTE
;                                    ; <7> RBPU Enable week pull-ups
;                                    ; <6> INTEDG Interrupt on falling edge of INT pin
;                                    ; <5> Internal instruction cycle clock
;                                    ; <4> Increment on low-to-high transistion on T0CKI pin
;                                    ; <3> PSA Prescaler is assigned to the Timer0 module
;                                    ; <2:0> PS2:PS0 Prescaler set to 1:2
;        MOVWF   OPTION_REG
;
;        MOVLW   B'10001000'         ; INTCON INTTERRUPT CONTROL BYTE
;                                    ; <7> GIE Enable all interrupts
;                                    ; <6> PEIE Disable all peripherl interrupts
;                                    ; <5> T0IE Disable the TMR0 overflow interrupt
;                                    ; <4> INTE Disable the INT external interrupt
;                                    ; <3> RBIE Enable the RB port change interrupt
;                                    ; <2> T0IF Interrupt FLAG BIT
;                                    ; <1> INTF Interrupt FLAG BIT
;                                    ; <0> RBIF Interrupt FLAG BIT
;        MOVWF   INTCON





CHARATER_TABLE ; This routine holds all the words needed for the LCD display
       ADDWF   PCL,F
                               ;BAFGEDCx
       RETLW   A'I' ; 0
       RETLW   A'S' ; 1
       RETLW   A'D' ; 2
       RETLW   A' ' ; 3
       RETLW   A'4' ; 4
       RETLW   A'0' ; 5
       RETLW   A'0' ; 6
       RETLW   A'2' ; 7
       RETLW   A'P' ; 8
       RETLW   A'R' ; 9
       RETLW   A'O' ; 10
       RETLW   A'G' ; 11
       RETLW   A'R' ; 12
       RETLW   A'A' ; 13
       RETLW   A'M' ; 14
       RETLW   A'M' ; 15
       RETLW   A'E' ; 16
       RETLW   A'R' ; 17

       RETURN

START
SETIO  ; This rountine sets up the chips Inputs and Outputs
        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        CLRF    PORTA               ; Initialize PORTA by clearing output data latches
        CLRF    PORTB               ; Initialize PORTB by clearing output data latches
        CLRF    PORTC               ; Initialize PORTC by clearing output data latches
        BSF     STATUS,RP0          ; Bank 1
        BCF     STATUS,RP1          ; Bank 1
        MOVLW   0x06                ; Configure all pins
        MOVWF   ADCON1              ; as digital inputs
        MOVLW   B'00001000'         ; Value used to initialize data direction
        MOVWF   TRISA               ; Set RA<1:0> as outputs
                                    ; RA<3> as inputs
                                    ; RA<5:4> as outputs
                                    ; TRISA<7:6> are always
                                    ; read as ‘0’.

        MOVLW   B'11110000'         ; Value used to initialize data direction
        MOVWF   TRISB               ; Set RB<7:4> as outputs
                                    ; RB<3:0> as inputs

        MOVLW   B'00000000'         ; Value used to initialize data direction
        MOVWF   TRISC               ; Set RC<7:0> as outputs

        BCF     OPTION_REG, NOT_RBPU

        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        GOTO    MAIN_PROGRAM


; LCD ROUTINES
INITIALISE_LCD  ; This routine initialises the LCD so that it is ready to display charaters
        BSF     PORTA, E            ; Set E line
        BCF     PORTA, RS           ; LCD in Command mode
        CALL    DELAY_1mS

        MOVLW   B'00111000'         ; Command: 8-Bit Mode, 2 Line, 5x7 Dot Matrix
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS

        MOVLW   B'00001100'         ; Command: Display On, Cursor Underline Off, Blink Off
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        RETURN

TOGGLE_E  ; This routine is called when a command/charater is ready to be entered into the LCD
        BCF     PORTA, E
        CALL    DELAY_1mS
        BSF     PORTA, E
        RETURN

CLEAR_DISPLAY
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'00000001'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_04
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'10000100'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_43
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'11000011'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

TYPE_ISD4002  ; Word for LCD (ISD4002)
        MOVLW   D'0'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'7'                ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_PROGRAMMER  ; Word for LCD (PROGRAMMER)
        MOVLW   D'8'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'17'               ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_IT  ; This routine is for displaying charaters on the LCD. This routine is called only after data has been stored in the 2 countdown registers
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        CALL    CHARATER_TABLE      ; Call 'CHARATER_TABLE' to get charater
        MOVWF   PORTC               ; Move Working Register (which will have the ascii character stored in it) to PORTC
        CALL    TOGGLE_E            ; Enter into LCD
        CALL    DELAY_1mS           ; Wait
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        XORWF   GPR3,W              ; XOR the Table Line Number we are currently at with the finish Table Line Number we previously set (The 'XORWF' intruction affects the 'Zero' bit or the Status Register)
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+3                 ; If the test returns a 'zero', the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        INCF    GPR1                ; If the test does not return a 'zero', (meaning we have not reached the LAST Table Line Number we previously set), we do it again and print the next charater
        GOTO    TYPE_IT             ; Do it again after INC insruction (the INCrement is so we print the NEXT charater in the table)
        RETURN




; ISD4002 ChipCorder Commands
BTN_POWERUP  ; This routine sends a Power Up command to the ISD4002
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'00100'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_PLAY
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'11110'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_RECORD
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01101'            ; Move 'Record code' into Working Register
        GOTO    ENTERCOMMAND


BTN_MESSAGECUE
        SLEEP


BTN_STOP
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01100'            ; Move 'Stop' into Working Register
        GOTO    ENTERCOMMAND


BTN_SETPLAY
        SLEEP


BTN_SETRECORD
        SLEEP


BTN_SETMESSAGECUE
        SLEEP


BTN_STOPPOWERDOWN
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01000'            ; Move 'Stop Power Down' into Working Register
        GOTO    ENTERCOMMAND


BTN_SS
        BSF     PORTA,SS            ; Set Slave Select Line
        BCF     PORTA,SS            ; Clear Slave Select Line
        RETURN


BTN_CLK
        BSF     PORTA, CLK          ; Set Clock Line
        BCF     PORTA, CLK          ; Clear Clock Line
        RETURN


BTN_MOSI
        BTFSC   PORTA, MOSI         ;
        GOTO    $+3                 ;
        BSF     PORTA, MOSI         ; } This routine is simply to invert the MOSI Line
        GOTO    $+2                 ;
        BCF     PORTA, MOSI         ;
        RETURN


BTN_READADDRESS
        RETURN


BTN_ADDRESSINC
        RETURN


BTN_ADDRESSDEC
        RETURN



ENTERCOMMAND  ; This routine is to clock the data into the ISD4002
        MOVWF   GPR2                ; Move Working Register to General Purpose Register
AGAIN   BTFSS   GPR2, 0             ; Test bit 1 of GPR
        GOTO    $+2                 ; If Clear, goto here + 2
        GOTO    $+3                 ; If Set, goto here + 3
        BCF     PORTA, MOSI         ;
        GOTO    $+2                 ;
        BSF     PORTA, MOSI         ;

        BSF     PORTA, CLK          ;
        BCF     PORTA, CLK          ;

        RRF     GPR2                ;

        DECF    GPR1,F              ; Decrease Count Reg, Put value back into Count Reg (The 'DECF' intruction affects the 'Zero' bit or the Status Register
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+2                 ; If out Count Reg has reached Zero, the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        GOTO    AGAIN               ; Count Reg has not reached Zero, So we do it again

        BSF     PORTA,SS            ;
        BCF     PORTA,SS            ;
        RETURN





; DELAY ROUTINES
; Actual delay = 0.001 seconds = 1000 cycles
DELAY_1mS
        MOVLW    0xC6                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0x01                ;
        MOVWF    DELAYGPR2           ;
DELAY_1mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_1mS_0         ; 993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)


; Actual delay = 0.25 seconds = 250000 cycles
DELAY_250mS
        MOVLW    0x4E                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0xC4                ;
        MOVWF    DELAYGPR2           ;
DELAY_250mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_250mS_0         ; 249993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)

STOP    GOTO    STOP
END
 
You need to save the registers in your ISR. See section 11.12 of the data sheet.

Mike.
 
Whoa, just looked at your code a bit more and you are calling all sorts of things from the ISR, some of which sleep. You ISR should just work out which key is pressed and put it in a variable and your main code should do the calling of functions etc.

Mike.
 
Last edited:
I think i should go to bed!
I'm overlooking way too many simple things.

I will have a go at it all in the morning. Hopefully I have a more successful day.

Thanks again Mike.
 
well, i added the save register bits to the ISR.
and i removed the calls from the ISR and placed them in the main code.

but still nothing happens when i press a key.

Im convinced its not the hardware.

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;     
;                                     ISD 4002 Programmer                                          ;
;                                   Author: Jake Sutherland                                        ;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        list            p=pic16f72
        include         "P16F72.INC"
       __config _BOREN_OFF & _CP_OFF & _PWRTEN_ON & _WDTEN_OFF & _WDT_OFF & _XT_OSC
       errorlevel      -302    ;Eliminate bank warning

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     PIC16F72 Microcontroller                                     ;
;                                            ____ ____                                             ;
;                                     MCLR -|    -    |- RB7  Keypad Column 1   I                  ;
;                    O     ISD4002 SS  RA0 -|         |- RB6  Keypad Column 2   I                  ;
;                    O    ISD4002 CLK  RA1 -|         |- RB5  Keypad Column 3   I                  ;
;                    O   ISD4002 MOSI  RA2 -|         |- RB4  Keypad Column 4   I                  ;
;                    I   ISD4002 MISO  RA3 -|         |- RB3  Keypad Row 1      O                  ;
;                    O        LCD R/S  RA4 -|         |- RB2  Keypad Row 2      O                  ;
;                    O          LCD E  RA5 -|         |- RB1  Keypad Row 3      O                  ;
;                                      VSS -|         |- RB0  Keypad Row 4      O                  ;
;                                     OSC1 -|         |- VDD                                       ;
;                                     OSC2 -|         |- VSS                                       ;
;                    O      LCD bit 0  RC0 -|         |- RC7  LCD bit 7         O                  ;
;                    O      LCD bit 1  RC1 -|         |- RC6  LCD bit 6         O                  ;
;                    O      LCD bit 2  RC2 -|         |- RC5  LCD bit 5         O                  ;
;                    O      LCD bit 3  RC3 -|_________|- RC4  LCD bit 4         O                  ;
;                                                                                                  ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Set EQU vales and registers
CBLOCK  0x20
GPR1    ; Countdown Reg
GPR2    ; For storing command codes
GPR3    ; Countdown Reg
GPR4    ; Countdown Reg
DELAYGPR1
DELAYGPR2
W_TEMP
STATUS_TEMP
KEYSTORE
ENDC

; PORTA bits
SS      EQU     0
CLK     EQU     1
MOSI    EQU     2
MISO    EQU     3
RS      EQU     4
E       EQU     5

; PORTB bits
COL1    EQU     7
COL2    EQU     6
COL3    EQU     5
COL4    EQU     4
ROW1    EQU     3
ROW2    EQU     2
ROW3    EQU     1
ROW4    EQU     0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        ORG     0x00                ; Program starts at 0x00
        GOTO    START

        ORG     0x04                ; Interupt vector jumps here
        GOTO    ISR


; Interrupt Sevice Routine
ISR
        BCF     INTCON, GIE

        MOVWF   W_TEMP
        SWAPF   STATUS, W
        CLRF    STATUS
        MOVWF   STATUS_TEMP
; KEYPAD ROUTINES
; This routine scans the keypad for a button press
        BCF     PORTB,3
        BTFSS   PORTB, COL1         ; Scan COL 1
        MOVLW   D'1'                ;    BTN_POWERUP
        BTFSS   PORTB, COL2         ; Scan COL 2
        MOVLW   D'2'                ;    BTN_STOP            ;
        BTFSS   PORTB, COL3         ; Scan COL 3
        MOVLW   D'3'                ;    BTN_STOPPOWERDOWN   ;
        BTFSS   PORTB, COL4         ; Scan COL 4
        MOVLW   D'4'                ;    BTN_READADDRESS     ;

        BSF     PORTB,3
        BCF     PORTB,2
        BTFSS   PORTB, COL1         ;
        MOVLW   D'5'                ;    BTN_PLAY            ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'6'                ;    BTN_SETPLAY         ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'7'                ;    BTN_SS              ;
        BTFSS   PORTB, COL4         ;
        MOVLW   D'8'                ;    BTN_ADDRESSINC      ;

        BSF     PORTB,2
        BCF     PORTB,1
        BTFSS   PORTB, COL1         ;
        MOVLW   D'9'                ;    BTN_RECORD          ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'10'               ;    BTN_SETRECORD       ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'11'               ;    BTN_CLK             ;
        BTFSS   PORTB, COL4         ;
        MOVLW   D'12'               ;    BTN_ADDRESSDEC      ;

        BSF     PORTB,1
        BCF     PORTB,0
        BTFSS   PORTB, COL1         ;
        MOVLW   D'13'               ;    BTN_MESSAGECUE      ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'14'               ;    BTN_SETMESSAGECUE   ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'15'               ;    BTN_MOSI            ;
        BTFSS   PORTB, COL4         ;
        GOTO    $+1                 ;
        MOVWF   KEYSTORE
        CALL    DELAY_250mS

        BCF     INTCON, RBIF

        SWAPF   STATUS_TEMP, W
        MOVWF   STATUS
        SWAPF   W_TEMP, F
        SWAPF   W_TEMP, W
        RETFIE

MAIN_PROGRAM
        CALL    INITIALISE_LCD
        CALL    CLEAR_DISPLAY       ; Clear Display
        CALL    MOVE_CURSOR_04      ; Move Cursor to Position 5 on Line 1
        CALL    TYPE_ISD4002        ; TYPE_ISD4002
        CALL    MOVE_CURSOR_43      ; Move Cursor to Position 4 on Line 2
        CALL    TYPE_PROGRAMMER     ; TYPE_PROGRAMMER
here
        BSF     INTCON, GIE
        BSF     INTCON, PEIE
        BSF     INTCON, RBIE
        BCF     INTCON, RBIF

        SLEEP
        NOP

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_POWERUP         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_STOP         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_STOPPOWERDOWN         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_READADDRESS         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_PLAY         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_SETPLAY         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_SS         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_ADDRESSINC         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_RECORD         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_SETRECORD         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_CLK         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_ADDRESSDEC         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_MESSAGECUE         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_SETMESSAGECUE         ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    BTN_MOSI         ;


        goto here



CHARATER_TABLE ; This routine holds all the words needed for the LCD display
       ADDWF   PCL,F
                               ;BAFGEDCx
       RETLW   A'I' ; 0
       RETLW   A'S' ; 1
       RETLW   A'D' ; 2
       RETLW   A' ' ; 3
       RETLW   A'4' ; 4
       RETLW   A'0' ; 5
       RETLW   A'0' ; 6
       RETLW   A'2' ; 7
       RETLW   A'P' ; 8
       RETLW   A'R' ; 9
       RETLW   A'O' ; 10
       RETLW   A'G' ; 11
       RETLW   A'R' ; 12
       RETLW   A'A' ; 13
       RETLW   A'M' ; 14
       RETLW   A'M' ; 15
       RETLW   A'E' ; 16
       RETLW   A'R' ; 17

       RETURN

START
SETIO  ; This rountine sets up the chips Inputs and Outputs
        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        CLRF    PORTA               ; Initialize PORTA by clearing output data latches
        CLRF    PORTB               ; Initialize PORTB by clearing output data latches
        CLRF    PORTC               ; Initialize PORTC by clearing output data latches
        BSF     STATUS,RP0          ; Bank 1
        BCF     STATUS,RP1          ; Bank 1
        MOVLW   0x06                ; Configure all pins
        MOVWF   ADCON1              ; as digital inputs
        MOVLW   B'00001000'         ; Value used to initialize data direction
        MOVWF   TRISA               ; Set RA<1:0> as outputs
                                    ; RA<3> as inputs
                                    ; RA<5:4> as outputs
                                    ; TRISA<7:6> are always
                                    ; read as ‘0’.

        MOVLW   B'11110000'         ; Value used to initialize data direction
        MOVWF   TRISB               ; Set RB<7:4> as outputs
                                    ; RB<3:0> as inputs

        MOVLW   B'00000000'         ; Value used to initialize data direction
        MOVWF   TRISC               ; Set RC<7:0> as outputs

        BCF     OPTION_REG, NOT_RBPU

        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        GOTO    MAIN_PROGRAM


; LCD ROUTINES
INITIALISE_LCD  ; This routine initialises the LCD so that it is ready to display charaters
        BSF     PORTA, E            ; Set E line
        BCF     PORTA, RS           ; LCD in Command mode
        CALL    DELAY_1mS

        MOVLW   B'00111000'         ; Command: 8-Bit Mode, 2 Line, 5x7 Dot Matrix
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS

        MOVLW   B'00001100'         ; Command: Display On, Cursor Underline Off, Blink Off
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        RETURN

TOGGLE_E  ; This routine is called when a command/charater is ready to be entered into the LCD
        BCF     PORTA, E
        CALL    DELAY_1mS
        BSF     PORTA, E
        RETURN

CLEAR_DISPLAY
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'00000001'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_04
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'10000100'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

MOVE_CURSOR_43
        BCF     PORTA, RS           ; LCD in Command mode
        MOVLW   B'11000011'         ; Command: Clear Display
        MOVWF   PORTC               ; Move Working Register to PORTC
        CALL    TOGGLE_E            ; Enter
        CALL    DELAY_1mS
        BSF     PORTA, RS           ; LCD in Character mode
        RETURN

TYPE_ISD4002  ; Word for LCD (ISD4002)
        MOVLW   D'0'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'7'                ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_PROGRAMMER  ; Word for LCD (PROGRAMMER)
        MOVLW   D'8'                ; Table Line to start printing from
        MOVWF   GPR1                ; Move Working Register to General Purpose Register
        MOVLW   D'17'               ; Table Line to finish printing at
        MOVWF   GPR3                ; Move Working Register to General Purpose Register
        CALL    TYPE_IT             ; Call 'TYPE_IT' routine to display word on LCD (ISD4002)
        RETURN

TYPE_IT  ; This routine is for displaying charaters on the LCD. This routine is called only after data has been stored in the 2 countdown registers
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        CALL    CHARATER_TABLE      ; Call 'CHARATER_TABLE' to get charater
        MOVWF   PORTC               ; Move Working Register (which will have the ascii character stored in it) to PORTC
        CALL    TOGGLE_E            ; Enter into LCD
        CALL    DELAY_1mS           ; Wait
        MOVF    GPR1,W              ; Move GPR1 to the Working Register. This number will be the line number of the table we will start printing from
        XORWF   GPR3,W              ; XOR the Table Line Number we are currently at with the finish Table Line Number we previously set (The 'XORWF' intruction affects the 'Zero' bit or the Status Register)
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+3                 ; If the test returns a 'zero', the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        INCF    GPR1                ; If the test does not return a 'zero', (meaning we have not reached the LAST Table Line Number we previously set), we do it again and print the next charater
        GOTO    TYPE_IT             ; Do it again after INC insruction (the INCrement is so we print the NEXT charater in the table)
        RETURN




; ISD4002 ChipCorder Commands
BTN_POWERUP  ; This routine sends a Power Up command to the ISD4002
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'00100'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_PLAY
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'11110'            ; Move 'Power Up code' into Working Register
        GOTO    ENTERCOMMAND


BTN_RECORD
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01101'            ; Move 'Record code' into Working Register
        GOTO    ENTERCOMMAND


BTN_MESSAGECUE
        SLEEP


BTN_STOP
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01100'            ; Move 'Stop' into Working Register
        GOTO    ENTERCOMMAND


BTN_SETPLAY
        SLEEP


BTN_SETRECORD
        SLEEP


BTN_SETMESSAGECUE
        SLEEP


BTN_STOPPOWERDOWN
        MOVLW   0x05                ; Move '5' into Working Register
        MOVWF   GPR1                ; Move Working Register to Countdown Register
        MOVLW   B'01000'            ; Move 'Stop Power Down' into Working Register
        GOTO    ENTERCOMMAND


BTN_SS
        BSF     PORTA,SS            ; Set Slave Select Line
        BCF     PORTA,SS            ; Clear Slave Select Line
        RETURN


BTN_CLK
        BSF     PORTA, CLK          ; Set Clock Line
        BCF     PORTA, CLK          ; Clear Clock Line
        RETURN


BTN_MOSI
        BTFSC   PORTA, MOSI         ;
        GOTO    $+3                 ;
        BSF     PORTA, MOSI         ; } This routine is simply to invert the MOSI Line
        GOTO    $+2                 ;
        BCF     PORTA, MOSI         ;
        RETURN


BTN_READADDRESS
        RETURN


BTN_ADDRESSINC
        RETURN


BTN_ADDRESSDEC
        RETURN



ENTERCOMMAND  ; This routine is to clock the data into the ISD4002
        MOVWF   GPR2                ; Move Working Register to General Purpose Register
AGAIN   BTFSS   GPR2, 0             ; Test bit 1 of GPR
        GOTO    $+2                 ; If Clear, goto here + 2
        GOTO    $+3                 ; If Set, goto here + 3
        BCF     PORTA, MOSI         ;
        GOTO    $+2                 ;
        BSF     PORTA, MOSI         ;

        BSF     PORTA, CLK          ;
        BCF     PORTA, CLK          ;

        RRF     GPR2                ;

        DECF    GPR1,F              ; Decrease Count Reg, Put value back into Count Reg (The 'DECF' intruction affects the 'Zero' bit or the Status Register
        BTFSC   STATUS, Z           ; Test 'Zero' bit of Status Register
        GOTO    $+2                 ; If out Count Reg has reached Zero, the routine has been exectuted the right amount of times, The 'Zero' bit of the Status Register will be 1 if we have decreased to zero. So, we are done.
        GOTO    AGAIN               ; Count Reg has not reached Zero, So we do it again

        BSF     PORTA,SS            ;
        BCF     PORTA,SS            ;
        RETURN





; DELAY ROUTINES
; Actual delay = 0.001 seconds = 1000 cycles
DELAY_1mS
        MOVLW    0xC6                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0x01                ;
        MOVWF    DELAYGPR2           ;
DELAY_1mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_1mS_0         ; 993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)


; Actual delay = 0.25 seconds = 250000 cycles
DELAY_250mS
        MOVLW    0x4E                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0xC4                ;
        MOVWF    DELAYGPR2           ;
DELAY_250mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_250mS_0         ; 249993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)

STOP    GOTO    STOP
END
 
Can you check if the interrupt is being called? Set a breakpoint or something.

I notice that you don't set all rows high at the beginning of your key scan and set them low again after. Also, a 1/4 second delay in an ISR is not good, for debounce 50mS is more than enough.

Mike.
 
Can you check if the interrupt is being called? Set a breakpoint or something.

I notice that you don't set all rows high at the beginning of your key scan and set them low again after. Also, a 1/4 second delay in an ISR is not good, for debounce 50mS is more than enough.

Mike.

hi Mike,
Oshonsoft sim shows ISR not being called by key actions,,, in the original program as listed...

EDIT:
as Osoft dosnt 'like' SLEEP' this was temp remmed out.

Special notes:
- Watchdog Timer is not simulated (CLRWDT instruction is executed as
NOP)
- Power-down Mode is not simulated (SLEEP instruction will stop the
simulation)
 
Last edited:
Eric,

Can you try the latest code? The first code didn't have pullups turned on and so wouldn't work.

Mike.
 
hi Mike,
Tried the latest code.
On running, the ISR is called, if no button has been pressed I get a 'stack underflow' error, in this area.

Code:
BTN_SS
        BSF     PORTA,SS            ; Set Slave Select Line
        BCF     PORTA,SS            ; Clear Slave Select Line
        RETURN


BTN_CLK
        BSF     PORTA, CLK          ; Set Clock Line
        BCF     PORTA, CLK          ; Clear Clock Line
        RETURN

If I have a button pressed after the first ISR call,[with a key down] it never is called again on a key press.
 
hi,
One detail which I would change is this 'ISR save' reg allocation, to 0x7f, 0x7e.. for W_TEMP & STATUS_TEMP

Code:
CBLOCK  0x20
GPR1    ; Countdown Reg
GPR2    ; For storing command codes
GPR3    ; Countdown Reg
GPR4    ; Countdown Reg
DELAYGPR1
DELAYGPR2
W_TEMP;;;;;;;;;;;;;;;;;;;;;;;;;;
STATUS_TEMP;;;;;;;;;;;;;;;;;;
KEYSTORE
ENDC
 
Yes, they should be in the shared area. I don't have time now to check the code but the stack underflow is due to using goto to routines which use return.

Mike.
 
Try getting it to work without sleep first...
Secondly I don't like how main isnt at the top as well as the set up, makes us run around too much when looking for mistakes..
 
thanks eric
BTN_SS
BSF PORTA,SS ; Set Slave Select Line
BCF PORTA,SS ; Clear Slave Select Line
SLEEP


BTN_CLK
BSF PORTA, CLK ; Set Clock Line
BCF PORTA, CLK ; Clear Clock Line
SLEEP

I changed all returns to sleeps where that routine is exectuted from a goto (not a call)


also I changed the W_TEMP & STATUS_TEMP locations so they are accessable from any bank.
That shouldn't have been a problem though because the program is only in bank 1 while setting the IO and never goes back.
But I do agree it a good habit to get into!:
; Set EQU vales and registers
CBLOCK 0x20
GPR1 ; Countdown Reg
GPR2 ; For storing command codes
GPR3 ; Countdown Reg
GPR4 ; Countdown Reg
DELAYGPR1
DELAYGPR2
KEYSTORE
ENDC

W_TEMP EQU 0X7F
STATUS_TEMP EQU 0X7E
 
Last edited:
I cant try and gett a whole program working when there is so much **** to sort through in the code.

I am making a (hopefully) simple program with only the keypad and an LED

I want to try and just get the Keypad ISR working and know its working first. Then I will build from there.
Which is probably what i should have done first.

Give me 5 minutes to make a new program out of what i've got.
 
Ok, I've cut the program back to only the things needed.

What I want this program to do is:

All upper 8 keys of the keypad should turn the LED on, and all Lower 8 keys on the keypad should turn the LED off.

I ran the program, and the LED comes on like it should at the start of the program, but still, nothing happens when i press a key.

Here it is:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     ISD 4002 Programmer                                          ;
;                                   Author: Jake Sutherland                                        ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        list            p=pic16f72
        include         "P16F72.INC"
       __config _BOREN_OFF & _CP_OFF & _PWRTEN_ON & _WDTEN_OFF & _WDT_OFF & _XT_OSC
       errorlevel      -302    ;Eliminate bank warning

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                                                  ;
;                                     PIC16F72 Microcontroller                                     ;
;                                            ____ ____                                             ;
;                                     MCLR -|    -    |- RB7  Keypad Column 1   I                  ;
;                    O                 RA0 -|         |- RB6  Keypad Column 2   I                  ;
;                    O                 RA1 -|         |- RB5  Keypad Column 3   I                  ;
;                    O       LED       RA2 -|         |- RB4  Keypad Column 4   I                  ;
;                    I                 RA3 -|         |- RB3  Keypad Row 1      O                  ;
;                    O                 RA4 -|         |- RB2  Keypad Row 2      O                  ;
;                    O                 RA5 -|         |- RB1  Keypad Row 3      O                  ;
;                                      VSS -|         |- RB0  Keypad Row 4      O                  ;
;                                     OSC1 -|         |- VDD                                       ;
;                                     OSC2 -|         |- VSS                                       ;
;                    O                 RC0 -|         |- RC7                    O                  ;
;                    O                 RC1 -|         |- RC6                    O                  ;
;                    O                 RC2 -|         |- RC5                    O                  ;
;                    O                 RC3 -|_________|- RC4                    O                  ;
;                                                                                                  ;
;                                                                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Set EQU vales and registers
CBLOCK  0x20
GPR1    ; Countdown Reg
GPR2    ; For storing command codes
GPR3    ; Countdown Reg
GPR4    ; Countdown Reg
DELAYGPR1
DELAYGPR2
KEYSTORE
ENDC

W_TEMP      EQU 0X7F
STATUS_TEMP EQU 0X7E

; PORTB bits
COL1    EQU     7
COL2    EQU     6
COL3    EQU     5
COL4    EQU     4
ROW1    EQU     3
ROW2    EQU     2
ROW3    EQU     1
ROW4    EQU     0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        ORG     0x00                ; Program starts at 0x00
        GOTO    START

        ORG     0x04                ; Interupt vector jumps here
        GOTO    ISR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START
SETIO  ; This rountine sets up the chips Inputs and Outputs
        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0
        CLRF    PORTA               ; Initialize PORTA by clearing output data latches
        CLRF    PORTB               ; Initialize PORTB by clearing output data latches
        CLRF    PORTC               ; Initialize PORTC by clearing output data latches
        BSF     STATUS,RP0          ; Bank 1
        BCF     STATUS,RP1          ; Bank 1
        MOVLW   0x06                ; Configure all pins
        MOVWF   ADCON1              ; as digital inputs
        MOVLW   B'00001000'         ; Value used to initialize data direction
        MOVWF   TRISA               ; Set RA<1:0> as outputs
                                    ; RA<3> as inputs
                                    ; RA<5:4> as outputs
                                    ; TRISA<7:6> are always
                                    ; read as ‘0’.

        MOVLW   B'11110000'         ; Value used to initialize data direction
        MOVWF   TRISB               ; Set RB<7:4> as outputs
                                    ; RB<3:0> as inputs

        MOVLW   B'00000000'         ; Value used to initialize data direction
        MOVWF   TRISC               ; Set RC<7:0> as outputs

        BCF     OPTION_REG, NOT_RBPU; Set PORTB weak pull-ups on

        BCF     STATUS,RP0          ; Bank 0
        BCF     STATUS,RP1          ; Bank 0

        MOVLW   D'1'                ; This is so when the program goes to MAIN_PROGRAM the LED goes on, then to SLEEP
        MOVWF   KEYSTORE            ;

        GOTO    MAIN_PROGRAM

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Interrupt Sevice Routine
ISR
        BCF     INTCON, GIE

        MOVWF   W_TEMP
        SWAPF   STATUS, W
        CLRF    STATUS
        MOVWF   STATUS_TEMP
; KEYPAD ROUTINES
; This routine scans the keypad for a button press
        MOVLW   B'0000'
        MOVWF   PORTB

        BTFSS   PORTB, COL1         ; Scan COL 1
        MOVLW   D'1'                ;    BTN_POWERUP
        BTFSS   PORTB, COL2         ; Scan COL 2
        MOVLW   D'2'                ;    BTN_STOP            ;
        BTFSS   PORTB, COL3         ; Scan COL 3
        MOVLW   D'3'                ;    BTN_STOPPOWERDOWN   ;
        BTFSS   PORTB, COL4         ; Scan COL 4
        MOVLW   D'4'                ;    BTN_READADDRESS     ;

        BTFSS   PORTB, COL1         ;
        MOVLW   D'5'                ;    BTN_PLAY            ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'6'                ;    BTN_SETPLAY         ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'7'                ;    BTN_SS              ;
        BTFSS   PORTB, COL4         ;
        MOVLW   D'8'                ;    BTN_ADDRESSINC      ;

        BTFSS   PORTB, COL1         ;
        MOVLW   D'9'                ;    BTN_RECORD          ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'10'               ;    BTN_SETRECORD       ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'11'               ;    BTN_CLK             ;
        BTFSS   PORTB, COL4         ;
        MOVLW   D'12'               ;    BTN_ADDRESSDEC      ;

        BTFSS   PORTB, COL1         ;
        MOVLW   D'13'               ;    BTN_MESSAGECUE      ;
        BTFSS   PORTB, COL2         ;
        MOVLW   D'14'               ;    BTN_SETMESSAGECUE   ;
        BTFSS   PORTB, COL3         ;
        MOVLW   D'15'               ;    BTN_MOSI            ;
        BTFSS   PORTB, COL4         ;
        MOVLW   D'16'               ;
        MOVWF   KEYSTORE
        CALL    DELAY_50mS

        BCF     INTCON, RBIF

        SWAPF   STATUS_TEMP, W
        MOVWF   STATUS
        SWAPF   W_TEMP, F
        SWAPF   W_TEMP, W
        RETFIE

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MAIN_PROGRAM

        BSF     INTCON, GIE
        BSF     INTCON, PEIE
        BSF     INTCON, RBIE
        BCF     INTCON, RBIF


        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON   ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_ON              ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        DECF    KEYSTORE, F         ;
        BTFSC   STATUS, Z           ;
        GOTO    LED_OFF             ;

        GOTO    MAIN_PROGRAM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LED_ON
        BSF     PORTA, 2
        SLEEP
        NOP
        GOTO    LED_ON

LED_OFF
        BCF     PORTA, 2
        SLEEP
        NOP
        GOTO    LED_OFF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; DELAY ROUTINES
; Actual delay = 0.001 seconds = 1000 cycles
DELAY_1mS
        MOVLW    0xC6                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0x01                ;
        MOVWF    DELAYGPR2           ;
DELAY_1mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_1mS_0         ; 993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)


; Actual delay = 0.05 seconds = 50000 cycles
DELAY_50mS
        MOVLW    0x0E                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0x28                ;
        MOVWF    DELAYGPR2           ;
DELAY_50mS_0                         ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO    $+2                  ;
        DECFSZ  DELAYGPR2, f         ;
        GOTO    DELAY_50mS_0         ; 49993 cycles
        GOTO    $+1                  ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)


; Actual delay = 0.25 seconds = 250000 cycles
DELAY_250mS
        MOVLW    0x4E                ;
        MOVWF    DELAYGPR1           ;
        MOVLW    0xC4                ;
        MOVWF    DELAYGPR2           ;
DELAY_250mS_0                          ;
        DECFSZ   DELAYGPR1, f        ;
        GOTO     $+2                 ;
        DECFSZ   DELAYGPR2, f        ;
        GOTO     DELAY_250mS_0         ; 249993 cycles
        GOTO     $+1                 ;
        NOP                          ; 3 cycles
        RETURN                       ; 4 cycles (including call)

STOP    GOTO    STOP
END
 
hi jakes,
Copied the code will run it thru the Oshonsoft sim today, let you know how it goes [ or not]
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top