📄 mc_16f72.asm
字号:
;*******************************************************************************
;THIS ROUTINE UPDATES THE OFFSET POINTERS TO THE TABLE AFTER EVERY ACCESS
;*******************************************************************************
UPDATE_TABLE_OFFSET
bcf STATUS,RP0
btfss FLAGS,OFFSET1_FLAG ;IF SET INCR. ON TABLE
goto DECREMENT_OFFSET1
movlw (SINE_TABLE_ENTRIES-1) ;CHECK FOR THE LAST VALUE ON THE TABLE
SUBWF TABLE_OFFSET1,W
btfsc STATUS,C
goto CLEAR_OFFSET1_FLAG
INCF TABLE_OFFSET1,F ;INCREMENT OFFSET1
goto UPDATE_OFFSET2
CLEAR_OFFSET1_FLAG
bcf FLAGS,OFFSET1_FLAG
DECREMENT_OFFSET1
DECFSZ TABLE_OFFSET1,F ;DECREMENT OFFSET1
goto UPDATE_OFFSET2
bsf FLAGS,OFFSET1_FLAG
UPDATE_OFFSET2
btfss FLAGS,OFFSET2_FLAG ;IF SET INCR. ON TABLE
goto DECREMENT_OFFSET2
movlw (SINE_TABLE_ENTRIES-1) ;CHECK FOR THE LAST VALUE ON THE TABLE
SUBWF TABLE_OFFSET2,W
btfsc STATUS,C
goto CLEAR_OFFSET2_FLAG
INCF TABLE_OFFSET2,F ;INCREMENT OFFSET2
goto UPDATE_OFFSET3
CLEAR_OFFSET2_FLAG
bcf FLAGS,OFFSET2_FLAG
DECREMENT_OFFSET2
DECFSZ TABLE_OFFSET2,F ;DECREMENT OFFSET2
goto UPDATE_OFFSET3
bsf FLAGS,OFFSET2_FLAG
UPDATE_OFFSET3
btfss FLAGS,OFFSET3_FLAG ;IF SET INCR. ON TABLE
goto DECREMENT_OFFSET3
movlw (SINE_TABLE_ENTRIES-1) ;CHECK FOR THE LAST VALUE ON THE TABLE
SUBWF TABLE_OFFSET3,W
btfsc STATUS,C
goto CLEAR_OFFSET3_FLAG
INCF TABLE_OFFSET3,F ;INCREMENT OFFSET3
RETURN
CLEAR_OFFSET3_FLAG
bcf FLAGS,OFFSET3_FLAG
DECREMENT_OFFSET3
DECFSZ TABLE_OFFSET3,F ;DECREMENT OFFSET3
RETURN
bsf FLAGS,OFFSET3_FLAG
RETURN
;*******************************************************************************
CALCULATE_NEW_SPEED
movf NEW_FREQ,W
movwf MOTOR_FREQUENCY
movlw 0x22
addwf MOTOR_FREQUENCY,F
bcf STATUS,C
rrf MOTOR_FREQUENCY,F
bcf STATUS,C
rrf MOTOR_FREQUENCY,F
movlw 0xB5
addwf MOTOR_FREQUENCY,F
return
;*************************************************************************
;PWMs are arranged from low duty cycle to high duty cycle
;Original duty cycles are input to routine on PWMx_DS
;Output on PWM_PRx and PWM_PR_CHx
PRIORATIZE_PWMS
movlw 0x1
movwf PWM_PR_CH1_Buff
movlw 0x2
movwf PWM_PR_CH2_Buff
movlw 0x4
movwf PWM_PR_CH3_Buff
movf PWM1_DS_Buff,W
subwf PWM2_DS_Buff,W
btfss STATUS,C
goto INTCHG_1_2
goto CHECK_2_3
INTCHG_1_2
;interchange duty cycles in 1 and 2
movf PWM1_DS_Buff,W
movwf TEMP_LOC
movf PWM2_DS_Buff,W
movwf PWM1_DS_Buff
movf TEMP_LOC,W
movwf PWM2_DS_Buff
;interchange the PWM outputs
movf PWM_PR_CH1_Buff,W
movwf TEMP_LOC
movf PWM_PR_CH2_Buff,W
movwf PWM_PR_CH1_Buff
movf TEMP_LOC,W
movwf PWM_PR_CH2_Buff
CHECK_2_3
;interchange duty cycles in 2 and 3
movf PWM2_DS_Buff,W
subwf PWM3_DS_Buff,W
btfss STATUS,C
goto INTCHG_2_3
goto CHECK_1_2_AGN
INTCHG_2_3
movf PWM2_DS_Buff,W
movwf TEMP_LOC
movf PWM3_DS_Buff,W
movwf PWM2_DS_Buff
movf TEMP_LOC,W
movwf PWM3_DS_Buff
;interchange the PWM outputs pins
movf PWM_PR_CH2_Buff,W
movwf TEMP_LOC
movf PWM_PR_CH3_Buff,W
movwf PWM_PR_CH2_Buff
movf TEMP_LOC,W
movwf PWM_PR_CH3_Buff
CHECK_1_2_AGN
;interchange duty cycles in 1 and 2
movf PWM1_DS_Buff,W
subwf PWM2_DS_Buff,W
btfss STATUS,C
goto INTCHG_1_2_AGN
goto CALCULATE_TIMER_RELOAD
INTCHG_1_2_AGN
movf PWM1_DS_Buff,W
movwf TEMP_LOC
movf PWM2_DS_Buff,W
movwf PWM1_DS_Buff
movf TEMP_LOC,W
movwf PWM2_DS_Buff
;interchange the PWM outputs pins
movf PWM_PR_CH1_Buff,W
movwf TEMP_LOC
movf PWM_PR_CH2_Buff,W
movwf PWM_PR_CH1_Buff
movf TEMP_LOC,W
movwf PWM_PR_CH2_Buff
CALCULATE_TIMER_RELOAD
movlw 0x9C ;Corresponding to 8KHz count with Timer1 prescale 1:4
movwf PWM4_DS_Buff
movf PWM3_DS_Buff,W
subwf PWM4_DS_Buff,F
movf PWM2_DS_Buff,W
subwf PWM3_DS_Buff,F
movf PWM1_DS_Buff,W
subwf PWM2_DS_Buff,F
RETURN
;*******************************************************************************
;This routine checks for the keys status. 2 keys are checked, Run/Stop and
;Forward(FWD)/Reverse(REV)
;*******************************************************************************
KEY_CHECK
btfss KEY_PORT,RUN_STOP_KEY ;Is key pressed "RUN/STOP"?
goto CHECK_FWD_REV_KEY
btfsc FLAGS1,DEBOUNCE
return
call KEY_DEBOUNCE
btfss FLAGS1,DEBOUNCE
return
bsf FLAGS1,KEY_RS
return
CHECK_FWD_REV_KEY
btfss KEY_PORT,FWD_REV_KEY ;Is key pressed "RUN/STOP"?
goto SET_KEYS
btfsc FLAGS1,DEBOUNCE
return
call KEY_DEBOUNCE
btfss FLAGS1,DEBOUNCE
return
bsf FLAGS1,KEY_FR
return
SET_KEYS
btfss FLAGS1,DEBOUNCE
return
bcf FLAGS1,DEBOUNCE
bsf FLAGS1,KEY_PRESSED
btfss FLAGS1,KEY_RS
goto ITS_FWD_REV
btfss FLAGS1,RUN_STOP ;Toggle RUN_STOP bit
goto $+3
bcf FLAGS1,RUN_STOP
return
bsf FLAGS1,RUN_STOP
return
ITS_FWD_REV
btfss FLAGS1,FWD_REV ;Toggle RUN_STOP bit
goto $+3
bcf FLAGS1,FWD_REV
return
bsf FLAGS1,FWD_REV
return
;*******************************************************************************
KEY_DEBOUNCE
decfsz DEBOUNCE_COUNTER,F ;Key debounce time checked
return
bsf FLAGS1,DEBOUNCE
movlw DEBOUNCE_COUNT
movwf DEBOUNCE_COUNTER
return
;*******************************************************************************
;This routine takes action for the keys pressed
;If SW1(RUN/STOP) Key is pressed, the state toggles between RUN and STOP
;If SW2(FWD/REV) Key is pressed, the state toggles between FORWARD and REVERSE
PROCESS_KEY_PRESSED
btfss FLAGS1,KEY_PRESSED ;Is there a key press waiting?
return
btfss FLAGS1,KEY_RS ;Is it RUN/STOP?
goto CHECK_FWD_REV
btfss FLAGS1,RUN_STOP ;Yes,Was the previous state a Stop?
goto STOP_MOTOR_NOW
call RUN_MOTOR_AGAIN ;Yes, Then RUN the motor
bcf FLAGS1,KEY_PRESSED ;Clear the Flag
bcf FLAGS1,KEY_RS
; bsf LED_PORT,RUN_STOP_LED ;Turn on LED to indicate motor running
return
STOP_MOTOR_NOW
call STOP_MOTOR ;Was the previous state a RUN?, Then stop the motor
bcf FLAGS1,KEY_PRESSED
bcf FLAGS1,KEY_RS
; bcf LED_PORT,RUN_STOP_LED ;Clear Flags and indicate motor stopped on LED
return
CHECK_FWD_REV
btfss FLAGS1,KEY_FR ;Is the Key pressed = FWD/REV?
return
; btg LED_PORT,FWD_REV_LED ;Yes,
; bcf LED_PORT,RUN_STOP_LED
call STOP_MOTOR ;Stop the motor before reversing
call BIG_DELAY ;Delay between reversing the direction
call BIG_DELAY
call RUN_MOTOR_AGAIN ;Run the motor in Reverse direction
bcf FLAGS1,KEY_PRESSED ;Clear Flags
bcf FLAGS1,KEY_FR
; bsf LED_PORT,RUN_STOP_LED
return
;*******************************************************************************
;THIS ROUTINE STOPS THE MOTOR BY DRIVING THE PWMS TO 0% DUTY CYCLE. ALSO DISABLE
;SELECT INTERRUPT TO MAINTAIN STOP CONDITION OF MOTOR
;*******************************************************************************
STOP_MOTOR
movlw b'00111111' ;Turn off PWM1,3,5 PWMs(active low) at the beginning of the cycle
movwf PWM_PORT ;& turn on PWM0,2,4
bsf STATUS,RP0
bcf PIE1,TMR1IE
bcf PIE1,ADIE
bcf STATUS,RP0
bcf INTCON,T0IE
bcf FLAGS,MOTOR_FREQ_COUNTER
clrf TABLE_OFFSET1
clrf TABLE_OFFSET2
clrf TABLE_OFFSET3
; bcf PORT_RELAY,RELAY_BIT
RETURN
;*******************************************************************************
;THIS ROUTINE STARTS MOTOR FROM PREVIOUS STOP WITH MOTOR PARAMETERS INITIALIZED
;*******************************************************************************
RUN_MOTOR_AGAIN
call INIT_MOTOR_PARAMETERS
bsf STATUS,RP0
bsf PIE1,TMR1IE
bcf STATUS,RP0
bsf INTCON,T0IE
RETURN
;*******************************************************************************
;THIS ROUTINE INITIALIZES THE PARAMETERS REQUIRED FOR MOTOR INITIALIZATION.
;*******************************************************************************
INIT_MOTOR_PARAMETERS
#ifdef PSC_MOTOR_CONTROL
movlw 0X012 ;INITIALIZE THE TABLE OFFSET TO 3 REGISTERS
movwf TABLE_OFFSET1 ;TO FORM 0-120-240 DEGREES
movlw 0X00
movwf TABLE_OFFSET2
movlw 0X08
movwf TABLE_OFFSET3
bcf FLAGS,OFFSET1_FLAG ;OFFSET FLAGS INITIALIZATION
bsf FLAGS,OFFSET2_FLAG
btfsc FLAGS1,FWD_REV
goto INIT_MOT_REV
bsf FLAGS,OFFSET3_FLAG ;Offset3 initialized
goto INIT_MOT_FREQ
INIT_MOT_REV
bcf FLAGS,OFFSET3_FLAG
#endif
#ifdef THREE_PHASE_MOTOR_CONTROL
movlw 0x09 ;Initialize the table offset to 3 registers
movwf TABLE_OFFSET1 ;to form 0-120-240 degrees
bsf FLAGS,OFFSET1_FLAG ;Offset flags initialization
btfsc FLAGS1,FWD_REV
goto INIT_MOT_REV
movlw 0x03
movwf TABLE_OFFSET2
bcf FLAGS,OFFSET2_FLAG
movlw 0x0F
movwf TABLE_OFFSET3
bcf FLAGS,OFFSET3_FLAG
goto INIT_MOT_FREQ
INIT_MOT_REV
movlw 0x0F
movwf TABLE_OFFSET2
bcf FLAGS,OFFSET2_FLAG
movlw 0x03
movwf TABLE_OFFSET3
bcf FLAGS,OFFSET3_FLAG
#endif
INIT_MOT_FREQ
movlw 0XB1
movwf TMR0
bsf FLAGS,MOTOR_FREQ_COUNTER
RETURN
;*******************************************************************************
;ROUTINE FOR 8*8 BIT MULTIPLICAION
;*******************************************************************************
MUL_8X8
clrf RESULT_MSB
clrf RESULT_LSB
movf NEW_FREQ,W ;MOVE THE MULTIPLICAND TO W REG.
bcf STATUS,C ;CLEAR THE CARRY BIT IN THE STATUS REG.
MULT 0
MULT 1
MULT 2
MULT 3
MULT 4
MULT 5
MULT 6
MULT 7
RETLW 0
;*******************************************************************************
;UPON INITIALIZATION THE SINE TABLE CONTENTS ARE COPIED TO THE RAM FROM
;PROGRAM MEMORY
;*******************************************************************************
COPY_TABLE_TO_RAM
BANKSEL SINE_TABLE_RAM
BANKISEL SINE_TABLE_RAM
movlw LOW SINE_TABLE_RAM
movwf FSR
movlw 0X13
movwf TEMP_LOC
clrf TEMP_LOC_1
COPY_AGAIN
movlw HIGH SINE_TABLE
movwf PCLATH
movf TEMP_LOC_1,W
call SINE_TABLE
movwf INDF
INCF TEMP_LOC_1,F
INCF FSR,F
DECFSZ TEMP_LOC,F
goto COPY_AGAIN
movlw LOW SINE_TABLE_RAM ;FSR POINTS TO THE STARTING OF THE TABLE
movwf FSR
RETURN
;*******************************************************************************
;GENERAL PURPOSE DELAY ROUTINE - PRESENT DELAY TIME ~38msec
;*******************************************************************************
DELAY
movlw DELAY_COUNT1
movwf TEMP_LOC
DEC_TEMP_LOC
movlw DELAY_COUNT2
movwf TEMP_LOC_1
DEC_TEMP_LOC_1
DECFSZ TEMP_LOC_1,F
goto DEC_TEMP_LOC_1
DECFSZ TEMP_LOC,F
goto DEC_TEMP_LOC
RETURN
B_DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
call DELAY
return
BIG_DELAY
call B_DELAY
call B_DELAY
call B_DELAY
call B_DELAY
return
;*******************************************************************************
;EQUATION USED FOR CALCULATION OF SINE TABLE ENTRIES = (SIN(ANGLE)+1)*FF/2
;Sine table has value corresponding to every 10 electrical degrees
;*******************************************************************************
TABLE CODE 0X0005
SINE_TABLE
addwf PCL,F
RETLW .2
RETLW .4
RETLW .8
RETLW .16
RETLW .24
RETLW .34
RETLW .50
RETLW .64
RETLW .80
RETLW .96
RETLW .112
RETLW .128
RETLW .144
RETLW .156
RETLW .168
RETLW .178
RETLW .184
RETLW .188
RETLW .190
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -