Assembly language help for PIC16F887

Thread Starter

zhengkoon8

Joined Nov 28, 2011
10
Below is the language for my code. but i unable to on the led. so anyone can help me to solve this problem? thanks





Rich (BB code):
#include "prologue.inc"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Declaring Variable used
     cblock     0x20
Value                                    ; Assign an address 0x20 to label Value
Read                                     ; Assign an address 0x21 to label Read
Value1                                   ; Assign an address 0x22 to label Value1
Read1                                    ; Assign an address 0x23 to label Read1
Counter                                  ; Assign an address 0x27 to label Counter
Time                               ; Assign an address 0x27 to label TimerValue
     endc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialisation
Start:
     bsf       STATUS,RP0                ; select Register Bank 1
     clrf      TRISD                     ; Make PortD all output
     movlw     0x01                      ; Bit one to work register
     movlw     0xFF                      ; b'11111111'
     movwf     TRISA                     ; Make PortA all input
     movwf     TRISB                     ; Make RBO pin input (switch)
     bsf       STATUS,RP1                ; select Register Bank 3
     movlw     0x00                      ; move b'00000000' to work register
     movwf     ANSELH                    ; PortB pins are digitial (important as RB0 is switch)
     bcf       STATUS,RP0                ; select Register Bank 2
     bcf       STATUS,RP1                ; select Register Bank 0
     clrf      PORTD                     ; clear value in PORTD
     clrf      Counter                   ; clear value in Counter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MainLoop:
FirstValue:
     incf      Counter                   ; increase counter value
     btfsc     PORTB,0                   ; test whether switch is press
     goto      FirstValue                ; switch not press go back to the beginning of FirstValue
     movf      Counter,w                 ; move value in counter to work register
     movwf     Value                     ; move value in work register to Value register
     movf      Value,w                   ; move value in Value to work register
     movwf     PORTD                     ; move value in work register to PORTD register
     movf      PORTD,w                   ; move value in PORTD to work register
     movwf     Value                     ; move value in work register to Value register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x00                      ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
SecondValue:
     incf      Counter                   ; increase counter value
     btfsc     PORTB,0                   ; test whether switch is press
     goto      SecondValue               ; switch not press go back to the beginning of SecondValue
     movf      Counter,w                 ; move value in counter to work register
     movwf     Read                      ; move value in work register to Read register
     movf      Read,w                    ; move value in Read to work register
     movwf     PORTD                     ; move value in work register to PORTD register
     movf      PORTD,w                   ; move value in PORTD to work register
     movwf     Read                      ; move value in work register to Read register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x000                     ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
Sum:
     btfsc     PORTB,0                   ; test whether switch is press
     goto      Sum                       ; switch not press go back to the beginning of Sum
     movf      Value,w                   ; move value in Value register to work register
     addwf     Read,0                    ; add value in work register with value in Read register
     movwf     PORTD                     ; move value in work register to PORTD register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x000                     ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
ThirdValue:
     incf      Counter                   ; increase counter value
     btfsc     PORTB,0                   ; test whether switch is press
     goto      ThirdValue                ; switch not press go back to the beginning of ThirdValue
     movf      Counter,w                 ; move value in counter to work register
     movwf     Value1                    ; move value in work register to Value1 register
     movf      Value1,w                  ; move value in Value1 to work register
     movwf     PORTD                     ; move value in work register to PORTD register
     movf      PORTD,w                   ; move value in PORTD to work register 
     movwf     Value1                    ; move value in work register to Value1 register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x000                     ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
FourthValue:
     incf      Counter                   ; increase counter value
     btfsc     PORTB,0                   ; test whether switch is press
     goto      FourthValue               ; switch not press go back to the beginning of FourthValue
     movf      Counter,w                 ; move value in counter to work register
     movwf     Read1                     ; move value in work register to Read1 register
     movf      Read1,w                   ; move value in Read1 to work register
     movwf     PORTD                     ; move value in work register to PORTD register
     movf      PORTD,w                   ; move value in PORTD to work register
     movwf     Read1                     ; move value in work register to Read1 register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x000                     ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
