Maker Pro
Maker Pro

PIC16F84 Assembler - Absolute Mode Issues

LordSputnik

Aug 11, 2011
45
Joined
Aug 11, 2011
Messages
45
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!
 

CocaCola

Apr 7, 2012
3,635
Joined
Apr 7, 2012
Messages
3,635
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...
 

LordSputnik

Aug 11, 2011
45
Joined
Aug 11, 2011
Messages
45
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:

BobK

Jan 5, 2010
7,682
Joined
Jan 5, 2010
Messages
7,682
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
 

LordSputnik

Aug 11, 2011
45
Joined
Aug 11, 2011
Messages
45
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!
 

LordSputnik

Aug 11, 2011
45
Joined
Aug 11, 2011
Messages
45
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:
Top