ASM code


Closed Thread
Results 1 to 21 of 21

Thread: ASM code

Hybrid View

  1. #1
    Join Date
    Nov 2007
    Location
    South-West of Australia. A small town called Denmark. 'Where the forest meets the sea.'
    Posts
    136


    Did you find this post helpful? Yes | No

    Default ASM code

    Dave,

    Thanks for your support and interest.

    Having got it to work using the 'end-loop' process you suggested, I had a further play-around with the interrupts - and made it work!

    I added the code:

    Code:
    bcf  RCON,7    ; Clear IPEN=0, disable priority interrupts
    And now all is OK.

    If anyone is interested in the code I'm happy to put it up here. The routine uses ASM to:

    1. Drive 2 stepper motors at the same time.
    2. Main purpose is to get diagonal moves on an XY plotter
    3. The asm code is passed parameters by PBP:
    a. X steps to be done
    b. Y steps to be done
    c. X inter-pulse delay
    d. Y inter-pulse delay
    4. Code has yet to be 'polished' and oly works with byte size parameters.
    Next is changing to accept WORD size parameters.

    Once again - thanks for your help.

    Regards Bill Legge

  2. #2
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bill Legge View Post
    Code:
    bcf  RCON,7    ; Clear IPEN=0, disable priority interrupts
    If anyone is interested in the code I'm happy to put it up here. The routine uses ASM to:

    1. Drive 2 stepper motors at the same time.
    2. Main purpose is to get diagonal moves on an XY plotter
    3. The asm code is passed parameters by PBP:
    a. X steps to be done
    b. Y steps to be done
    c. X inter-pulse delay
    d. Y inter-pulse delay
    4. Code has yet to be 'polished' and only works with byte size parameters.
    Next is changing to accept WORD size parameters.
    Hi Bill,
    I would like to see it,
    Thank You.
    JS
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bill Legge View Post
    I added the code:

    Code:
    bcf  RCON,7    ; Clear IPEN=0, disable priority interrupts
    And now all is OK.
    I have my doubts about that.

    IPEN defaults to 0 on Power-Up/Reset.
    So unless you have another RCON statement in your program that already changed it to 1, that statement will have no effect.
    <br>
    DT

  4. #4
    Join Date
    Nov 2007
    Location
    South-West of Australia. A small town called Denmark. 'Where the forest meets the sea.'
    Posts
    136


    Did you find this post helpful? Yes | No

    Default ASM code

    Darryl & Joe

    Thanks for your comment - yes I do have code that sets RCON,7 (IPEN)
    to enable priority levels on interrupts.

    I've made an XY plotter/scanner using stepper motors and cheap Chinese linear bearings (about $10 each!). Only got the 'movement/plot bit' done so far and will add the scan later (Paralax Line Scan module).

    I went to assembler so that I could drive X and Y motors at the same time to get diagonal moves. This bit of the code works like:

    1. In PBP set the X_steps (Nx) and Y_steps (Ny)
    2. In PBP work out the periods of the pulses (Px znd Py) so that the time to make the X/Y moves are the same T(move) = Nx.Px = Ny.Py
    3. Send the variables to the ASM code
    4. Use Timer0 to interrupt (high priority) for Px
    5. Use Timer1 to interrupt for Py
    6. Decrament Nx whenever an X pulse is sent and halt at zero
    7. Stop and return to PBP

    It's the 'stopping' that took me two days to sort out and the guilty party was the IPEN bit - and an inexperienced asm programmer!

    Happy to post the code - sorry - I've used TABS and it looks terrible at the moment:

    Code:
    ;******************************************************************************
    ;                                                                             *
    ;	Filename: WL_Scanner_01                                                *
    ;	Date:	February 2010                                                   *
    ;                                                                             * 
    ;******************************************************************************
    
    ;******************************************************************************
    ;                                                                             *
    ;	Function: Drive two stepper motors with timers/interrupts	        *
    ;	Files Required: P18F8722.INC                                           *
    ;                                                                             *
    ;******************************************************************************
    
    	LIST P=18F8722		; Directive to define processor
    	#include <P18F8722.INC>	; Drocessor specific variable definitions
    	
    ;******************************************************************************
    ;	Configuration bits
    	CONFIG	OSC = HSPLL	; Run at 4X speed
    	CONFIG	CP0=OFF	; Disable code protect				
    	CONFIG	PWRT = OFF	; Power up timer off so DEBUG works            
    	CONFIG	WDT=OFF	; WDT off
    	CONFIG	LVP = OFF	; LVP off
    	CONFIG	WAIT = OFF	; External bus data wait disabled
    ;******************************************************************************
    ;	Variable definitions in data memory
    WREG_TEMP	equ	0x010		; Variable used for context saving 
    STATUS_TEMP	equ	0x011		; Variable used for context saving
    BSR_TEMP	equ	0x012		; Variable used for context saving
    Count_pulse	equ	0x013		; Loop delay in 5 uS pulse to motor driver
    X_delay_lb	equ	0x014		; Inter-pulse delay for X axis, high byte
    X_delay_hb	equ	0x015		; Inter-pulse delay for X axis, low byte
    Y_delay_lb	equ	0x016		; Inter-pulse delay for Y axis, high byte
    Y_delay_hb	equ	0x017		; Inter-pulse delay for Y axis, low byte
    X_steps_lb	equ	0x018		; Number of steps to do on X axis
    X_steps_hb	equ	0x019		; Y steps not needed as Tx.Dx=Ty.Dy
    
    ;******************************************************************************
    ;	Reset vector in program memory
    	ORG	0x0000
    	goto	Main_ASM		; Go to start of main code
    ;******************************************************************************
    ;	High priority interrupt vector in program memory
    	ORG	0x0008
    	goto	High_int		; Go to high priority interrupt routine
    ;******************************************************************************
    ;	Low priority interrupt vector and routine in program memory, when Timer1
    ;	overflows send out stepper drive pulse for Y axis on PORTD.3
    	ORG	0x0018
    	movff	STATUS,STATUS_TEMP	; save STATUS register
    	movff	WREG,WREG_TEMP	; save working register
    	movff	BSR,BSR_TEMP		; save BSR register
    
    	bcf	INTCON,7		; Disable all interrupts
    	bsf	PORTD,3		; High PORTD.3
    	call	Pulse_out		; Delay for 10 microseconds
    	bcf	PORTD,3		; High PORTD.3
    	bcf	PIR1,0			; Clear Timer1 interrupt flag
    	movff	Y_delay_hb,TMR1H	; Load Timer1 with Y_delay
    	movff	Y_delay_lb,TMR1L	; Load timer1 with Y_delay
    	
    	movff	BSR_TEMP,BSR		; restore BSR register
    	movff	WREG_TEMP,WREG	; restore working register
    	movff	STATUS_TEMP,STATUS	; restore STATUS register
    	
    	bsf	INTCON,7		; Enable interrupts	
    	retfie
    	
    ;******************************************************************************
    ;	High priority interrupt routine, when Timer0 overflows, send out stepper
    ;	drive pulse for X axis on PORTD.0
    High_int:
    	bcf	INTCON,7		; Disable interrupte
    	bsf	PORTD,0		; High PORTD.0
    	call	Pulse_out		; Send 5uS pulse on PORTB.0
    	bcf	PORTD,0		; Low PORTD.0
    	bcf	INTCON,2		; Clear Timer0 interrupt flag
    	movff	X_delay_hb,TMR0H	; Load timer0 with X_delay
    	movff	X_delay_lb,TMR0L	; Load timer0 with X_delay
    		
    	decf	X_steps_lb		; Decrement X_steps				
    	bsf	INTCON,7		; Enable interrupts						
    	retfie	1
    	
    ;******************************************************************************
    ;                                                                             *
    ;                               SUBROUTINES                                   *
    ;                                                                             * 
    ;******************************************************************************
    	
    Pulse_out:			; Delay = 3.n + 7 [0.1 microseconds]
    	movlw	0xff		; Load w with n
    	movwf	Count_pulse	; Load Count with n
    Pulse_loop:
    	decfsz	Count_pulse	; Decrament the file Count
    	goto	Pulse_loop	; Loop if not zero
    	return
    	
    ;******************************************************************************
    ;                                                                             *
    ;                                  MAIN ASM                                   *
    ;                                                                             * 
    ;******************************************************************************
    	
    Main_ASM:	
    	clrf	TRISA			; PORTA is output
    	clrf	TRISB     		; PORTB is output
    	clrf	TRISC			; PORTC is output
    	clrf	TRISD     		; PORTD is output
    	clrf	TRISE			; PORTE is output
    	clrf	TRISF			; PORTF is output
    	clrf	TRISG			; PORTG is output
    	clrf	TRISH			; PORTH is output
    	clrf	TRISJ			; PORTJ is output
    	
    	clrf	PORTA			; Clear PORTA
    	clrf	PORTB			; Clear PORTB
    	clrf	PORTC			; Clear PORTC
    	clrf	PORTD			; Clear PORTD
    	clrf	PORTE			; Clear PORTE
    	clrf	PORTF			; Clear PORTF
    	clrf	PORTG			; Clear PORTG
    	clrf	PORTH			; Clear PORTH
    	clrf	PORTJ			; Clear PORTJ
    	
    	movlw	0x0f
    	movwf	ADCON1			; PORTA is digital I/O
    	movlw	0x07
    	movwf	CMCON			; Comparator off
    	
    ; Set up interrupt conditions for Timer0 and Timer1	
    	bsf	RCON,7			; Enable priority levels on interrupts,IPEN=1
    	bsf	INTCON,7		; Enable all high priority interrupts
    	bsf	INTCON,6		; Enable all low priority interrupts
    	bcf	INTCON,3		; Disable PORTB interrupts
    	bsf	INTCON2,2		; Make Timer0 overflow high priority
    	bcf	IPR1,0			; Make Timer1 overflow low priority
    	bsf	INTCON,5		; Enable Timer0 overflow flag
    	bsf	PIE1,0			; Enable Timer1 overflow flag		
    	
    ; Set up Timer0 conditions				
    	bcf	T0CON,6		; Timer0 uses 16 bits
    	bcf	T0CON,5		; Timer0 uses internal osc
    	bcf	T0CON,4		; Timer0 count on rising edge og osc
    	bsf	T0CON,3		; Timer0 pre-scaler not assigned
    	clrf	TMR0L			; Zero the clock
    	clrf	TMR0H			; Zero the clock				
    	bsf	T0CON,7		; Timer0 on
    		
    ; Set up Timer1 conditions
    	bsf	T1CON,7		; Timer1 uses 16 bits
    	bcf	T1CON,1		; Timer1 uses internal osc
    	clrf	TMR1L			; Zero the clock
    	clrf	TMR1H			; Zero the clock
    	bsf	T1CON,0		; Timer1 on	
    	
    ;	Temp code to simmulate PBP input for the delays
    	movlw	0x00
    	movwf	X_delay_lb
    	movlw	0x00
    	movwf	X_delay_hb
    	movlw	0x00
    	movwf	Y_delay_lb
    	movlw	0x00
    	movwf	Y_delay_hb
    	movlw	0xff
    	movwf	X_steps_lb
    	movlw	0xff
    	movwf	X_steps_hb					
    ;	End of Temp code	
    
    ; Check if X_steps_lb=0 (decremented in high priority interrupt)
    ; If so, check X_steps_hb and if zero, end
    ; If not, decrement X_steps_hb, set X_steps_lb and go again	
    Main_loop:
    	movff	X_steps_hb,PORTC
    	;comf	PORTC,1	; LEDS active low so invert
    	movff	X_steps_lb,PORTD
    	;comf	PORTD,1				
    	tstfsz	X_steps_lb	; Test, skip next if zero
    	goto	Main_loop	; More steps to do, so loop
    	tstfsz	X_steps_hb	; Test, skip next if zero
    	goto	Re_load_lb
    	goto	All_done
    	
    Re_load_lb:
    	decf	X_steps_hb,1	; Decrement hb and then carry to lb
    	setf	X_steps_lb	; Decremented hb, so load ff to lb
    	goto	Main_loop
    	
    All_done:	
    	bcf	RCON,7		; Clear IPEN=0, disable priority interrupts
    	end			; IPEN must be cleared or asm keeps running
    Regards Bill Legge

  5. #5
    Join Date
    Nov 2007
    Location
    South-West of Australia. A small town called Denmark. 'Where the forest meets the sea.'
    Posts
    136


    Did you find this post helpful? Yes | No

    Default ASM code

    And some more help please.

    I'm now having difficulty in putting the asm code into a PBP program:

    1. Running on a PIC18F8722.
    2. Low and high priority interrupts are used BUT IN THE ASM CODE ONLY.
    3. The action to be taken on interrupt is only in the ASM code.

    So far I have:

    1. Deleted the asm configs and done them in PBP
    2. Listed the variables like:

    Code:
    WREG_TEMP       var byte    $20     System     ; Variable used for context saving 
    STATUS_TEMP     var byte    Bank0   System     ; Variable used for context saving
    BSR_TEMP        var byte    Bank0   System	; Variable used for context saving
    Count_pulse     var byte    Bank0   System     ; Pulse duration = 3.n + 7
    X_delay_lb      var byte    Bank0   System     ; Subtracted from $ffff to get X delay 
    X_delay_hb      var byte    Bank0   System     ; ..result loaded into Timer0_High and Timer0_Low
    Y_delay_lb      var byte    Bank0   System     ; Subtracted from $ffff to get Y delay
    Y_delay_hb      var byte    Bank0   System     ; ..result loaded into Timer1_High and Timer1_Low
    X_steps_lb      var byte    Bank0   System     ; Y steps not needed because different X/Y pulse
    X_steps_hb      var byte    Bank0   System     ; ..frequencies make Nx.Dx = Ny.Dy
    I have deleted (Should I have kept them?) these bits of the original ASM code:

    Code:
    LIST P=18F8722              ; Directive to define processor
    #include <P18F8722.INC> ; Drocessor specific variable definitions
    Should I use the instructions (although my interrupts occur in ASM only):

    DEFINE INTLHAND Label
    DEFINE INTHAND Label

    I have had a good read of the PBP handbook and DT's interrupt code and examples - but am still missing something?

    Regards Bill legge

  6. #6
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    Bill,

    I don't have time to give you a complete answer right now, but I believe you are making this too hard.

    If you use DT-Ints, you don't need to worry about saving/restoring the registers, or any ORGs. All of that is taken care of for you.
    All I can do right now is give you a snippet of some code that I have handy.

    This code has only high priority INTs, but low-priority INTS are done the same way.



    Go to Darrel's page and read about using his structure. It will really help you a lot.

    You will notice that the code snippet below has both PBP and ASM ints.

    MasterClock is defined as a BankA SYSTEM var so that PBP can access it.
    All the vars (including the ASM vars) are declared in PBP.



    Code:
    '----------------------------------  End of basic assignment section ---------------------------------  
      
    
            INCLUDE "DT_INTS-18.bas"         ; Base Interrupt System
            INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
      
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
                  INT_Handler    TMR0_INT,   SystemTimer,   ASM,  yes 
                  INT_Handler    RX1_INT,    _GetCharPort1,    PBP,  yes
                  INT_Handler    RX2_INT,    _GetCharPort2,    PBP,  yes
                  INT_Handler    INT2_INT,   _GetXData,    PBP,  yes
              endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
                             
    Goto OverInt
    
    '---[INT - interrupt handlers]-----------------------------------------------
    
    ASM 
    SystemTimer
             movff   0x0B,TMR0H  ;   10 msec with /16 prescaler
             movff   0xDC,TMR0L
          
             infsnz  MasterClock
             incf    MasterClock + 1
    
           INT_RETURN
    ENDASM
    If no one else posts a better response, I'll send you more information tomorrow.
    Charles Linquist

  7. #7
    Join Date
    Nov 2007
    Location
    South-West of Australia. A small town called Denmark. 'Where the forest meets the sea.'
    Posts
    136


    Did you find this post helpful? Yes | No

    Default ASM code

    Charles,

    Thanks, I will have a go at doing the work with DT's interrupts - I'm pretty sure that you are correct.

    I wanted to use my own ASM to:

    1. Learn more about ASM
    2. Learn more about MPLAB and debugging.
    3. Learn how to glue ASM into PBP.

    The most useful things learnt over the last few days were:

    1. Debugging ASM with interrupts in it.
    2. After a quickish look at DT's interrupt code I think I may now be able to follow it.

    I'd much appreciate your input on getting the code on this thread to run in PBP. Despite playing with 'org' and so on, I keep getting lots of:

    Code:
    overwrite previous address contents error
    Regards Bill Legge

  8. #8
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bill Legge View Post

    I'd much appreciate your input on getting the code on this thread to run in PBP. Despite playing with 'org' and so on, I keep getting lots of:

    Code:
    overwrite previous address contents error
    Regards Bill Legge
    You must be trying to set the configuration fuses more than once.
    In the PBP part of the code?
    In the ASM part?
    In the *.inc file?
    http://www.picbasic.co.uk/forum/showthread.php?t=543
    Dave
    Always wear safety glasses while programming.

Similar Threads

  1. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 22:14
  2. Adding PBPro code to an ASM file - how to?
    By wjsmarine in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 9th January 2010, 18:49
  3. How much code space do PBP statements use.
    By Darrel Taylor in forum Code Examples
    Replies: 5
    Last Post: - 13th February 2009, 21:31
  4. Loop with two motor and 2 sensors
    By MrRoboto in forum mel PIC BASIC
    Replies: 4
    Last Post: - 8th December 2008, 23:40
  5. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 08:26

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts