Calling a routine from within a called routine?

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
treez
Posts: 161
Joined: Sat Dec 27, 2008 8:39 am

Calling a routine from within a called routine?

Post by treez » Thu Oct 09, 2014 11:49 am

Hello,
I am writing MPASM assembler for pic18f65k22.
In one place I call a routine, and then from within that routine, I call a different routine, is this ok?
Here is my code...its an LED controller

Code: Select all

;Code for 3 channel led driver on the updated 550587 PCB
;REMEMBER RESET ADDRESS
;remember to   set the oscillator
;WE ARE TRUNCATING THE ADC REGISTER SO JUST USE UPPER 8 BITS

; XXX DIPSWITCH POLARITY:- XXX
;DIP 1...ON = EXTERNAL CONNECTOR CONTROL
;DIP 2...ON = LOGIC HIGH (note 'ON' gives a low input)
;DIP 3...ON = LOGIC HIGH
;DIP 4...OFF = 10V is for max current
;DIP 5...OFF = 80degC, ON = 90degC
;DIP 6... UNUSED
;DIP 7... UNUSED
;DIP 8...ON = NO FAN FITTED, OFF = FAN FITTED

; XXX  EXTERNAL CONTROL CONNECTOR POLARITY:- XXX
;CLEAR = ACTIVE HIGH
;RESET = ACTIVE HIGH
;CH1...HIGH = ON, LOW = OFF
;CH2...HIGH = ON, LOW = OFF
;CH3...HIGH = ON, LOW = OFF

;List of input ports:
; ************** DIPSWITCH INPUTS:
;DIP1 = RB0
;DIP2 = RB1
;DIP3 = RB2
;DIP4 = RB3
;DIP5 = RB4
;DIP6 = RB5
;DIP7 = RC5
;DIP8 = RE6

;************* External connector INPUTS:
;clear =       RC1
;ch3 on/off =  RC7
;RESET =       RD5
;CH1 on/off =  RD6
;ch2 on/off =  RD7

