Looking for work? Check out our jobs area.
*/
*/

View \MMOTOR.ASM

Hc11 program for automatic motor control

Submitted By: WEBMASTER
Rating: Not rated (Rate It)


*       Program for the HC11
** MMOTOR - manual motor operation
*       With the use of a terminal this program allows a user
*       to control the duty cycle percentage of a pwm signal
*       thus controlling the speed of a motor.  The direction of the
*       motor can also be changed with this program.  The program
*       displays menus that guide the user.  The user will be
*       prompted for a direction then a duty cycle percentage.  To
*       return to the direction prompt depress the delete key.  The
*       function keys are used to dictate the direction.  Out of reset
*       the program will display an introductory message then will
*       wait for any key to be depressed before continuing.  This
*       program takes advantage of the many routines available
*       in BUFFALO for I/O and initialization of the SCI port and
*       the interrupt vectors.  The frequency of the pwm signal
*       is a constant and is approximately 14khz.
*
*       This program is to be used with any HC11 with BUFFALO
*       (monitor and debug program) availabe in ROM.  The program length
*       is approximately 512 bytes and can therefore also be used with
*       EEPROM versions of the HC11.
*
**      The HC11 is used in conjunction with kits KITDEVB103 and KITDEVB118
*       and application notes AN1300 and AN1301 for dc brushed motor drive.
*       Kits and ap notes are availale through Motorola Literature Distribution.
*
*
*TIMER REGISTER ADDRESSES
REGBAS EQU     $1000           * Register base
OC1M    EQU     $0C             * OC1 action mask register
OC1D    EQU     $0D             * OC1 action data register
TOC1    EQU     $16             * Output compare 1 register
TOC2    EQU     $18             * Output compare 2 register
TCTL1  EQU     $20             * Timer control register 1
TMSK1  EQU     $22             * Timer interrupt mask register 1
TFLG1  EQU     $23             * Timer interrupt flag register 1
TCNT    EQU     $0E             * Timer counter register
 
*BUFFALO I/O AND INITIALIZATION ROUTINE ADDRESSES
INCHAR EQU     $FFCD           * Get character from terminal
OUTCRLF EQU     $FFC4           * Output a CR and LF to screen
OUTSTRG EQU     $FFC7           * Output a string
OTSTRGO EQU     $FFCA           * Out string w/o preceedin crlf
OUTA    EQU     $FFB8           * Output contents of acca
OUTLHLF EQU     $FFB2           * Cnvrt lft nibble to ascii & out
OUTRHLF EQU     $FFB5           * Cnvrt rt nibble to ascii & out
INIT    EQU     $FFA9           * Initialize I/O device in IODEV
VECINIT EQU     $FFD0           * Initialize vectors

*ADDITIONAL VARIABLE ADDRESSES AND CONSTANT EQUATES
AUTOLF EQU     $A6             * Auto lf flag byte
BAUD    EQU     $102B           * Baud select register
BPROT  EQU     $1035           * Block protect register
OPTION EQU     $1039           * Option register
EXTDEV EQU     $A8             * Buffalo variable 0=none, 1=acia
IODEV  EQU     $A7             * Buffalo var 0=sci, 1=acia, 2=duart
HOSTDEV EQU     $A9             * Buffalo var 0=sci, 1=acia
SP      EQU     $006F           * Default user stack pointer
UCCR    EQU     $006E           * Defaul user CCR
PERIOD EQU     $0000           * Program location of constant period
PERCENT EQU     $0002           * Program variable % duty cycle input
PWIDTH EQU     $0004           * Program variable pulse width
TRIBYTS EQU     $0006           * Program 24 bit # location
FLAGS  EQU     $0009           * Program flag byte
PORTB  EQU     $1004           * Port B address
EOT    EQU     $04             * End of transmission

*PSEUDO VECTOR EQUATES FOR OUTPUT COMPARE INTERRUPTS
PVOC1  EQU     $00DF
PVOC2  EQU     $00DC
 
*
**      START OF MAIN PROGRAM
*
        ORG     $B600           * Start of EEPROM
        LDS     #$0033          * User's stack area on EVB
        JSR     SETUP
