Friday, 3 August 2012

Assembler language endeavours in PIC land ...

I find the architecture of the PIC harder to grasp...
On studying Assembler language for Microchip PIC uC's managed to get confused with the real role of the STATUS Register ( RP0 and RP1 ). And why you have to resume it back to bank 0, after each of the changes...



Code is this :


#include <p16F887.inc>
 __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
 __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V

     org 0
Start:
     bsf     STATUS,RP0  ; select Register Bank 1
     bcf     TRISD,0     ; make IO Pin RD0 an output
     bcf     STATUS,RP0  ; back to Register Bank 0
     bsf     PORTD,0     ; turn on LED RD0 (DS0) 
     bcf  PORTD,0
     bcf     STATUS,RP0
  bsf     STATUS,RP0  ; select Register Bank 1
     bcf     TRISD,1     ; make IO Pin RD1 an output
     bcf     STATUS,RP0  ; back to Register Bank 0
     bsf     PORTD,1     ; turn on LED RD1 
     bcf  PORTD,1
     bcf     STATUS,RP0
  bsf     STATUS,RP0  ; select Register Bank 1
     bcf     TRISD,2    ; make IO Pin RD2 an output
     bcf     STATUS,RP0  ; back to Register Bank 0
     bsf     PORTD,2     ; turn on LED RD2 
     bcf  PORTD,2
     bcf     STATUS,RP0
         bsf     STATUS,RP0  ; select Register Bank 1
     bcf     TRISD,3    ; make IO Pin RD3 an output
     bcf     STATUS,RP0  ; back to Register Bank 0
     bsf     PORTD,3     ; turn on LED RD3 
     bcf  PORTD,3
     bcf     STATUS,RP0
         bsf     STATUS,RP0  ; select Register Bank 1
     bcf     TRISD,4    ; make IO Pin RD4 an output
     bcf     STATUS,RP0  ; back to Register Bank 0
     bsf     PORTD,4     ; turn on LED RD4  
     bcf  PORTD,4
     bcf     STATUS,RP0
  goto    Start      ; wait here
     end


So it seems that this is the way banks work: In the status SFR, bit 5 , bit 6 and bit 7 are RP0, RP1 and IRP ( which It is used for indirect addressing), So The two banks used are RP0 and RP1. And they have.the RAM divided in 4 each of RP0 and RP1, which are blocks and we need to change it in order to use them ( im told this is one of the points in favour of the ATMEL chips). If we after using arrays then we'd have to use FSR-INDF ( not relevant now).

I was then also told, that MPLAB has some macros that sort it for you.
Its name is banksel .
So, after some research here is my way of seeing it...
The banksel will sort out for us the stuff related to the status for us, seting the bits and clearing them for us.





#include <p16F887.inc>
 __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
 __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V

     org 0
Start:
     

  banksel TRISD           ;Include standard header file
                          ;for the selected device...
                          
  clrf    TRISD           ;Clear TRISD. Sets PORTD to outputs.
  banksel PORTD           ;banksel used to return to bank 0,
                          ;where PORTD is located.

  movlw   0x55            ;Set PORTD value.

  movwf   PORTD
  clrf    PORTD
  goto    Start
  end                     ;All programs must have an end.



Also, managed to get the PCLATCH register understood, today ( Ill just say that is the counter of the program, and will cover the number of up to 8192, divided by the 13 bits of the SFR's PCL and PCLATCH (2^13=8192) , always incrementing automatically, though having the Least significant bits( LSB) on the PCL... there seem to be some quirks here for some cases, but im told to leave that for now !!


For completions of info:
PIC16F887 44 Pins, 8 leds on PORTD and PickIt2 debugger !
PS- Another code, brought from someone @ http://lusorobotica.com, explaining that you can set all your bits first, and then bring back the register back to bank 0.



#include <p16F887.inc>
 __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
 __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V

org 0x00

Start:

     bsf     STATUS,RP0  ; choose Register 1
     MOVLW 0x00          ;load register W with 0
     MOVWF TRISD         ;Start register TRISD with 0 (Moved from the already loaded value in W)
     bcf     STATUS,RP0  ; Bit clear, back to Bank 0
     MOVLW b'10101010'   ; A pattern to light the LEDs (bynary, with 1 for on and 0 for off)
     MOVWF PORTD        ;write to port D
     GOTO $              ; 

     end                ;The End !




Some people who been totally to blame for these adventures in PICland... and one is definitely SENA, who you can visit here http://www.antoniosergiosena.com/ .
He has a wicked tutorial in Portuguese which been priceless to me ! With examples in both C and ASSEMBLER; I chose Assembler first  ( i know, i know...)
Man is a PRO in PIC assembler and C. Hands down !!
Also, as mentioned above, http://lusorobotica.com.

Some reference
http://www.mikroe.com/eng/chapters/view/3/chapter-2-core-sfrs/

1 comment:

  1. je peux avoir l'organigramme de ce

    LIST p=16F84
    #include
    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
    OPTIONVAL EQU H'87'
    cmptval EQU .08
    cmpt1val EQU .16
    ;***********************************
    bank0 macro
    bcf STATUS,RP0
    endm
    bank1 macro
    bsf STATUS,RP0
    endm
    ;**********************************
    CBLOCK 0x00C
    cmpt :1
    cmpt1 :1
    dec :1
    w_temp :1
    status_temp:1
    ENDC
    ;*********************************
    org 0x000
    goto init
    org 0x004
    movwf w_temp
    swapf STATUS,w
    movwf status_temp
    call intrb0
    ;-------------------
    bcf INTCON , 2
    swapf status_temp,w
    movwf STATUS
    swapf w_temp,f
    swapf w_temp,w
    retfie
    ;*******************************
    intrb0
    movf dec,f
    btfss STATUS,Z
    goto intrb1
    decfsz cmpt,f
    return
    movlw 0x01

    xorwf PORTA,f
    movlw cmptval
    movwf cmpt
    movlw 0x01
    movwf dec
    return
    intrb1
    decfsz cmpt1,f
    return
    movlw 0x01
    xorwf PORTA,f
    movlw cmpt1val
    movwf cmpt1
    movlw 0x00
    movwf dec
    return
    ;***************************
    init
    clrf PORTA
    clrf PORTB
    clrf EEADR
    bank1
    movlw OPTIONVAL
    movwf OPTION_REG
    movlw 0x0c
    movwf FSR
    init1
    clrf INDF
    incf FSR,f
    btfss FSR,6
    goto init1
    btfss FSR,4
    goto init1
    clrf TRISA
    bank0
    movlw 0xA0
    movwf INTCON
    movlw cmptval
    movwf cmpt
    movlw cmpt1val
    movwf cmpt1
    ;*************************
    start
    goto start
    END

    ReplyDelete

Feel free to contact me with any suggestions, doubts or requests.

Bless