;Other inputs (DIGITAL I/O
;Fan tacho = RG2
;mclr =      RG5

;Inputs that are ADC inputs:
;RA2 = AN2
;RA3 = AN3
;RA5 = AN4
;RF1 = AN6
;RF2 = AN7
;RF3 = AN8
;RF4 = AN9
;RF5 = AN10
;RF6 = AN11
;RF7 = AN5

;**********ADC INPUTS:
;AN0 = NC
;AN1 = NC
;AN2 = VREF- (0V)
;AN3 = VREF+ (3V)
;AN4 = Therm ch1
;AN5 = I_CH1
;AN6 = 0-10V control input
;AN7 = PCB thermistor
;AN8 = I_ch2
;AN9 = I_ch3
;AN10 = Therm-ch2
;AN11 = Therm-ch3

;OOOOOOOOOOO LIST OF OUTPUTS:
;Trip =          RA4

;Indicator LED = RC2
;MCP4013_CS =    RC3
;MCP4013_UD =    RC4

;Shutdown-Ch2 =  RE0
;Shutdown-Ch1 =  RE1
;Fancon PWM =    RE2

;Shutdown-Ch3 =  RG0

;NCNCNCNCNCNCNCNCNC LIST OF NON CONNECTED PINS:
;RA0
;RA1
;RA6
;RA7
;    RB6  = PGC
;    RB7  = PGD
;RC0
;RC6
;    RD0
;    RD1
;    RD2
;    RD3
;    RD4
;RE3
;RE4
;RE5
;RE7
;    RG1
;    RG3
;    RG4





#include "p18F65K22.inc"
 list p=18f65k22       	  ;list directive to define processor
; CONFIG1L
  CONFIG  RETEN = OFF           ; VREG Sleep Enable bit (Disabled - Controlled by SRETEN bit)
  CONFIG  INTOSCSEL = HIGH      ; LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
  CONFIG  SOSCSEL = HIGH        ; SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
  CONFIG  XINST = ON            ; Extended Instruction Set (Enabled)

; CONFIG1H
  CONFIG  FOSC = INTIO1         ; Oscillator (Internal RC oscillator, CLKOUT function on OSC2)
  CONFIG  PLLCFG = OFF          ; PLL x4 Enable bit (Disabled)
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor (Disabled)
  CONFIG  IESO = OFF            ; Internal External Oscillator Switch Over Mode (Disabled)

; CONFIG2L
  CONFIG  PWRTEN = OFF          ; Power Up Timer (Disabled)
  CONFIG  BOREN = SBORDIS       ; Brown Out Detect (Enabled in hardware, SBOREN disabled)
  CONFIG  BORV = 0              ; Brown-out Reset Voltage bits (3.0V)
  CONFIG  BORPWR = ZPBORMV      ; BORMV Power level (ZPBORMV instead of BORMV is selected)

; CONFIG2H
  CONFIG  WDTEN = OFF           ; Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
  CONFIG  WDTPS = 1048576       ; Watchdog Postscaler (1:1048576)

; CONFIG3L
  CONFIG  RTCOSC = SOSCREF      ; RTCC Clock Select (RTCC uses SOSC)

; CONFIG3H
  CONFIG  CCP2MX = PORTC        ; CCP2 Mux (RC1)
  CONFIG  MSSPMSK = MSK7        ; MSSP address masking (7 Bit address masking mode)
  CONFIG  MCLRE = OFF           ; Master Clear Enable (MCLR Disabled, RG5 Enabled)

; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Overflow Reset (Enabled)
  CONFIG  BBSIZ = BB2K          ; Boot Block Size (2K word Boot Block size)

; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protect 00800-01FFF (Disabled)
  CONFIG  CP1 = OFF             ; Code Protect 02000-03FFF (Disabled)
  CONFIG  CP2 = OFF             ; Code Protect 04000-05FFF (Disabled)
  CONFIG  CP3 = OFF             ; Code Protect 06000-07FFF (Disabled)

; CONFIG5H
  CONFIG  CPB = OFF             ; Code Protect Boot (Disabled)
  CONFIG  CPD = OFF             ; Data EE Read Protect (Disabled)

; CONFIG6L
  CONFIG  WRT0 = OFF            ; Table Write Protect 00800-017FF (Disabled)
  CONFIG  WRT1 = OFF            ; Table Write Protect 01800-03FFF (Disabled)
  CONFIG  WRT2 = OFF            ; Table Write Protect 04000-05FFF (Disabled)
  CONFIG  WRT3 = OFF            ; Table Write Protect 06000-07FFF (Disabled)

; CONFIG6H
  CONFIG  WRTC = OFF            ; Config. Write Protect (Disabled)
  CONFIG  WRTB = OFF            ; Table Write Protect Boot (Disabled)
  CONFIG  WRTD = OFF            ; Data EE Write Protect (Disabled)

; CONFIG7L
  CONFIG  EBRT0 = OFF           ; Table Read Protect 00800-017FF (Disabled)
  CONFIG  EBRT1 = OFF           ; Table Read Protect 01800-03FFF (Disabled)
  CONFIG  EBRT2 = OFF           ; Table Read Protect 04000-05FFF (Disabled)
  CONFIG  EBRT3 = OFF           ; Table Read Protect 06000-07FFF (Disabled)

; CONFIG7H
  CONFIG  EBRTB = OFF           ; Table Read Protect Boot (Disabled)





;DEFINE OUTPUTS
#define ch1bit     LATE,LATE1
#define ch2bit     LATE,LATE0
#define ch3bit     LATG,LATG0
#define ind_ledbit LATC,LATC2
#define fanconbit LATE,LATE2
#define tripbit    LATA,LATA4
#define mcp4013_csbit  LATC,LATC3
#define mcp4013_udbit  LATC,LATC4

;DEFINE INPUTS FROM DIPSWITCH
;Note that the new board has pullups on the dipswitch,
;whereas 550587 PCB had pull downs, thus logic is reversed.
#define modebit     dip8,0  ;low = external connector sets power via 0-10V
#define LSBbit      dip8,1  ;00 -> 3.52A, 01 -> 2.64A, 10 -> 1.76A, 11 -> OFF
#define MSBbit      dip8,2
#define polaritybit dip8,3  ;high = 10V gives max current
#define t80t90bit   dip8,4  ;high = 80degC, low=90degC
#define fanbit      dip8,8  ;high = fan fitted, low = no fan fitted

;DEFINE INPUTS FROM EXTERNAL CONNECTOR
#define re_setbit  ext_in,0
#define ch1_extbit ext_in,1
#define ch2_extbit ext_in,2
#define ch3_extbit ext_in,3
#define clearbit   ext_in,4

temp1     equ	0x20         ;register for HOLDING ch 1 temperature
temp2     equ	0x21         ;register for holding ch 2 temperature
temp3     equ	0x22         ;register for holding ch 3 temperature
tempb     equ	0x23         ;register for holding board temperature

ana8     equ   0x25         ;holds ADC reading converted to 8 bit from 12 bit
ana_hi    equ   0x26         ;holds the ADRESH register
ana_lo    equ   0x27         ;holds the ADRESL register
ext_in    equ   0x28         ;holds the external connector inputs
del1        equ     0x29         ;Delay register
del2        equ     0x2A         ;Delay register
board_90C   equ     0x2B         ;HOLDS 90C VALUE FOR BOARD
board_80C   equ     0x2C        ;HOLDS 80C VALUE FOR BOARD
led_90C     equ     0x2D        ;HOLDS 90C VALUE FOR LEDS
led_80C     equ     0x2E        ;HOLDS 80C VALUE FOR LEDS
max_temp    equ     0x2F        ;Holds the max temp
current     equ     0x30        ;Holds the current level bits (bits 0=0 to 3)

dip8      equ   0x32         ;holds dipswitch settings
dip8_next      equ 0x33        ;holds updated dipswitch settings
dip8_prev   equ 0x34
count       equ 0x35           ;count
iset_mcp4013    equ     0x36    ;Holds the set current value in mcp4013 steps
iset_mcp4013_A  equ     0x37    ;

; *** DECLARE MACRO'S ***
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

;**** bank switching ****

;*** TURN LEDS ON AND OFF
ON1 macro               ;Turn on chan1
    bsf LATE,LATE1
    endm

OFF1 macro               ;Turn off chan1
    bcf LATE,LATE1
    endm

ON2 macro               ;Turn on chan2
    bsf LATE,LATE0
    endm

OFF2 macro               ;Turn off chan2
    bcf LATE,LATE0
    endm

ON3 macro               ;Turn on chan2
    bsf LATG,LATG0
    endm

OFF3 macro               ;Turn off chan2
    bcf LATG,LATG0
    endm

;****** READ TEMP ******************


; ************************

; ********  Read dipswitchs into dip8 register ********
;Remember that the new PCB has pullups, wheras 550587 PCB had pull downs
;..thus logic in the program is reversed
read_dips   macro
    bsf dip8,0      ;DIPSWITCH 1 = MODE
    btfss   PORTB,RB0
    bcf dip8,0

    bsf dip8,1      ;DIPSWITCH 2, Power bit 0
    btfss   PORTB,RB1
    bcf dip8,1

    bsf dip8,2      ;DIPSWITCH 3, power bit 1
    btfss   PORTB,RB2
    bcf dip8,2

    bsf dip8,3      ;DIPSWITCH 4, polarity of 0-10V
    btfss   PORTB,RB3
    bcf dip8,3

    bsf dip8,4      ;DIPSWITCH 5, Temp threshold = 80c or 90c
    btfss   PORTB,RB4
    bcf dip8,4

    bsf dip8,5      ;DIPSWITCH 6, unused
    btfss   PORTB,RB5
    bcf dip8,5

    bsf dip8,6      ;DIPSWITCH 7, unused
    btfss   PORTC,RC5
    bcf dip8,6

    bsf dip8,7      ;DIPSWITCH 8, fan or no fan
    btfss   PORTE,RE6
    bcf dip8,7
    endm
;-----------------------------------------------


;****** READ EXTERNAL CONNECTOR DIGITAL INPUTS *******
read_ext_conn   macro


    bsf ext_in,0   ;extconn PIN 3; RESET
    btfss   PORTD,RD5
    bcf ext_in,0

    bsf ext_in,1   ;extconn PIN 4; CH1_ON/OFF
    btfss   PORTD,RD6
    bcf ext_in,1

    bsf ext_in,2   ;extconn PIN 5; CH2_ON/OFF
    btfss   PORTD,RD7
    bcf ext_in,2

    bsf ext_in,3   ;extconn PIN 6; CH3_ON/OFF
    btfss   PORTC,RC7
    bcf ext_in,3

    bsf ext_in,4  ;extconn PIN 10; CLEAR
    btfss   PORTC,RC1
    bcf ext_in,4
    endm
; *****************************************

; **** output a tripped signal ****
output_trip macro
    bsf tripbit
    endm

; *****output a non-tripped signal ****
no_output_trip macro
    bcf tripbit
    endm

;***** Make ADC reading 8 bit from 12 bit ***********
ana_to_8bit    macro
    movf    ADRESH,w
    movwf   ana8
    endm
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;SET UP THE ADC
setupADC    macro
    movlw   0x00
    movwf   ADCON0  ;channel select, godone, ADON

    movlw   0x10
    movwf   ADCON1  ;vref

    movlw   0x3E
    movwf   ADCON2  ;Right justified, acquisition time
    endm
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

; ************ Define analog pins ***********8
ana_pins    macro
    movlw   0xFC    ;
    movwf  ANCON0
    movlw   0x0F    ;
    movwf  ANCON1
    movlw   0x00    ;
    movwf   ANCON2
    endm
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; Disable the comparators
comparator_off    macro
    movlw   0x00
    movwf   CM1CON
    movlw   0x00
    movwf   CM2CON
    movlw   0x00
    movwf   CM3CON
    endm
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; Disable interrupts
no_interrupts   macro
    clrf    INTCON
    movlw   0x80
    movwf   INTCON2
    clrf    INTCON3
    clrf        PIE1
    clrf        PIE2
    clrf        PIE3
    clrf        PIE4
    clrf        PIE5
    clrf        PIE6
    endm
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

; Disable pullups
no_pullups  macro
    clrf    PADCFG1
    endm
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; disable open drain outputs
no_opendrain    macro
    clrf    ODCON1
    clrf    ODCON2
    clrf    ODCON3
    endm
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXX


;xxxxxxxxxxxxxxxxxxxxxxx
;set up ports as inputs or outputs
setup_ports    macro
    movlw   0x2C
    movwf   TRISA
    movlw   0x3F
    movwf   TRISB
    movlw   0xA2
    movwf   TRISC
    movlw   0xD0
    movwf   TRISD
    movlw   0x40
    movwf   TRISE
    movlw   0xFE
    movwf   TRISF
    movlw   0x24
    movwf   TRISG
    endm
;XXXXXXXXXXXXXXXXXXXXXXXXX

load_temps   macro
    movlw   0xA8        ;80  DEGC
    movwf   board_80C
    movlw   0xB8        ;90  DEGC
    movwf   board_90C
    movlw   0xA8        ;80  DEGC
    movwf   led_80C
    movlw   0xC9        ;90  DEGC
    movwf   led_90C
    endm

;XXXXXXXXXXXXXXXXXXXXXXXXXX
;Make all NC pins low (they are already made to outputs)
;They are outputs for noise immunity reasons
NC_pins_low macro
    bcf LATA,LATA0
    bcf LATA,LATA1
    bcf LATA,LATA6
    bcf LATA,LATA7

    bcf LATB,LATB6  ;PGC
    bcf LATB,LATB7  ;PGD

    bcf LATC,LATC0
    bcf LATC,LATC6

    bcf LATD,LATD0
    bcf LATD,LATD1
    bcf LATD,LATD2
    bcf LATD,LATD3
    bcf LATD,LATD4

    bcf LATE,LATE3
    bcf LATE,LATE4
    bcf LATE,LATE5
    bcf LATE,LATE7

    bcf LATG,LATG1
    bcf LATG,LATG3
    bcf LATG,LATG4

;    bcf PORTF,RF0
    endm

;DEFINES TO NAME OUTPUTS
;INITIALISE OUTPUTS THAT ARE CONNECTED
;defines for dip8 bits and ext_con bits


    org 0x04

start

Main	movlw	b'01100000'		; set internal osc to 8 mhz
		movwf	OSCCON

;SETUP JOBS
    setup_ports
    no_pullups
    no_opendrain
    NC_pins_low
    ana_pins
    comparator_off
    setupADC
    no_interrupts

begin
;Turn LEDs off
    OFF1
    OFF2
    OFF3

    call    delay_ms
;load temperature maximums.
    load_temps  ;load the max temperature values
;Read the dipswitchs
    read_dips
;Load the maximum temperature (either 80C or 90C)
    movf    led_80C,w
    movwf   max_temp
    btfss   t80t90bit
    movf    led_90C,w
    movwf   max_temp

;Find the maximum current level
    clrf    current     ;clear current reg prior to loading
    btfss   MSBbit
    call    a0_or_a1    ;set relevant bit in 'çurrent' register
    btfsc   LSBbit
    call    a2_or_a3    ;set relevant bit in 'çurrent' register
;Load the isetlevel register with relevant no of pulses
    btfsc   current,0
    goto    shutdown    ;bit 0 of 'current' register was set
    btfsc   current,1
    call    a1p76       ;1.76A = 33 PULSES to mcp4013
    btfsc   current,2   ;2.64A = 47 PULSES to mcp4013
    call    a2p64
    btfsc   current,3   ;3.52A = 61 pulses to mcp4013
    call    a3p52






;Find whether need internal  or external mode.
    btfss   modebit
    goto    EXTMODE
    goto    INTMODE

;Load the maximum temperature registers




EXTMODE
    nop


INTMODE
int1
    call    zero_mcp4013    ;zero the mcp4013 (zero volts out)
    call    set_mcp4013     ;Set the led driver current with MCP4013

int2
    movf    dip8,w
    movwf   dip8_prev
    read_dips
    movf    dip8,w
    movwf   dip8_next
    movf    dip8_next,w
    bcf     STATUS,Z
    xorwf   dip8_prev
    btfss   STATUS,Z    ;skip if the registers are the same
    goto    begin

;check temperature too hot
;Read temperture LED1.
    movlw   0x10
    movwf   ADCON0  ;Select AN4 for therm CH1
    movlw   0x11
    movwf   ADCON0     ;Enable ADC
    bsf     ADCON0,1    ;start ADC conversion
int3
    btfsc   ADCON0,1    ;check for ADC done
    goto    int3



;   goto    int2

 








    goto    begin
; ***** END OF MAIN LOOP *******

;------------------------------------------------
; FUNCTIONS   FUNCTIONS    FUNCTIONS    FUNCTIONS
;------------------------------------------------

; **** LOAD THE CURRENT REGISTER LOWER 4 BITS ****
a0_or_a1    ;Find out if its 0a or 1a
    btfss   LSBbit
    bsf     current,0   ;indicate 0 amps set
    bsf     current,1   ;indicate 1.76 amps set
    retlw   0x00
a2_or_a3    ;Find out if its 2a or 3a
    btfss   MSBbit
    bsf     current,2   ;indicate 2.64 amps set
    bsf     current,3   ;indicate 3.52 amps set
    retlw   0x00
; ***************************************************

;xxxxxx Load set current level ((no of pulses to mcp4013)  xxxxxxxxxxxx
shutdown    ;MSB and LSB bits were 0,0
    bcf     ch1bit
    bcf     ch2bit
    bcf     ch3bit
    goto    begin
a1p76       ;MSB = 0, LSB = 1
    movlw   0x21        ;33 pulses for 1A76
    movwf   iset_mcp4013
    retlw   0x00
a2p64       ;MSB = 1, LSB = 0
    movlw   0x2F        ;47 pulses for 2A64
    movwf   iset_mcp4013
    retlw   0x00
a3p52
    movlw   0x3D        ;61 pulses for 3A52
    movwf   iset_mcp4013
    retlw   0x00
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

zero_mcp4013        ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    bsf     mcp4013_csbit   ;disable mcp4013
    bcf     mcp4013_udbit   ;prep for decrement
    movlw   0x42            ;enough to decrement to zero volts
    movwf   count           ;
    call    delay_1ms
    bcf     mcp4013_csbit   ;enable mcp4013
mcp1
    bsf     mcp4013_udbit   ;do a decrement
    call    delay_1ms
    bcf     mcp4013_udbit
    call    delay_1ms
    decfsz  count,1
    goto    mcp1
    bsf     mcp4013_udbit   ;disbale change of mcp4013
    call    delay_1ms
    retlw   0x00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

set_mcp4013     ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    movf    iset_mcp4013,w
    movwf   iset_mcp4013_A
    bsf     mcp4013_csbit   ;disable mcp4013
    bsf     mcp4013_udbit   ;prep for increment
    call    delay_1ms
    bcf     mcp4013_csbit   ;enable mcp4013
    call    delay_1ms
set1
    bcf     mcp4013_udbit
    call    delay_1ms
    bsf     mcp4013_udbit
    call    delay_1ms
    decfsz  iset_mcp4013_A
    goto    set1
    bsf     mcp4013_csbit   ;disable change of mcp4013
    call    delay_1ms
    retlw   0x00
    


    

 






; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
delay_1ms
    movlw   0x05
    movwf   del1
b1
    movlw   0xFF
    movwf   del2
a1
    decfsz  del2,f
    goto    a1
    decfsz  del1,f
    goto    b1
    retlw   0x00

delay_10ms
    movlw   0x0A
    movwf   del1
b10
    movlw   0xFF
    movwf   del2
a10
    decfsz  del2,f
    goto    a10
    decfsz  del1,f
    goto    b10
    retlw   0x00


delay_ms
    movlw   0xFF
    movwf   del1
zzz
    movlw   0xFF
    movwf   del2
yyy
    decfsz  del2,f
    goto    yyy
    decfsz  del1,f
    goto    zzz
    retlw   0x00


    end

User avatar
phalanx
Non-SFE Guru
Posts: 1991
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: Calling a routine from within a called routine?

Post by phalanx » Fri Oct 10, 2014 5:34 am

Your PIC has a 31 layer deep hardware stack which means you can have any combination of up to 31 nested interrupts or function calls before you run into trouble. There are status bits you can check to see if the stack is full, overflowed, or underflowed.

That said, calling a delay from one of your subroutines is no problem.

-Bill

Post Reply