Connect with us

PIC16F84 Assembler - Absolute Mode Issues

Discussion in 'Microcontrollers, Programming and IoT' started by LordSputnik, Oct 17, 2012.

  1. LordSputnik

    LordSputnik

    45
    0
    Aug 11, 2011
    Dear all,

    I'm writing a simple program in absolute mode, in order to get started with MPASM.

    This program works as expected - an LED on B5 comes on and stays on:
    Code:
        LIST        p=16f84
        RADIX hex
        #include <P16F84.inc>
    
        __CONFIG   _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
    
    var1 EQU 0x0C
    
        ORG 0000h
    
        ;;; Initialization Code ;;;
    start:
        MOVLW   0xA0 ;; 10100000 Enable Global Interrupts, enable TMR0 interrupt.
        BANKSEL INTCON
        MOVWF   INTCON
        CLRF    PORTB
    
        MOVLW   0xD7 ;; 11010111 Set the TMR0 source to the internal clock, give the prescaler to TMR0, 1:128 Prescale.
        BANKSEL OPTION_REG
        MOVWF   OPTION_REG
    
        BANKSEL TRISB
        CLRF    TRISB   ;; Set all of PORTB to be outputs.
    
        BANKSEL PORTB
        MOVLW 0x20
    
    test:
        MOVWF PORTB
        GOTO test
    
        END
    However, if I want to add an interrupt routine, I need to use a goto in order to skip its execution at start up. With the GOTO in the program, the LED on B5 doesn't light up...

    Code:
        LIST        p=16f84
        RADIX hex
        #include <P16F84.inc>
    
        __CONFIG   _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
    
    var1 EQU 0x0C
    
        ORG 0000h
        GOTO start
    
        ;;; Initialization Code ;;;
    start:
        MOVLW   0xA0 ;; 10100000 Enable Global Interrupts, enable TMR0 interrupt.
        BANKSEL INTCON
        MOVWF   INTCON
        CLRF    PORTB
    
        MOVLW   0xD7 ;; 11010111 Set the TMR0 source to the internal clock, give the prescaler to TMR0, 1:128 Prescale.
        BANKSEL OPTION_REG
        MOVWF   OPTION_REG
    
        BANKSEL TRISB
        CLRF    TRISB   ;; Set all of PORTB to be outputs.
    
        BANKSEL PORTB
        MOVLW 0x20
    
    test:
        MOVWF PORTB
        GOTO test
    
        END
    Does anyone know why this might be?

    Let me know if you need any additional information in order to help! Many Thanks!
     
  2. CocaCola

    CocaCola

    3,635
    4
    Apr 7, 2012
    I'm not going to comment on assembly as it not my forte and I'm not quite following your code as it appears there is no difference besides the addition of a redundant GOTO... But I will comment that you might want to consider using a newer chip... The PIC16F84 is really an antique and nearly obsolete, you should move to at least the PIC16F628 it will help alleviate some aggravations as you expand and grow, the internal oscillator is reason enough in my book...
     
  3. LordSputnik

    LordSputnik

    45
    0
    Aug 11, 2011
    I know it's really ancient, I'm not able to switch chips, it's a uni project and for some reason the PIC they provide is the 16F84...

    I use 18F25K22 at other times, so bit of a step down in terms of functionality, I know...
     
    Last edited: Oct 18, 2012
  4. BobK

    BobK

    7,599
    1,641
    Jan 5, 2010
    An interrupt causes the program to start execution at address 4. You must have an interrupt handler starting at that address. You have enabled interrupts with no interrupt handler, which causes the PIC to jump to address 4 in your program.

    Try this:

    ORG 0
    goto start

    ORG 4
    RETFIE

    start: <your prorgram>

    This provides an interrupt handler that simply returns. You should put the actual interrupt handler there once you know how.

    Bob
     
  5. LordSputnik

    LordSputnik

    45
    0
    Aug 11, 2011
    Ok, I did have an interrupt handler similar to that in my code before I posted, but it didn't seem to make much difference.

    A few people at the Microchip forums suggested that instead of writing the code from scratch, I make a short program using the Microchip template for the PIC, and see if that works, so I'll let you know how that goes.

    Thanks!
     
  6. LordSputnik

    LordSputnik

    45
    0
    Aug 11, 2011
    Thanks for your help guys, using the template from <installdir>/mpasmx/templates and building on that got it working for me.

    Here's the code that worked:

    Code:
        list      p=16F84             ; list directive to define processor
        #include <p16F84.inc>         ; processor specific variable definitions
    
        __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
    
    ; '__CONFIG' directive is used to embed configuration data within .asm file.
    ; The lables following the directive are located in the respective .inc file.
    ; See respective data sheet for additional information on configuration word.
    
    ;***** VARIABLE DEFINITIONS
    w_temp        EQU     0x0C        ; variable used for context saving
    status_temp   EQU     0x0D        ; variable used for context saving
    var1          EQU     0x0E
    
    
    ;**********************************************************************
        ORG     0x000             ; processor reset vector
        goto    Init              ; go to beginning of program
    
    
        ORG     0x004             ; interrupt vector location
        movwf   w_temp            ; save off current W register contents
        movf    STATUS,w          ; move status register into W register
        movwf    status_temp       ; save off contents of STATUS register
    
    
    ; isr code can go here or be located as a call subroutine elsewhere
    
    
        movf    status_temp,w     ; retrieve copy of STATUS register
        movwf    STATUS            ; restore pre-isr STATUS register contents
        swapf   w_temp,f
        swapf   w_temp,w          ; restore pre-isr W register contents
        retfie                    ; return from interrupt
    
    
    
    Init
    ; remaining code goes here
    
        movlw   0x20 ;; 10100000 Enable Global Interrupts, enable TMR0 interrupt.
        banksel INTCON
        movwf   INTCON
        clrf    PORTB
    
        movlw   0xD7 ;; 11010111 Set the TMR0 source to the internal clock, give the prescaler to TMR0, 1:128 Prescale.
        banksel OPTION_REG
        movwf   OPTION_REG
    
        banksel TRISB
        clrf    TRISB   ;; Set all of PORTB to be outputs.
    
        banksel PORTB
    
    MainLoop
        movlw 0x30
        btfsc PORTA,1
            movlw 0x00
        movwf PORTB
        goto MainLoop
    
    
    
        END                     ; directive 'end of program'
    It waits for a button to be pushed on A1, and lights up two LEDs if it is (the LEDs are connected with their cathodes to the PIC pins - since pins can sink 25mA but only source 20mA). Note: I also globally turned off interrupts in INTCON, as I'm not using them yet.

    Mainly posting this so others with the same problem can fix it.

    P.S. If you have any advice for programming PICs in assembler, please let me know!
     
    Last edited: Oct 18, 2012
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-