Substract:
     btfsc     PORTB,0                   ; test whether switch is press
     goto      Substract                 ; switch not press go back to the beginning of Substract
     movf      Read1,w                   ; move value in Read register to work register
     subwf     Value1,0                  ; subtract value in Value1 register with value in work register
     movwf     PORTD                     ; move value in work register to PORTD register
     call      DelayOneSecond            ; delay 1 second
     movlw     0x000                     ; move b'00000000' into work register
     movwf     PORTD                     ; move value in work register to PORTD register
     goto      MainLoop                  ; go back to main loop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function Delays for One Second
DelayOneSecond:
     clrf      Time                ; clear value in TimerValue register
WaitOneSecond:
     clrf      TMR0                      ; clear Timer0
WaitTMR0:
     movf      TMR0,w                    ; move value in TMR0 register to work register
     xorlw     .250                      ; wait for 4ms (250x16us)
     btfss     STATUS,Z                  ; check whether zero present in STATUS
     goto      WaitTMR0                  ; loop back to WaitTMR0
     incf      Time,f                    ; increase the value of Counter register by 1 and store in TimerValue register
     movlw     .250                      ; wait for 1s (250x4ms)
     xorwf     Time,w                    ; move value in TimerValue register to work register
     btfss     STATUS,Z                  ; check whether zero present in STATUS
     goto      WaitOneSecond             ; loop back to WaitOneSecond
     return                              ; return back to the next instruction after function call 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     end
 
Last edited by a moderator:

Markd77

Joined Sep 7, 2009
2,806
I can't see anything obvious.
What is the configuration word set to?
What are the chip connections?
If you add the code:
Rich (BB code):
movlw b'10101010'
movwf PORTD
goto MainLoop
directly after mainloop, can you measure the correct voltages on PORTD?
 

Thread Starter

zhengkoon8

Joined Nov 28, 2011
10
Actually this is my task

Description: Design a simple calculator that performs addition and subtraction.

Just that I just simply copy the value from counter to be my first random value and do the same things for the second random value. Then add both of them together. Then I do the same thing to the subtract part. and lastly loop back to the beginning to do back the main loop again.

the configuration is

Rich (BB code):
#include <P16F887.INC>
    __CONFIG     _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_ON

what do u mean by Chip connection?

and i have added the code to try out already. it only does not work after 

WaitTMR0:      
movf      TMR0,w                    ; move value in TMR0 register to work register      
xorlw     .250                      ; wait for 4ms (250x16us)      
btfss     STATUS,Z                  ; check whether zero present in STATUS      
goto      WaitTMR0                  ; loop back to WaitTMR0
incf      Time,f                    ; increase the value of Counter register by 1 and store in TimerValue register      
movlw     .250                      ; wait for 1s (250x4ms)      
xorwf     Time,w                    ; move value in TimerValue register to work register      
btfss     STATUS,Z                  ; check whether zero present in STATUS
goto      WaitOneSecond             ; loop back to WaitOneSecond      
return                              ; return back to the next instruction after function call


And thanks for the reply. I am very appreciate it.
 
Last edited by a moderator:

Markd77

Joined Sep 7, 2009
2,806
OK, I can't see OPTION_REG being set up anywhere. TMR0 won't be running.
Also if you are going to check TMR0 in a loop, you either need to set the prescaler so that it increments less often than the loop takes, or use a subtract operation and check for a carry, or preload TMR0 with a value then check the TMR0 interrupt flag.
_MCLRE_ON is defined, have you got the MCLR pin pulled up to +V with a resistor?
 

Thread Starter

zhengkoon8

Joined Nov 28, 2011
10
Thank you very much. It works already after I added the OPTION_REG. Thanks for it. There is not hardware to added. It is purely software based programming. :)
 
Top