MPLAB Special Function Register Not Updating

Discussion in 'Embedded Systems and Microcontrollers' started by kf4knf, Dec 26, 2010.

  1. kf4knf

    Thread Starter New Member

    Dec 26, 2010
    Hi everyone,

    I am new to the forum and this is my first day trying to program a PIC. I have created a small program to turn a few LEDs on and off. The program seems to compile without any errors but when I try and simulate it in MPLabSIM with Special Function Registers turned on, I dont see any changes to PORTA or PORTB. What am I doing wrong? Please understand, I am trying to get the actions down for now, I will add some delays at a later time to slow down the LED's flashing frequency.

    Here is a copy of my code:

    Code ( (Unknown Language)):
    2. ; Program Functions:
    3.  list P=16F690
    4.  include "C:\Program Files\Microchip\MPASM Suite\"
    5. ;============================
    6. ;Declarations:
    7. porta equ  05h
    8. portb equ  06h
    9. portc equ  07h
    10.   goto Start
    11. ;============================
    12. ;Subroutines:
    13. Init clrf porta  ; Resets the input/output ports
    14.   clrf portb
    15.   clrf  portc
    16.   movlw b'0000' ; Setting all a ports to output
    17.   movwf porta
    18.   movlw b'00000000' ; Setting all b ports to output
    19.   movwf portb
    20.   retlw 0
    21. ;============================
    22. ;Program Start:
    23. Start call Init
    24. Main bsf  porta,0  ;Turn on LED on porta
    25.   bsf  portb,0  ;Turn on LED on portb
    26.   bsf  porta,1     ;Turn off LED on porta
    27.   bsf  portb,1     ;Turn off LED on portb
    28.   goto Main  ;Loops back to Main
    29.   END
    Last edited by a moderator: Dec 27, 2010
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    I am probably wrong, but, goto Start, I think that jumps you to Start and bypass the Subroutines all together, then Subroutines are never initialized.
  3. Chris.M


    Dec 9, 2009
    There are a few problems within your code.

    1. To set the direction of a port, you need to set the TRISA/TRISB/TRISC registers.
    2. In your Main loop, your second set of BSF needs to be changed to BCF (Bit Clear F). BSF will turn on the LED, BCF will turn off the LED.
    3. In your Main loop, your second set of BSF (should be BCF as above) uses a different pin to the first set of BSF (ie, you turn on pin 0 of PORTA but turn off pin 1 of PORTA, same problem for PORTB)
    4. PORTB only has pins RB4/RB5/RB6/RB7 so using PORTB pin 1 will not work.
    Here is some code which should work better:
    Code ( (Unknown Language)):
    1. ; Program Functions:
    2. list P=16F690
    3. include ""
    4. ;============================
    5. ORG    0x0000
    6. GOTO    Start
    7. ;============================
    8. ;Subroutines:
    9. Init
    10.     ; Turn comparator1 off
    11.     BANKSEL CM1CON0
    12.     BCF    CM1CON0,C1ON
    14.     ; Turn comparator2 off
    15.     BANKSEL CM2CON0
    16.     BCF    CM2CON0,C2ON
    18.     ; Set PORTA pins as digital I/O
    19.     BANKSEL    ANSEL
    20.     CLRF ANSEL
    22.     ; Set PORTB pins as digital I/O
    23.     BANKSEL ANSELH
    24.     CLRF    ANSELH
    26.     ; Turn off all outputs
    27.     BANKSEL    PORTA
    28.     CLRF    PORTA
    29.     BANKSEL    PORTB
    30.     CLRF    PORTB
    31.     BANKSEL    PORTC
    32.     CLRF    PORTC
    34.     ; Set all pins to output
    35.     BANKSEL    TRISA
    36.     CLRF    TRISA
    37.     BANKSEL    TRISB
    38.     CLRF    TRISB
    39.     BANKSEL    TRISC
    40.     CLRF    TRISC
    41.     RETLW    0
    43. ;============================
    44. ;Program Start:
    45. Start
    46.     CALL Init
    47. Main
    48.     ; Turn on LEDs
    49.     BANKSEL PORTA
    50.     bsf    PORTA, 0
    51.     BANKSEL PORTB
    52.     bsf    PORTB, 4
    54.     ; Turn off LEDs
    55.     BANKSEL PORTA
    56.     bcf    PORTA, 0
    57.     BANKSEL PORTB
    58.     bcf    PORTB, 4
    60.     goto Main ;Loops back to Main
    61. END
    This code does not have any delay's so it will not show a flashing LED on a real circuit, but will show you the bits changing in MPLAB SIM. You need to step through the code to see the pins turn on and off.
  4. kf4knf

    Thread Starter New Member

    Dec 26, 2010
    Thanks Chris.M, those changes you mentioned got it working. I can see the TRISA and TRISB updating in the Special Function Registers now. Now can you or someone else explain what the BANKSEL actually does in simple english in this situation?
  5. Markd77

    Senior Member

    Sep 7, 2009
    MPLAB is pretty good so if you don't see the port register changing there is a problem in the code. Check TRIS, CMCON and ANSEL registers in the datasheet and see if they need changing. Chris's code looks good.
    You can use the template which should be found here which can be a help. It has the configuration word in it which your program seems to be missing (it's easier to declare it in the code).
    C:\Program Files\Microchip\MPASM Suite\Template\code
  6. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    If just starting out with PICs, I'd suggest a high level language, such as C (Boost C or MikroC for PIC16, C18 and others are added for the 18F Series).

    You will get functional and small code on the first try, getting what you want done completed a bit quicker. Once you understand that the system works, you can tweak the .asm assembly language file created by the compiler for tweaks or improvements. Doing this teaches assembly fairly well at the same time as actually using the microcontrollers.

    The 16F series relies on the separate banks, while the 18F series is somewhat optimized, specifically the C for programming language and compilers, with a bit more 'flat' addressing scheme for certain things, like memory access and stacks.
  7. Chris.M


    Dec 9, 2009
    kf4knf, if you look at the documentation for you particular chip, you will see that the special function registers are located in different memory banks.

    To change a particular register value, you need to first tell the microcontroller which bank the register belongs too, so it knows how to access it. Essentially the BANKSEL directive (ie it is not an assembly instruction, look up directives in the MPASM Assembler Help for more info), when compiled, generates some code to select the appropriate bank.

    Therefore, when ever you need to access a register which is not in the current bank, you call BANKSEL to change banks.

    You can pass a register name to BANKSEL, and it will change to the appropriate bank. To get a list of definitions that you can use for your microcontroller (eg, PORTA, TRISA, RP0, etc), look at the include file.

    As thatoneguy as stated, learning a higher level language helps remove some of this complexity.
    Last edited: Dec 26, 2010
  8. Markd77

    Senior Member

    Sep 7, 2009
    Or using a PIC10F200, you don't need to worry about banks. I genuinely think it's pretty good to write the first few programs on.
    By the way you don't have to write the bit in your declares section, PORTA, etc are all defined in the .inc file, but they are case sensitive so "PORTA" is not the same as "porta".