Hi all,
I am learning asembler. I am working with Microchip's PIC microcontrollers in particluar PIC16F877A.
My issue is that I have a program and using MSLIM. The program is simple however I cannot seem to get the stimulus to work. I wanted RD4 to go high but when I set the stimulus it does nothing.
The program is below.
The program just follows an indefinite loop until an interupt... but I cant seem to get stimulus to cause an interupt of infact to work...
Here is a video screen capture of it not working...
**broken link removed**
Hope you can help..
Simon
; LIST P=16F877A, F=INHX8M
; ERRORLEVEL 2
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC
;*****************************************************************************
;
;
; Program to read a standard 4x4 keyboard.
; Keypresses are detected on interrupt and
; debounced.
;
; Fosc = 4MHz
; Cycle_time = 1/Fosc / 4 = 1uSec
;*****************************************************************************
; CHANGE NEXT LINE TO REFLECT YOUR MPLAB SETUP
include <p16F877A.inc>
;*****************************************************************************
; Equates, I/O, vars
;*****************************************************************************
RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt Vector
OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4 MHz
; PORTB bits
RB7 EQU 7 ; Keyboard, COL 4
RB6 EQU 6 ; Keyboard, COL 3
RB5 EQU 5 ; Keyboard, COL 2
RB4 EQU 4 ; Keyboard, COL 1
; PORTD bits
RD7 EQU 7 ; Keyboard, ROW 1
RD6 EQU 6 ; Keyboard, ROW 2
RD5 EQU 5 ; Keyboard, ROW 3
RD4 EQU 4 ; Keyboard, ROW 4
RD3 EQU 3 ; Key code, bit 3, use 1k + LED to Vss
RD2 EQU 2 ; Key code, bit 2, use 1k + LED to Vss
RD1 EQU 1 ; Key code, bit 1, use 1k + LED to Vss
RD0 EQU 0 ; Key code, bit 0, use 1k + LED to Vss
;*****************************************************************************
; Equates, registers
;*****************************************************************************
cblock H'20'
TEMP ; Temp storage
LASTKEY ; Last key pressed
KEYCNT ; Copy of LASTKEY
; Misc.
DELAY ; Used in delay routines
X_DELAY ; "
COUNT ; Used as g.p. counter
_W ; TEMPORARY STORE FOR W
_STATUS ; TEMPORARY STORE FOR STATUS
endc
;*****************************************************************************
; Program start
;*****************************************************************************
ORG RESET_V ; RESET vector location
RESET GOTO START
;*****************************************************************************
; This is the Peripheral Interrupt routine.
;*****************************************************************************
ORG ISR_V ; Interrupt vector location
MOVWF _W
SWAPF STATUS,W
MOVWF _STATUS
BCF STATUS,RP0 ; Select bank 0
GOTO INTERRUPT
;*****************************************************************************
; Initialize processor registers
;*****************************************************************************
START ; POWER_ON Reset (Beginning of program)
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
CLRF PCLATH ; Keep in lower 2KByte
CLRF PORTA ; ALL PORT output should output Low.
CLRF PORTB ; ALL PORT output should output Low.
CLRF PORTC ; ALL PORT output should output Low.
CLRF PORTD ; ALL PORT output should output Low.
CLRF PORTE ; ALL PORT output should output Low.
BCF STATUS, RP1 ; For bank 1 RP1=0 RP0=1
BSF STATUS, RP0 ; Select bank 1
CLRF PORTB ;LATCH ALL LOW
MOVLW B'11110000' ;RB4-RB7 inputs
MOVWF TRISB
MOVLW B'00000000' ; RD0-3 as outputs RD4-7 inputs
MOVWF TRISD
BCF OPTION_REG, NOT_RBPU ;Enable weak pull-ups
;on port B
BCF STATUS, RP0 ; Select bank 0
BCF INTCON, INTF; Clear interrupt flag
BSF INTCON, RBIE; Enable interrupt on RB7-4 change
BSF INTCON, GIE ; Enable interrupts
;*****************************************************************************
; Wait for keypress
CALL FLASH ; Flash leds a few times
LOOP GOTO LOOP
;*****************************************************************************
; Program ends here.
; Routines follow.
;*****************************************************************************
; FLASH flash leds a few times
;*****************************************************************************
FLASH
MOVLW B'00001111'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00000000'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00001111'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00000000'
MOVWF PORTD
RETURN
;*****************************************************************************
; DISPLAY display key code on RA0,1,2,3
;*****************************************************************************
DISPLAY
MOVF LASTKEY, W
ANDLW 0x0F ; Make sure only 4 lower bits are valid
MOVWF PORTD
RETURN
;*****************************************************************************
; DONE Return from interrupt
;*****************************************************************************
DONE
BCF STATUS,RP0 ; Select bank 0
CLRF PORTB ; Clear port b
CLRF PORTD ; Clear port b
MOVF PORTB,F
SWAPF _STATUS,W ; Restore saved registers
MOVWF STATUS
SWAPF _W,F
SWAPF _W,W
BCF INTCON,RBIF ; CLEAR Port B interrupt FLAG
RETFIE
;*****************************************************************************
; INTERRUPT Service keyboard interrupt
;*****************************************************************************
INTERRUPT
BCF STATUS,RP0
MOVLW d'80'
CALL X_DELAY500 ; 80 * 0.5mS = 40mS
MOVLW B'11110000' ; CHECK FOR KEY DOWN
MOVWF TEMP
MOVF PORTB,W
SUBWF TEMP,F
BTFSC STATUS, Z
GOTO DONE ; ALL KEYS UP SO RETURN
CALL GETKEY ; KEY PRESSED NOW IN W (0 - 15)
MOVWF LASTKEY ; SAVE IT
CALL DISPLAY ; Display key code on RA0,1,2,3
GOTO DONE
;*****************************************************************************
;GETKEY ROUTINE THAT RETURNS WITH THE KEY PRESSED IN W. (0 to 15, 16 = NO KEY)
;*****************************************************************************
GETKEY
BTFSS PORTB, RB4
GOTO ROW1
BTFSS PORTB, RB5
GOTO ROW2
BTFSS PORTB, RB6
GOTO ROW3
BTFSS PORTB, RB7
GOTO ROW4
RETLW D'16'
ROW1 BSF PORTB, RB4
BTFSC PORTB, RD4
RETLW D'1' ;1
BSF PORTB, RB5
BTFSC PORTB, RD4
RETLW D'2' ;2
BSF PORTB, RB6
BTFSC PORTB, RD4
RETLW D'3' ;3
BSF PORTB, RB7
BTFSC PORTB, RD4
RETLW D'15' ;FNC
RETLW D'16'
ROW2 BSF PORTB, RB4
BTFSC PORTB, RD5
RETLW D'4' ;4
BSF PORTB, RB5
BTFSC PORTB, RD5
RETLW D'5' ;5
BSF PORTB, RB6
BTFSC PORTB, RD5
RETLW D'6' ;6
BSF PORTB, RB7
BTFSC PORTB, RD5
RETLW D'14' ;RCL
RETLW D'16'
ROW3 BSF PORTB, RB4
BTFSC PORTB, RD6
RETLW D'7' ;7
BSF PORTB, RB5
BTFSC PORTB, RD6
RETLW D'8' ;8
BSF PORTB, RB6
BTFSC PORTB, RD6
RETLW D'9' ;9
BSF PORTB, RB7
BTFSC PORTB, RD6
RETLW D'13' ;STO
RETLW D'16'
ROW4 BSF PORTB, RB4
BTFSC PORTB, RD7
RETLW D'11' ;CLR
BSF PORTB, RB5
BTFSC PORTB, RD7
RETLW D'0' ;0
BSF PORTB, RB6
BTFSC PORTB, RD7
RETLW D'10' ;DOT
BSF PORTB, RB7
BTFSC PORTB, RD7
RETLW D'12' ;ENT
RETLW D'16'
;*****************************************************************************
; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; i.e. (@ 4MHz crystal)
; Delay_time = ((32 * 3) + 4) * 1uSec
; = 100uSec
; DELAY_value = (500uSec - 4) / 3
; = 165.33
; = 165
;*****************************************************************************
DELAY500 MOVLW D'165' ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
DELAY500_END RETURN ; +3 2 cycles
;
;
X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
X_DELAY500_END RETURN ; +2 2 cycles
;*****************************************************************************
;*****************************************************************************
SECWAIT MOVLW D'20' ; 20 times 15 = 300 msec
MOVWF COUNT
SECLOOP MOVLW 0x01E ; 15 msec
CALL X_DELAY500
DECFSZ COUNT, F
GOTO SECLOOP
SECLOOPEND RETURN
END
I am learning asembler. I am working with Microchip's PIC microcontrollers in particluar PIC16F877A.
My issue is that I have a program and using MSLIM. The program is simple however I cannot seem to get the stimulus to work. I wanted RD4 to go high but when I set the stimulus it does nothing.
The program is below.
The program just follows an indefinite loop until an interupt... but I cant seem to get stimulus to cause an interupt of infact to work...
Here is a video screen capture of it not working...
**broken link removed**
Hope you can help..
Simon
; LIST P=16F877A, F=INHX8M
; ERRORLEVEL 2
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC
;*****************************************************************************
;
;
; Program to read a standard 4x4 keyboard.
; Keypresses are detected on interrupt and
; debounced.
;
; Fosc = 4MHz
; Cycle_time = 1/Fosc / 4 = 1uSec
;*****************************************************************************
; CHANGE NEXT LINE TO REFLECT YOUR MPLAB SETUP
include <p16F877A.inc>
;*****************************************************************************
; Equates, I/O, vars
;*****************************************************************************
RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt Vector
OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4 MHz
; PORTB bits
RB7 EQU 7 ; Keyboard, COL 4
RB6 EQU 6 ; Keyboard, COL 3
RB5 EQU 5 ; Keyboard, COL 2
RB4 EQU 4 ; Keyboard, COL 1
; PORTD bits
RD7 EQU 7 ; Keyboard, ROW 1
RD6 EQU 6 ; Keyboard, ROW 2
RD5 EQU 5 ; Keyboard, ROW 3
RD4 EQU 4 ; Keyboard, ROW 4
RD3 EQU 3 ; Key code, bit 3, use 1k + LED to Vss
RD2 EQU 2 ; Key code, bit 2, use 1k + LED to Vss
RD1 EQU 1 ; Key code, bit 1, use 1k + LED to Vss
RD0 EQU 0 ; Key code, bit 0, use 1k + LED to Vss
;*****************************************************************************
; Equates, registers
;*****************************************************************************
cblock H'20'
TEMP ; Temp storage
LASTKEY ; Last key pressed
KEYCNT ; Copy of LASTKEY
; Misc.
DELAY ; Used in delay routines
X_DELAY ; "
COUNT ; Used as g.p. counter
_W ; TEMPORARY STORE FOR W
_STATUS ; TEMPORARY STORE FOR STATUS
endc
;*****************************************************************************
; Program start
;*****************************************************************************
ORG RESET_V ; RESET vector location
RESET GOTO START
;*****************************************************************************
; This is the Peripheral Interrupt routine.
;*****************************************************************************
ORG ISR_V ; Interrupt vector location
MOVWF _W
SWAPF STATUS,W
MOVWF _STATUS
BCF STATUS,RP0 ; Select bank 0
GOTO INTERRUPT
;*****************************************************************************
; Initialize processor registers
;*****************************************************************************
START ; POWER_ON Reset (Beginning of program)
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
CLRF PCLATH ; Keep in lower 2KByte
CLRF PORTA ; ALL PORT output should output Low.
CLRF PORTB ; ALL PORT output should output Low.
CLRF PORTC ; ALL PORT output should output Low.
CLRF PORTD ; ALL PORT output should output Low.
CLRF PORTE ; ALL PORT output should output Low.
BCF STATUS, RP1 ; For bank 1 RP1=0 RP0=1
BSF STATUS, RP0 ; Select bank 1
CLRF PORTB ;LATCH ALL LOW
MOVLW B'11110000' ;RB4-RB7 inputs
MOVWF TRISB
MOVLW B'00000000' ; RD0-3 as outputs RD4-7 inputs
MOVWF TRISD
BCF OPTION_REG, NOT_RBPU ;Enable weak pull-ups
;on port B
BCF STATUS, RP0 ; Select bank 0
BCF INTCON, INTF; Clear interrupt flag
BSF INTCON, RBIE; Enable interrupt on RB7-4 change
BSF INTCON, GIE ; Enable interrupts
;*****************************************************************************
; Wait for keypress
CALL FLASH ; Flash leds a few times
LOOP GOTO LOOP
;*****************************************************************************
; Program ends here.
; Routines follow.
;*****************************************************************************
; FLASH flash leds a few times
;*****************************************************************************
FLASH
MOVLW B'00001111'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00000000'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00001111'
MOVWF PORTD
CALL SECWAIT
CALL SECWAIT
MOVLW B'00000000'
MOVWF PORTD
RETURN
;*****************************************************************************
; DISPLAY display key code on RA0,1,2,3
;*****************************************************************************
DISPLAY
MOVF LASTKEY, W
ANDLW 0x0F ; Make sure only 4 lower bits are valid
MOVWF PORTD
RETURN
;*****************************************************************************
; DONE Return from interrupt
;*****************************************************************************
DONE
BCF STATUS,RP0 ; Select bank 0
CLRF PORTB ; Clear port b
CLRF PORTD ; Clear port b
MOVF PORTB,F
SWAPF _STATUS,W ; Restore saved registers
MOVWF STATUS
SWAPF _W,F
SWAPF _W,W
BCF INTCON,RBIF ; CLEAR Port B interrupt FLAG
RETFIE
;*****************************************************************************
; INTERRUPT Service keyboard interrupt
;*****************************************************************************
INTERRUPT
BCF STATUS,RP0
MOVLW d'80'
CALL X_DELAY500 ; 80 * 0.5mS = 40mS
MOVLW B'11110000' ; CHECK FOR KEY DOWN
MOVWF TEMP
MOVF PORTB,W
SUBWF TEMP,F
BTFSC STATUS, Z
GOTO DONE ; ALL KEYS UP SO RETURN
CALL GETKEY ; KEY PRESSED NOW IN W (0 - 15)
MOVWF LASTKEY ; SAVE IT
CALL DISPLAY ; Display key code on RA0,1,2,3
GOTO DONE
;*****************************************************************************
;GETKEY ROUTINE THAT RETURNS WITH THE KEY PRESSED IN W. (0 to 15, 16 = NO KEY)
;*****************************************************************************
GETKEY
BTFSS PORTB, RB4
GOTO ROW1
BTFSS PORTB, RB5
GOTO ROW2
BTFSS PORTB, RB6
GOTO ROW3
BTFSS PORTB, RB7
GOTO ROW4
RETLW D'16'
ROW1 BSF PORTB, RB4
BTFSC PORTB, RD4
RETLW D'1' ;1
BSF PORTB, RB5
BTFSC PORTB, RD4
RETLW D'2' ;2
BSF PORTB, RB6
BTFSC PORTB, RD4
RETLW D'3' ;3
BSF PORTB, RB7
BTFSC PORTB, RD4
RETLW D'15' ;FNC
RETLW D'16'
ROW2 BSF PORTB, RB4
BTFSC PORTB, RD5
RETLW D'4' ;4
BSF PORTB, RB5
BTFSC PORTB, RD5
RETLW D'5' ;5
BSF PORTB, RB6
BTFSC PORTB, RD5
RETLW D'6' ;6
BSF PORTB, RB7
BTFSC PORTB, RD5
RETLW D'14' ;RCL
RETLW D'16'
ROW3 BSF PORTB, RB4
BTFSC PORTB, RD6
RETLW D'7' ;7
BSF PORTB, RB5
BTFSC PORTB, RD6
RETLW D'8' ;8
BSF PORTB, RB6
BTFSC PORTB, RD6
RETLW D'9' ;9
BSF PORTB, RB7
BTFSC PORTB, RD6
RETLW D'13' ;STO
RETLW D'16'
ROW4 BSF PORTB, RB4
BTFSC PORTB, RD7
RETLW D'11' ;CLR
BSF PORTB, RB5
BTFSC PORTB, RD7
RETLW D'0' ;0
BSF PORTB, RB6
BTFSC PORTB, RD7
RETLW D'10' ;DOT
BSF PORTB, RB7
BTFSC PORTB, RD7
RETLW D'12' ;ENT
RETLW D'16'
;*****************************************************************************
; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; i.e. (@ 4MHz crystal)
; Delay_time = ((32 * 3) + 4) * 1uSec
; = 100uSec
; DELAY_value = (500uSec - 4) / 3
; = 165.33
; = 165
;*****************************************************************************
DELAY500 MOVLW D'165' ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
DELAY500_END RETURN ; +3 2 cycles
;
;
X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
X_DELAY500_END RETURN ; +2 2 cycles
;*****************************************************************************
;*****************************************************************************
SECWAIT MOVLW D'20' ; 20 times 15 = 300 msec
MOVWF COUNT
SECLOOP MOVLW 0x01E ; 15 msec
CALL X_DELAY500
DECFSZ COUNT, F
GOTO SECLOOP
SECLOOPEND RETURN
END