PROCESSOR 16C84 ; TITLE "STP1.ASM - PIC 16C84 STEPPING MOTOR DRIVER" ;USING PIC16C84 ; ;USES 4.000 MHz RESONATOR OR RC OSCILLATOR (SET CONFIGURATION TO SUIT) ;WATCHDOG TIMER OFF ; ;STP1 FIRST VERSION -/9/96 ; RADIX HEX LIST ; #DEFINE INDF 0000 ;PAGE 0 & 1 INDIRECT ADDRESS #DEFINE RTCC 0001 ;PAGE 0 #DEFINE OPTN 0001 ;PAGE 1 (0081) #DEFINE PCL 0002 ;PAGE 0 & 1 PC LOW BYTE #DEFINE STATUS 0003 ;PAGE 0 & 1 #DEFINE FSR 0004 ;PAGE 0 & 1 #DEFINE PORTA 0005 ;PAGE 0 #DEFINE TRISA 0005 ;PAGE 1 (0085) #DEFINE PORTB 0006 ;PAGE 0 #DEFINE TRISB 0006 ;PAGE 1 (0086) #DEFINE EEDATA 0008 ;PAGE 0 #DEFINE EECON1 0008 ;PAGE 1 (0088) #DEFINE EEADR 0009 ;PAGE 0 #DEFINE EECON2 0009 ;PAGE 1 (0089) #DEFINE PCLATH 000A ;PAGE 0 & 1 #DEFINE INTCON 000B ;PAGE 0 & 1 ; #DEFINE DELAY0 000C ;PAGE 0 DELAY LOOP COUNTER #DEFINE DELAY1 000D ;PAGE 0 DELAY LOOP COUNTER #DEFINE DELAY2 000E ;PAGE 0 DELAY LOOP COUNTER #DEFINE UPBYT 000F ;PAGE 0 STEP PAGE ADDRESS #DEFINE INDEX 0010 ;PAGE 0 STEP NUMBER #DEFINE FLAGS1 0011 ;PAGE 0 SYSTEM FLAGS 1 #DEFINE SPEED 0012 ;PAGE 0 SPEED VALUE STORE #DEFINE SPEED1 0013 ;PAGE 0 SPEED1 #DEFINE SPEED2 0014 ;PAGE 0 SPEED2 #DEFINE STPSL 0015 ;PAGE 0 LSD OF STEP COUNTER #DEFINE STPSM 0016 ;PAGE 0 USD OF STEP COUNTER ; ; STATUS REGISTER BITS #DEFINE CARRY 0X03,0 ;CARRY FLAG #DEFINE DCARRY 0X03,1 ;DECIMAL CARRY FLAG #DEFINE ZERO 0X03,2 ;ZERO FLAG #DEFINE RPAGE 0X03,5 ;REGISTER PAGE SELECT ; ; OPTION REGISTER BITS #DEFINE PS0 0X01,0 ;P1 - PRESCALER SELECT VALUES #DEFINE PS1 0X01,1 ; '' #DEFINE PS2 0X01,2 ; '' #DEFINE PSA 0X01,3 ;P1 - PRESCALER ASSIGNMENT #DEFINE RTE 0X01,4 ;P1 - TMR0 EDGE (WHEN EXTERNL) #DEFINE RTS 0X01,5 ;P1 - TMR0 SOURCE #DEFINE INTEDG 0X01,6 ;P1 - B0 INTERRUPT EDGE #DEFINE RBPU 0X01,7 ;P1 - PORTB WEAK PULL UPS ; ; INTCON REGISTER BITS #DEFINE RBIF 0X0B,0 ;PORTB CHANGE FLAG #DEFINE INTF 0X0B,1 ;B0 INT FLAG #DEFINE T01F 0X0B,2 ;TIMER 1 INTERRUPT FLAG #DEFINE RBIE 0X0B,3 ;PORTB CHANGE INTERRUPT ENABLE #DEFINE INTE 0X0B,4 ;B0 INTERRUPT ENABLE #DEFINE T01E 0X0B,5 ;TIMER 1 INTERRUPT ENABLE #DEFINE EEIE 0X0B,6 ;EEPROM WRITE INT #DEFINE GIE 0X0B,7 ;GLOBAL INTERRUPT ENABLE ; ; PORTA BITS #DEFINE SWA1 0X05,0 ;P0 - A SWITCH INPUT 1 #DEFINE SWA2 0X05,1 ;P0 - 2 #DEFINE SWA3 0X05,2 ;P0 - 3 #DEFINE SWA4 0X05,3 ;P0 - 4 #DEFINE SWA5 0X05,4 ;P0 - 5 ; ; PORTB BITS #DEFINE PHASE3 0X06,0 ;P0 - MOTOR DRIVE PHASES 3 #DEFINE PHASE4 0X06,1 ;P0 - 4 #DEFINE PHASE2 0X06,2 ;P0 - 2 #DEFINE PHASE1 0X06,3 ;P0 - 1 #DEFINE SWB1 0X06,4 ;P0 - B SWITCH INPUT 1 #DEFINE SWB2 0X06,5 ;P0 - 2 ; #DEFINE 0X06,6 ;P0 - PROGRAMMING INPUTS ; #DEFINE 0X06,7 ;P0 - PROGRAMMING INPUTS ; ; FLAGS1 BITS #DEFINE FWDFLG 0X11,0 ;P0 - FORWARD RUN FLAG #DEFINE RUNFLG 0X11,1 ;P0 - RUN FLAG #DEFINE STEPF 0X11,2 ;P0 - FULL STEP FLAG #DEFINE STEPC 0X11,3 ;P0 - STEPS DONE FLAG ; ; ORG 0x000 ;RESET VECTOR GOTO FIRST ; ; ORG 0X004 ;INTERRUPT VECTOR GOTO SERVE1 ;INTERRUPT SERVICE ROUTINE ; FIRST ORG 0x005 ;FIRST INSTRUCTION NOP NOP NOP GOTO START ; ; ORG 0X10 START BCF RPAGE ;MAKE SURE PAGE 0 CLRWDT ;CLEAR WATCHDOG TIMER ; ;**************************************************************************** ;* CLEAR REGISTERS * ;CLEAR OPERATING REGISTERS LOWER BANK MOVLW 0X0C ;LOAD FIRST REGISTER ADDRESS MOVWF FSR ;TO FILE SELECT REGISTER NXREG CLRF INDF ;CLEAR SELECTED REGISTER INCF FSR,1 ;INCREMENT POINTER MOVLW 0X30 ;LOAD TOP LOCATION +1 TO W SUBWF FSR, 0 ;SUBTRACT FROM CURRENT ONE BTFSS ZERO ;CHECK TO SEE IF EQUAL GOTO NXREG ;IF NOT - LOOP ; ;**************************************************************************** ;* ;SET UP INITIAL PORT DATA MOVLW B'00010000' ;MOVE DATA FOR PORTA ;Note that A4 MUST be high if ;it is to be used as an input ;otherwise open collector will ;pull it down. MOVWF PORTA ;LOAD TO PORTA REGISTER MOVLW B'00000000' ;MOVE DATA FOR PORTB MOVWF PORTB ;LOAD TO PORTB REGISTER ; ;***************************************************************************** ; PAGE 1 ;SET UP PORT I/O AND OPTION REGISTER CONTENTS BSF RPAGE ;SET PAGE 1 ; MOVLW B'00011100' ;SET A1&2 TO OUTPUT, MOVWF TRISA ;LOAD TO I/O CONTROL REG A MOVLW B'11110000' ;SET B0-3 TO OUTPUT MOVWF TRISB ;LOAD TO I/O CONTROL REG B NOP NOP ; BCF RBPU ;ENABLE PORTB PULL UPS BSF INTEDG ;SET B0 INT ON RISING EDGE BCF RTS ;TIMER COUNTS INT CLOCK BCF RTE ;LOW-HIGH INT EDGE (UNUSED) BCF PSA ;ASSIGN PRESCALER TO TIMER BSF PS0 ;SET UP PRESCALER TO /256 BSF PS1 ; '' BSF PS2 ; '' ; BCF RPAGE ;BACK TO PAGE 0 ; PAGE 1 ;***************************************************************************** ; CLRF INTCON ;CLEAR ALL INTERRUPTS & FLAGS ; ;Set up operating register values & enable interrupts. A motor will be driven ;one step upon each interrupt. Interrupt timing is set by the value in RTCC ;and the prescaler setting (bits PS0, PS1, and PS2 select this - see PIC data) ;An interrupt is generated each time the RTCC value overflows from FF to 0. ;This means that a high value produces the highest speed, and 0 produces the ;minimum speed. With the MD35 motor a maximum speed of F8 can be loaded, but ;the motor may not start at this speed if it has a high inertia load. Trial ;and error will determine the best settings. If the speed is set too high the ;motor may simply refuse to move, or jitter about. A fully developed control ;program would accelerate the motor by increasing the step rate automatically ;this is beyond the scope of the simple program here. ; ; ;Step switching sequence is stored on memory page 2 in a table 8 steps long ;Full stepping just skips the intermediate Half steps. ; ; ;The next lines load register UPBYTE with the table page (2) and load the step ;pointer register ;(INDEX) with zero to indicate the first step location. ; MOVLW 0X02 ;LOAD DATA STRING POINTER MOVWF UPBYT ;FOR UPPER ADDRESS BYTE CLRF INDEX ;ZERO LOWER ADDRESS POINTER ; ;**************************************************************************** ;THERE ARE TWO PROGRAM OPTIONS - ;1) IS A DIRECT DRIVE OPERATION USING SWA3 AND SWA5 TO CONTROL THE MOTOR IN ;FORWARD AND REVERSE DIRECTIONS ;2) IS A SEQUENCE OF OPERATIONS DRAWN FROM A TABLE OF SPEED, DIRECTION, AND ;STEP NUMBERS. THIS SEQUENCE CAN BE EXTENDED AS REQUIRED, OR LOOPED WITH A ;SIMPLE GOTO INSTRUCTION ; ; ; ;PROGRAM OPTION 1) ;select required option ; GOTO DDRIVE ;by cancelling unwanted ;PROGRAM OPTION 2) ;option with a leading ';' GOTO SQRUN ; ;**************************************************************************** ;DDRIVE - OPTION 1 DIRECT DRIVE ;select full or half step mode ; ; DDRIVE BSF STEPF ;SET FOR FULL STEP, ;CLEAR FOR HALF STEP ; ; ;select speed counter value ; MOVLW 0X4C ;LOAD VALUE FOR SPEED COUNTER MOVWF SPEED ;INTO SPEED REGISTER MOVWF RTCC ;AND INITIALISE RTCC REGISTER ; BSF T01E ;TURN ON TIMER INTERRUPT BSF GIE ;AND ENABLE GLOBAL INTERRUPTS ; ; ;Run loop - tests push switches and runs forward or reverse in response ; RUNING BTFSS SWA3 ;TEST 'FORWARD' SWITCH GOTO FWDRUN BTFSS SWA5 ;TEST 'REVERSE' SWITCH GOTO REVRUN ; BCF RUNFLG ;CLEAR RUN FLAG 'STOP' GOTO RUNING ;LOOP FOREVER ; FWDRUN BSF FWDFLG ;SET DIRECTION BSF RUNFLG ;SET TO RUN GOTO RUNING ;LOOP FOREVER ; REVRUN BCF FWDFLG BSF RUNFLG ;SET TO RUN GOTO RUNING ;LOOP FOREVER ; ;**************************************************************************** ; SERVE1 INTERRUPT SERVICE ROUTINE ; SERVE1 MOVF SPEED,0 ;RELOAD SPEED COUNTER VALUE MOVWF RTCC ;INTO TIMER COUNT UP REGISTER ; BTFSS RUNFLG ;TEST RUN FLAG GOTO ENDSTP ;IF NOT SET, EXIT ; BTFSC STEPF ;TEST FLAG FOR FULL STEP CALL DRIVE ;FULL STEP CALL 'DRIVE'TWICE ;TO JUMP OVER HALF STEPS CALL DRIVE ;WORK OUT FOLLOWING STEP ; CALL STEP ;EXECUTE STEP ; CALL STPCNT ;DECREMENT POSITION COUNTERS ; ENDSTP BCF T01F ;CLEAR INTERRUPT FLAG RETFIE ;RETURN FROM INTERRUPT ; ;**************************************************************************** ; ;**************************************************************************** ; DRIVE CALCULATES STEP NUMBER & LOADS INTO INDEX ; DRIVE BTFSS FWDFLG ;TEST DIRECTION FLAG GOTO REVSE ;IF CLEAR REVERSE ; ; ;FORWARD INCF INDEX,1 ;INCREMENT STEP COUNTER BTFSC INDEX,3 ;8 HALF STEPS? CLRF INDEX ;IF 8 RESET TO ZERO RETURN ; ; ;REVERSE REVSE MOVF INDEX,1 ;TEST VALUE OF STEP COUNTER BTFSC ZERO ; BSF INDEX,3 ;IF ZERO RELOAD DECF INDEX,1 ;AND DECREMENT RETURN ; ;**************************************************************************** ; ;**************************************************************************** ;SQRUN OPTION2 MOTOR SEQUENCE DRIVE ; SQRUN ; ;first run: ; MOVLW 0X02 ;SET NUMBER OF STEPS MOVWF STPSM ;MSD MOVLW 0XA0 ; MOVWF STPSL ;LSD BSF FWDFLG ;SET DIRECTION BSF RUNFLG ;SET TO RUN MOVLW 0X80 ;LOAD VALUE FOR SPEED COUNTER MOVWF SPEED ;INTO SPEED REGISTER CALL RUNSTP ; ; ;second run: ; MOVLW 0X02 ;SET NUMBER OF STEPS MOVWF STPSM ;MSD MOVLW 0XA0 ; MOVWF STPSL ;LSD BCF FWDFLG ;SET DIRECTION BSF RUNFLG ;SET TO RUN MOVLW 0XA0 ;LOAD VALUE FOR SPEED COUNTER MOVWF SPEED ;INTO SPEED REGISTER CALL RUNSTP ; ; ;third run: ; ;same speed so leave previous ; ;values MOVLW 0X02 ;SET NUMBER OF STEPS MOVWF STPSM ;MSD MOVLW 0XA0 ; MOVWF STPSL ;LSD BSF FWDFLG ;SET DIRECTION CALL RUNSTP ; ; ; ;forth run: ; MOVLW 0X10 ;SET NUMBER OF STEPS MOVWF STPSM ;MSD MOVLW 0XA0 ; MOVWF STPSL ;LSD BCF FWDFLG ;SET DIRECTION BSF RUNFLG ;SET TO RUN MOVLW 0XF4 ;LOAD VALUE FOR SPEED COUNTER MOVWF SPEED ;INTO SPEED REGISTER CALL RUNSTP ; LAST GOTO LAST ;LAST MOVE COMPLETED ; ; RUNSTP BCF STEPC ;CLEAR FLAG MOVF SPEED,0 ;LOAD SPEED REGISTER INTO W MOVWF RTCC ;AND INITIALISE RTCC REGISTER ; BSF T01E ;TURN ON TIMER INTERRUPT BSF GIE ;AND ENABLE GLOBAL INTERRUPTS ; RUNIN BTFSS STEPC ;LOOP WAITING FOR INTERRUPTS GOTO RUNIN ;UNTIL FLAG IS SET BCF GIE ;THEN DISABLE INTERRUPTS RETURN ;AND RETURN ; ; ;**************************************************************************** ;STPCNT - STEP COUNTING ROUTINE ; STPCNT MOVF STPSM,1 ;IS MSD ZERO BTFSC ZERO ;TEST ZERO FLAG IF ZERO - JUMP GOTO JUSTL ;ZERO FLAG SET, SO JUMP ;MSD IS NOT ZERO MOVF STPSL,1 ;IS LSD ZERO BTFSC ZERO ; DECF STPSM,1 ;LSD IS ZERO SO DEC MSD DECF STPSL,1 ;DEC LSD (ROLLS OVER TO FF) RETURN ;AND RETURN ;MSD IS ZERO JUSTL DECFSZ STPSL,1 ;DECREMENT LSD RETURN ; BSF STEPC ;IF ZERO ALL DONE - SET FLAG RETURN ; ;**************************************************************************** ;PAUSE2 GIVES LONG DELAY BY LOOPING 10 TIMES CALLING PAUSE1 EACH TIME ; PAUSE2 MOVLW 0x40 ;MOVE SET UP PAUSE DELAY MOVWF DELAY2 ;TO DELAY2 REGISTER DEL2LP CALL PAUSE1 ;CALL SECOND LOOP DECFSZ DELAY2, 1 ;DECREMENT SAMPLE PULSE COUNT GOTO DEL2LP ;AND LOOP UNTIL IT IS ZERO RETURN ; ;PAUSE1 GIVES MEDIUM DELAY BY LOOPING 10 TIMES CALLING PAUSE EACH TIME ; PAUSE1 MOVLW 0x80 ;MOVE SET UP PAUSE DELAY MOVWF DELAY1 ;TO DELAY1 REGISTER DEL1LP CALL PAUSE ;CALL SECOND LOOP DECFSZ DELAY1, 1 ;DECREMENT SAMPLE PULSE COUNT GOTO DEL1LP ;AND LOOP UNTIL IT IS ZERO RETURN ; ;PAUSE GIVES SHORT DELAY BY LOOPING FF TIMES ; PAUSE MOVLW 0x08 ;MOVE SET UP PAUSE DELAY MOVWF DELAY0 ;TO DELAY0 REGISTER DELLP DECFSZ DELAY0, 1 ;DECREMENT SAMPLE PULSE COUNT GOTO DELLP ;AND LOOP UNTIL IT IS ZERO RETURN ; ;**************************************************************************** ;* MOTOR DRIVE BLOCK * ;**************************************************************************** ; ;This routine takes the start addresses from UPBYTE and INDEX and collects ;the motor drive pattern from ROM. ; ; ORG 01F9 ; ; STEP CALL STEPCO ;GET DIGIT FROM TABLE INTO W MOVWF PORTB ;SWITCH DRIVE OUTPUTS RETURN ;RETURN ; STEPCO MOVF UPBYT, 0 ;LOAD UPPER BYTE ADDRESS MOVWF PCLATH ;TO PC UPPER BYTE REGISTER MOVF INDEX, 0 ;GET TABLE OFFSET INDEX ADDWF PCL,1 ;AND ADD TO PC LOWER 8 BITS ; ; THE SUBROUTINE 'STEPCO' MUST BE LOCATED AS SHOWN ; IN ORDER TO ALLOW THE 'TABLE LOOK UP' FUNCTION TO TAKE PLACE ; THIS HAS BEEN ENSURED IN THIS EXAMPLE BY THE 'ORG' 01F6 ; WHICH HAS FIXED THE 'MESGE' LINE AND ALL SUBSEQUENT CODE ; THIS IS ONE OF MANY POSSIBLE WAYS OF FIXING THE CODE. ; TAKE CARE NOT TO CROSS PAGE BOUNDARIES AS 'UPBYT' REFERS TO ; A SINGLE PAGE ONLY - 0200 TO 0300 IN THIS CASE. ; ;The PC (program counter) is loaded with the table address from UBBYT and ;INDEX and so jumps to that address, and returns with the data following ;the RETLW instruction. ; ; ;UPBYT 02, INDEX 00 RETLW B'00001010' ;STEP0 -'HOME' POSITION RETLW B'00000010' ;STEP0.5 RETLW B'00000110' ;STEP1 RETLW B'00000100' ;STEP1.5 RETLW B'00000101' ;STEP2 RETLW B'00000001' ;STEP2.5 RETLW B'00001001' ;STEP3 RETLW B'00001000' ;STEP3.5 ; ;**************************************************************************** ; ; ; END