*INTRODUCTION STATEMENT OUT OF RESET
        LDX     #INTRO          * Introduction message
        JSR     OUTSTRG         * Output messasge
        JSR     INCHAR          * Keep on screen till key depressed
*                               * then continue executing
URUN    JSR     INIT_OC         * Initialize the output compare registers
        CLR     PERCENT         * Clear percent hi byte
        CLR     PERCENT+1               * Clear percent lo byte
        CLI                     * Enable interrupts
        JSR     GET_DIR         * Display direction prompt &
*                               * get direction
ANOTHER JSR     OUTCRLF         * Output a cr and lf
        JSR     DSPLASP         * Display duty cycle percentage
        LDX     #SPDPRMT                * Prompt user for duty cycle %
        JSR     OUTSTRG         * Output prompt
        JSR     IN_SPD          * Get new Duty Cycle% from keybd
        BRSET   FLAGS $02 EXIT  * Exit if mode flag is set
        JSR     BCDHEX          * Convert from ascii bcd to hex
        JSR     MUL2BY1         * period*percent=tribyts
        JSR     DIV3BYT         * tribyts/100=pwidth(accd)
        STD     PWIDTH          * Store result in PWIDTH
        BSET    FLAGS $80               * Set the newspeed flag for OC2
        BRA     ANOTHER         * Repeat
EXIT    SEI                     * Disable interrupts
        BCLR    FLAGS $02               * Clear mode escape flag
        BRA     URUN            * Exit to mode prompt routine

*
* SETUP-        This subroutine configures the communication port
*       initializes interrupt vectors, sets the default user stack
*       and ccr, clears program flags, stores the period of the pwm
*       signal, and sets up the pseudo vectors for the output compares.
*
SETUP   LDAA    #$93            *
        STAA    OPTION          * adpu, dly, irqe, cop
        CLRA                    * 0 into acca
        STAA    BPROT           * Clear '
E9 eeprom block protect
        STAA    IODEV           * I/O through sci
        STAA    EXTDEV          * No external device
        JSR     VECINIT         * Initialize interrupt vectors
        LDX     #$0047          * $0047 into X
        STX     SP              * Default user stack
        LDAA    #$D0            * $D0 into acca
        STAA    UCCR            * Default user ccr
        CLR     HOSTDEV                 * Host = sci
        CLR     $4000           * Clear D flip-flop location
        JSR     INIT            * Initialize I/O device
        LDAA    #$32            * Change to 2400 baud for terminal
        STAA    BAUD
        LDAA    #$01
        STAA    AUTOLF          * Auto lf when cr occurs on
        LDAA    #
        CLR     FLAGS           * Clear all program flags
        LDD     #$008D          * Time between oc1 interrupts
        STD     PERIOD          * Save in period
*SETUP OF PSEUDO VECTORS***
        LDAA    #$7E            * Op code for jump
        STAA    PVOC1           * OC1 pseudo vector
        STAA    PVOC2           *       "
        LDD     #OC1ISR         * Address of OC1 interrupt service routine
        STD     PVOC1+1         * Finish JMP inst to OC1 routine
        LDD     #OC2ISR         * Address of OC2 interrupt servic
        STD     PVOC2+1         * Finish JMP inst to OC1 routine
        RTS
*
*INIT_OC-       This set of instructions initializes oc1 and
*       oc2 and sets toc1 and toc2 registers.
INIT_OC LDX     #REGBAS         * Set for indexed addressing
        LDAA    #%11000000              * Set OM2 & OML
        STAA    TCTL1,X         * OC2 sets its pin hi
        LDAA    #%01000000              * OC1 affects OC2 pin
        STAA    OC1M,X          * Sets OC1 action mask
        CLRA                    * OC1 sets all OCs low
        STAA    OC1D,X          * OC1 action data reg.
        LDD     PERIOD          * Period into accd
        LSLD                    * Period times 2
        ADDD    TCNT,X          * Add 2 periods of TCNT
        STD     TOC1,X          * Store in OC1 time
        ADDD    PERIOD          * Add period to OC1 time
        STD     TOC2,X          * Store OC2 time
        BCLR    TFLG1,X %00111111       * Clear OC1, OC2, &OC3 flags
        BSET    TMSK1,X %11000000       * Enable OCI & OC2 interrupts
        RTS
*
*GET_DIR-       This subroutine prompts the user for a direction
*       F1=fwd, F2=rev, then writes the appropriate byte to port b.
*       It also check for a flag to return to intro message
GET_DIR LDX     #DIR_MSG                * X points to message
        JSR     OUTSTRG         * Output message
        JSR     INCHAR          * Get character from terminal
        CMPA    #$46            * Not an "
F" then invalid repeat
*                               * terminal is sending ascii
*                               * F1='$4631' and F2='$4632'
        BNE     GET_DIR         * If "
F" then get 2nd character
        JSR     INCHAR          * Get second character from terminal
        CMPA    #$31            * =1 ?
        BNE     CMPARE2         * =1 then continue, else 2nd compare
        LDAA    #$01            * Portb0=1, portb1=0
        STAA    PORTB           * Store fwd bits in port b
        BRA     BACK            * Return from subroutine
CMPARE2 CMPA    #$32            * =2 ?
        BNE     GET_DIR         * If invalid char repeat prompt
        LDAA    #$02            * =2 then portb0=1, portb1=0
        STAA    PORTB           * Store reverse bits in port b
BACK    RTS

*DSPLYSPD-      This subroutine displays current % duty cycle message then
*       the current %. Ascii characters are at PERCENT
*
DSPLASP LDX     #SPDMSG         * X points to message
        JSR     OTSTRGO         * Out message w/o preceeding crlf
        LDAA    PERCENT         * Get first characer
        JSR     OUTA            * Output character
        LDAA    PERCENT+1               * Get 2nd character
        JSR     OUTA            * Output character
        RTS
*
*IN_SPD-        This subroutine takes characters for the new speed as a
*       a percentage. When a cr is received the input is com-
*       plete or when more than 2 characters without a cr the
*       input is assumed to be 100%. The inputs are stored at
*       location PERCENT (2 BYTES).
*
IN_SPD  JSR     INCHAR          * Get 1st input from terminal
        CMPA    #$0D            * cr ?
        BEQ     IN_SPD          * If cr then try again
        CMPA    #$7F            * Del ?
        BEQ     SETFLG          * If del then setflag,else continu
        STAA    PERCENT         * Save first charcater
        JSR     INCHAR          * Get 2nd input from terminal
        CMPA    #$0D            * CR ?
        BEQ     SHIFT           * If cr then only on digit, shift
        CMPA    #$7F            * DEl ?
        BEQ     SETFLG          * If del then setflag, else contin
        STAA    PERCENT+1               * Save 2nd character
        JSR     INCHAR          * Need a cr to indicate # entered
        CMPA    #$0D            * cr ?
        BEQ     RETURN          * If cr then return, else continue
        CMPA    #$7F            * Del ?
        BEQ     SETFLG          * If del the setflag,else continue
*                               * Redisplay prompt, invalid # entered
        JSR     OUTCRLF         * Output crlf
        LDX     #SPDPRMT                * X points to message
        JSR     OTSTRGO         * Output message w/o preceeding cr
        BRA     IN_SPD          * Start again
SETFLG  BSET    FLAGS $02               * Set mode escape flag
        BRA     RETURN          * Branch to return from subroutine
SHIFT   LDAB    PERCENT                 * Only one digit, char into accb
        LDAA    #$20            * Ascii space into acca
        STD     PERCENT         * Store double at percent
RETURN  RTS

*
*BCD_HEX-       This subroutine takes the two bytes at PERCENT
*       as an ascii two digit bcd number and converts to a hex equiv-
*       alent and returns the result in ACCA.
BCDHEX  LDAA    PERCENT         * Get hi byte of ascii bcd number
        CMPA    #$20            * If a space then only one digit
        BNE     TUDGITS         * not space then 2 digits
        LDAA    PERCENT+1               * Only one digit
        ANDA    #$0F            * Mask out the 4 msbs
        BRA     DONE            * result in acca so done
TUDGITS ANDA    #$0F            * Mask out the 4 msbs of hi byte
        LDAB    #$0A            * Ten into accb
        MUL                     * Acca*accb=accb(result of mul)
        LDAA    PERCENT+1               * Lo byte of ascii num into acca
        ANDA    #$0F            * Mask out the 4 msbs of lo byte
        ABA                     * acca+accb=hex number in acca
DONE    RTS

*MUL2BY1-       This subroutine multiplies a 2 byte number @ PERIOD
*       as a 1byte number located in acca with the result stored
*       number located in ACCB with the result stored in location
*       TRIBYTS
MUL2BY1 PSHA                    * Save hex number on the stack
        LDAB    PERIOD+1                * Get low byte of period
        MUL                     * multiply
        STAB    TRIBYTS+2               * Lowest byte of total result
        PULB                    * Get copy of hex rep of %
        PSHA                    * To be added to next mul result
        LDAA    PERIOD          * Get high byte of period
        MUL                     * Multiply
        STD     TRIBYTS         * Store this result in TRIBYTS
        PULB                    * Part to be added to last mul
        CLRA                    * Hi byte of accd = 0
        ADDD    TRIBYTS         * Add accd to last mul result
        STD     TRIBYTS         * 24 bit result @ TRIBYTS
        RTS
*
*DIV3BYT-       This subroutine divides a 24 bit number @ TRIBYTS
*       by a number in X with the result to be in ACCD
*
DIV3BYT LDD     TRIBYTS         * Get upper 16 bits of dividend
        LDX     #$0064          * Load X with divisor
        IDIV                    * Divide
        PSHB                    * Save remainder
        XGDX                    * Put quotient in accb
        PULA                    * Remainder as hi byte in accd
        PSHB                    * Save hi byte of result
        LDAB    TRIBYTS+2               * Get last byte of dividend
        LDX     #$0064          * Load X with divisor
        IDIV                    * Divide
        XGDX                    * Quotient of 2nd div in accb
        PULA                    * Get hi byte of total result
*                               * Total result now in accd
        RTS

* OC1 INTERRUPT SERVICE ROUTINE
OC1ISR  LDX     #REGBAS         * Set for indexed addressing
        LDD     TOC1,X          * Get old OC1 time
        ADDD    PERIOD          * Add one period
        STD     TOC1,X          * Store next OC1 time
        BCLR    TFLG1,X %01111111       * Clear OC1 flag bit
        RTI

* OC2 INTERRUPT SERVICE ROUTINE
OC2ISR  LDX     #REGBAS         * Set for indexed addressing
        BRSET   FLAGS $80 NEWPW * bra if newspeed flag set
        LDD     TOC2,X          * Get old OC2 tim
        ADDD    PERIOD          * Add a period
        STD     TOC2,X          * Store next OC2 time
        BCLR    TFLG1,X %10111111       * Clear OC2 flag
        RTI
NEWPW   LDD     TOC1,X          * Use time for oc1 as reference
        ADDD    PERIOD          * Add a period
        ADDD    PERIOD          * Add a second period
        SUBD    PWIDTH          * Subtract pw % to get oc2
        STD     TOC2,X          * Store next oc2 time
        BCLR    FLAGS %10000000 * Clear newspeed flag
        BCLR    TFLG1,X %10111111       * Clear OC2 flag
        RTI
*
*MESSAGES
*
INTRO   FCC     '       MC68HC11/ICePAK MOTOR CONTROL'
        FCB     $0D
        FCB     EOT
DIR_MSG FCB     $0D
        FCC     'ENTER DIRECTION (F1=fwd, F2=rev): '
        FCB     EOT
SPDMSG  FCC     'PWM DUTY CYCLE %: '
        FCB     EOT
SPDPRMT FCC     'ENTER PWM DUTY CYCLE %(1-99): '
        FCB     EOT

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.
Resource Listings