📄 mc_16f72.asm
字号:
;******************************************************************************
;
; Software License Agreement
;
; The software supplied herewith by Microchip Technology
; Incorporated (the "Company") is intended and supplied to you, the
; Company抯 customer, for use solely and exclusively on Microchip
; products. The software is owned by the Company and/or its supplier,
; and is protected under applicable copyright laws. All rights are
; reserved. Any use in violation of the foregoing restrictions may
; subject the user to criminal sanctions under applicable laws, as
; well as to civil liability for the breach of the terms and
; conditions of this license.
;
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
; WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
; TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
; PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
; IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
;
;*********************************************************************************
;----------------------------------------------------------------
;Author: Padmaraja Yedamale
;Home Appliance Solutions Group
;Microchip Technology Inc, Chandler,AZ
;Last Update: May-20-2004
;----------------------------------------------------------------
;This program is used to control the speed of a Permanent Series Capacitor(PSC) motor
;3 phase control of PSC motor without the starting capacitor
;Microcontroller used: PIC16F72 or PIC16F73
;----------------------------------------------------------------
;Operation:
;1) Connect motor terminals to J2 with following order(Order is importent)
; Connect J2/1(M1) to Main winding on the motor(
; Connect J2/2(M2) to Auxilliary winding on the motor
; Connect J2/3(M3) to Common point of Main and auxilliary winding on the motor
;2) Connect AC power input power to J1
;3) Power up the board
;4) Press switch S2,
;5) Turn potentiometer R5 to vary motor speed.
;6) Set potentiometer R21 to about half way. Vary this for different motor ratings.
; (On final production board, replace with appropriate resistor)
;7) Code monitors the over current and if it exceeds for more than 'HARDWARE_OC_COUNT'
; times, fault is generated and motor will stop. Reset the system and start from #3
;8) Software over current and heat sink over tempearatures will set flag, if occured.
; Add your actions according to the refrigerator requirements.
;
;----------------------------------------------------------------
#define PIC16F72
#define PSC_MOTOR_CONTROL
;#define THREE_PHASE_MOTOR_CONTROL
;----------------------------------------------------------------
;----------------------------------------------------------------
INCLUDE <MC_16F72.INC>
;----------------------------------------------------------------
;Configuration bits definition
;Oscillator : HS
;Watchdog timer : off
;Power up timer : on
;Brown out detect : on
;Code protect :off
; __CONFIG 0x2007, 0x5A
;----------------------------------------------------------------
;Macro
MULT MACRO BIT ;MACRO FOR UNSIGNEDMULTIPLICATION
btfsc NO_1_LSB,BIT
addwf RESULT_MSB,F
RRF RESULT_MSB,F
RRF RESULT_LSB,F
ENDM ;END OF MACRO FOR MULTIPLICATION
;----------------------------------------------------------------
STARTUP CODE 0X00 ;RESET VECTOR ADDRESS
goto START
CODE 0X04 ;INTERRUPT VECTOR LOCATION
goto ISR_INT ;goto INTERRUPT SERVICE ROUTINE
;****************************************************************
PROG CODE
START
;****************************************************************
;INITIALIZATION OF THE PORTS AND TIMERS
bsf STATUS,RP0
movlw 0X03
movwf TRISB ;RB0-1 AND CONFIGURED AS INPUT
movlw 0X00
movwf TRISC ;RC0-RC7 CONFIGURED AS OUTPUT
bcf STATUS,RP0
movlw b'00101010' ;Turn off PWM1,3,5 PWMs(active low) at the beginning of the cycle
movwf PWM_PORT ;& turn on PWM0,2,4
clrf PWM_PR_CH1_Buff
clrf PWM_PR_CH2_Buff
clrf PWM_PR_CH3_Buff
clrf PWM1_DS_Buff
clrf PWM2_DS_Buff
clrf PWM3_DS_Buff
clrf PWM4_DS_Buff
clrf FLAGS ;CLEAR ALL FLAGS
clrf FLAGS2 ;CLEAR ALL FLAGS
call STOP_MOTOR ;STOP MOTOR
call COPY_TABLE_TO_RAM ;COPY SINE TABLE FROM PROGRAM MEMORY TO RAM FOR FASTER ACCESS
;******************************************************************
;INITIALIZE ADC REGISTERS
;******************************************************************
bcf STATUS,RP0
movlw 0X81
movwf ADCON0 ;CONFIGURE FOR 32TOSC AND CHANNEL FOR CONVERSION - RA0 (FREQUNENCY)
bsf STATUS,RP0
movlw 0x02 ;CONFIGURE RA0-RA4 AS ANALOG INPUT
movwf ADCON1
movlw 0X07 ;RA0-RA3 INPUT and RA4-RA7 OUTPUT
movwf TRISA
bcf STATUS,RP0
;******************************************************************
;TIMER1 INITIALIZATION WITH PRESCALER - USED FOR SETTING THE PWM TIMING
;******************************************************************
movlw b'00100001' ;LOAD THE T1CON WITH CONTROL WORD
movwf T1CON ;FOR TMR1 ON AND PRESCALAR IS 1:4, INTERNAL CLOCK
;******************************************************************
;TIMER0 INITIALIZATION WITH PRESCALER - USED FOR ACCELERATION,DECELERATION AND ADC TRIGGER FOR FREQ. CONV.
;******************************************************************
bsf STATUS,RP0
movlw b'10000110' ;prescale 1:128
movwf OPTION_REG
bcf STATUS,RP0
clrf INTCON ;DISABLE ALL INTERRUPTS AND FLAGS ASSOCIATED WITH
clrf PIR1 ;DISABLE ALL INTERRUPT FLAGS
bsf STATUS,RP0
clrf PIE1 ;DISABLE ALL INTERRUPTS
movlw 0X03 ;SET #POR AND #BOR FLAGS
movwf PCON
bcf STATUS,RP0
;---------
WAIT_HERE
btfss KEY_PORT,FWD_REV_KEY
goto WAIT_HERE
;***********************************************************************
call BIG_DELAY
;Very important, turning on this bit will turn on DC bus to the IRAMS
bsf PORT_RELAY,RELAY_BIT ; PORTB,7
call BIG_DELAY
;***********************************************************************
call RUN_MOTOR_AGAIN
movlw 0x30
movwf NEW_FREQ
call UPDATE_PWM_DUTYCYCLES ;YES, UPDATE THE PWM DUTY CYCLE WITH NEW VALUE
call PRIORATIZE_PWMS
call UPDATE_TABLE_OFFSET ;UPDATE 3 OFFSETS
call CALCULATE_NEW_SPEED
bcf STATUS,RP0
bsf INTCON,INTE ;ENABLE RB PORT CHANGE INTERRUPT FOR RB4
bsf INTCON,PEIE ;PERIPHERAL INTERRUPTS ENABLE
bsf INTCON,GIE ;GLOBAL INTERRUPT ENABLE
;******************************************************************
;MAIN LOOP, THE PROGRAM WILL BE LOOPING
;******************************************************************
MAIN_LOOP
btfss FLAGS,MOTOR_FREQ_COUNTER
goto BYPASS
bcf FLAGS,MOTOR_FREQ_COUNTER ;CLEAR TMR1 OV FLAG
call UPDATE_PWM_DUTYCYCLES ;YES, UPDATE THE PWM DUTY CYCLE WITH NEW VALUE
call PRIORATIZE_PWMS
call UPDATE_TABLE_OFFSET ;UPDATE 3 OFFSETS
call CALCULATE_NEW_SPEED
btfss ADCON0, GO ;If AD Conversion is complete
bsf ADCON0, GO ; then start a new conversion
BYPASS
btfsc PIR1,ADIF ;ADC CONVERSION COMPLETE INTERRUPT?
call AD_CONV_COMPLETE ;YES - CONVERSON RESULT 'F - MOTOR FREQUENCY'
call KEY_CHECK ;Check keys change
call PROCESS_KEY_PRESSED
goto MAIN_LOOP ;GO BACK TO MAIN LOOP
;******************************************************************
;INTERRUPT SERVICE ROUTINE
;******************************************************************
ISR_INT
movwf W_TEMP ;COPY W TO A TEMPORARY REGISTER
swapf STATUS,W ;SWAP STATUS NIBBLES AND PLACE INTO W REGISTER
movwf STATUS_TEMP ;SAVE STATUS TO A TEMPORARY REGISTER IN BANK0
bcf STATUS,RP0
btfsc PIR1,TMR1IF ;TIMER1 OVERFLOW INTERRUPT?
goto TIMER1_OVERFLOW ;YES - INTERRUPT FOR UPDATING TMR1 REGISTERS BASED ON POT SETTING
btfsc INTCON,T0IF ;TIMER0 OVERFLOW INTERRUPT?
goto TIMER0_OVERFLOW ;YES - INTERRUPT FOR UPDATING TMR1 REGISTERS BASED ON POT SETTING
btfsc INTCON,INTF ;RB INTERRUPT?
goto CHECK_FAULT ;YES - OVER CURRENT FAULT
POPUP ;RETRIEVE SAVED WREG AND STAUS REGISTER VALUES
swapf STATUS_TEMP,W ;SWAP ORIGINAL STATUS REGISTER VALUE INTO W (RESTORES ORIGINAL BANK)
movwf STATUS ;RESTORE STATUS REGISTER FROM W REGISTER
swapf W_TEMP,F ;SWAP W_TEMP NIBBLES AND RETURN VALUE TO W_TEMP
swapf W_TEMP,W ;SWAP W_TEMP TO W TO RESTORE ORIGINAL W VALUE WITHOUT AFFECTING STATUS
RETFIE ;RETURN FROM INTERRUPT
;******************************************************************
TIMER1_OVERFLOW ;TMR1 OVERFLOW ISR
bcf PIR1,TMR1IF ;CLEAR TMR1IF
;---
btfss FLAGS1,PWM_FIRST
goto TAKE_CARE_PWM_SECOND
btfsc PWM_PR_CH1_Buff,0
bsf PWM_PORT,PWM1_PIN ;PWM1 is active low
btfsc PWM_PR_CH1_Buff,1
bsf PWM_PORT,PWM3_PIN ;PWM3 is active low
btfsc PWM_PR_CH1_Buff,2
bsf PWM_PORT,PWM5_PIN ;PWM5 is active low
btfsc PWM_PR_CH1_Buff,0
bcf PWM_PORT,PWM0_PIN ;PWM0 is active low
btfsc PWM_PR_CH1_Buff,1
bcf PWM_PORT,PWM2_PIN ;PWM2 is active low
btfsc PWM_PR_CH1_Buff,2
bcf PWM_PORT,PWM4_PIN ;PWM4 is active low
bcf FLAGS1,PWM_FIRST
movlw 0xFF
movwf TMR1H
bsf FLAGS1,PWM_SECOND
comf PWM2_DS_Buff,W
movwf TMR1L
btfss STATUS,Z
goto POPUP
;---
TAKE_CARE_PWM_SECOND
btfss FLAGS1,PWM_SECOND
goto TAKE_CARE_PWM_THIRD
btfsc PWM_PR_CH2_Buff,0
bsf PWM_PORT,PWM1_PIN ;PWM1 is active low
btfsc PWM_PR_CH2_Buff,1
bsf PWM_PORT,PWM3_PIN ;PWM3 is active low
btfsc PWM_PR_CH2_Buff,2
bsf PWM_PORT,PWM5_PIN ;PWM5 is active low
btfsc PWM_PR_CH2_Buff,0
bcf PWM_PORT,PWM0_PIN ;PWM0 is active low
btfsc PWM_PR_CH2_Buff,1
bcf PWM_PORT,PWM2_PIN ;PWM2 is active low
btfsc PWM_PR_CH2_Buff,2
bcf PWM_PORT,PWM4_PIN ;PWM4 is active low
bcf FLAGS1,PWM_SECOND
movlw 0xFF
movwf TMR1H
bsf FLAGS1,PWM_THIRD
comf PWM3_DS_Buff,W
movwf TMR1L
btfss STATUS,Z
goto POPUP
;---
TAKE_CARE_PWM_THIRD
btfss FLAGS1,PWM_THIRD
goto TAKE_CARE_FOR_NEXT_CYCLE
btfsc PWM_PR_CH3_Buff,0
bsf PWM_PORT,PWM1_PIN ;PWM1 is active low
btfsc PWM_PR_CH3_Buff,1
bsf PWM_PORT,PWM3_PIN ;PWM3 is active low
btfsc PWM_PR_CH3_Buff,2
bsf PWM_PORT,PWM5_PIN ;PWM5 is active low
btfsc PWM_PR_CH3_Buff,0
bcf PWM_PORT,PWM0_PIN ;PWM0 is active low
btfsc PWM_PR_CH3_Buff,1
bcf PWM_PORT,PWM2_PIN ;PWM2 is active low
btfsc PWM_PR_CH3_Buff,2
bcf PWM_PORT,PWM4_PIN ;PWM4 is active low
bcf FLAGS1,PWM_THIRD
movlw 0xFF
movwf TMR1H
bsf FLAGS1,PWM_NEW_CYCLE
comf PWM4_DS_Buff,W
movwf TMR1L
btfss STATUS,Z
goto POPUP
;---
TAKE_CARE_FOR_NEXT_CYCLE
movlw b'00111111' ;Turn off all PWMs(active low)
movwf PWM_PORT
comf PWM1_DS_Buff,W
movwf TMR1L
movlw 0xFF
movwf TMR1H
bcf FLAGS1,PWM_NEW_CYCLE
bsf FLAGS1,PWM_FIRST
movlw b'00010101' ;Turn on PWM1,3,5 PWMs(active low) at the beginning of the cycle
movwf PWM_PORT
goto POPUP
;******************************************************************
TIMER0_OVERFLOW ;TMR0 overflow ISR
movf MOTOR_FREQUENCY,W ;Load the Lower byte of SpeedCommand to TMR0L
movwf TMR0
bsf FLAGS,MOTOR_FREQ_COUNTER
bcf INTCON,T0IF ;Clear T0IF
movlw HARDWARE_OC_COUNT ;Over current count from the comparator
movwf OC_COUNT
goto POPUP
;******************************************************************
CHECK_FAULT
bcf INTCON,INTF
decfsz OC_COUNT,F
goto POPUP
call STOP_MOTOR ;STOP MOTOR
goto POPUP
;*****************************************************************
AD_CONV_COMPLETE ;ADC INTERRUPT
bcf PIR1,ADIF ;ADIF FLAG IS CLEARED FOR NEXT INTERRUPT
btfsc FLAGS2,FREQ_REF ;IS THE CONVERSION RESULT is FREQUENCY REF?
goto CONV_IS_FREQ
btfsc FLAGS2,MOTOR_CUR ;IS THE CONVERSION RESULT is Motor current?
goto CONV_IS_MOTOR_CURRENT ;YES - READ RESULT AS MOTOR_CURRENT
btfsc FLAGS2,HEATSINK_TEMP ;IS THE CONVERSION RESULT is Motor current?
goto CONV_IS_HS_TEMP ;YES - READ RESULT AS MOTOR_CURRENT
bsf FLAGS2,FREQ_REF
bcf ADCON0,3
bcf ADCON0,4
return
CONV_IS_FREQ
bcf FLAGS2,FREQ_REF
bsf FLAGS2,MOTOR_CUR
bsf ADCON0,3 ;Channle1 is selected for next conversion
bcf ADCON0,4
movf ADRES,W ;READ AD CONVERSION RESULT
movwf NEW_FREQ ;CHECK FOR LOWER AND UPPER ALLOWED LIMIT OF FREQ.
sublw 0X30 ;MINIMUM FREQUENCY SET TO 5HZ (SCALING FACTOR X4)
btfss STATUS,C ;IS POT SETTING FOR FREQ, MORE THAT LOWER SET LIMIT?
goto CHECK_UPPER_LIMIT_FREQUENCY ;YES - NOW CHECK UPPER LIMIT
movlw 0X30 ;NO - SET FREQ. TO LOWER ALLOWED LIMIT - 5HZ (X4)
movwf NEW_FREQ
return
CHECK_UPPER_LIMIT_FREQUENCY
movlw 0XD0
subwf NEW_FREQ,W
btfss STATUS,C ;IS POT SETTING MORE THAN ALLOWED UPPER LIMIT OF FREQ?
return ;NO - RETURN FROM INTERRUPT
movlw 0XD0 ;YES - SET FREQ TO UPPER ALLOWED LIMIT - 60HZ (X4)
movwf NEW_FREQ
return
CONV_IS_MOTOR_CURRENT
bsf FLAGS2,HEATSINK_TEMP
bcf FLAGS2,MOTOR_CUR
bcf ADCON0,3 ;Channle2 is selected for next conversion
bsf ADCON0,4
movf ADRES,W ;READ AD CONVERSION RESULT
sublw MAX_MOTOR_CURRENT ;Max current limit
btfss STATUS,C ;IS current > SET LIMIT?
bsf FLAGS2,OVER_CURRENT ;Yes, Take action
return
CONV_IS_HS_TEMP
bsf FLAGS2,FREQ_REF
bcf FLAGS2,HEATSINK_TEMP
bcf ADCON0,3 ;Channle0 is selected for next conversion
bcf ADCON0,4
movf ADRES,W ;READ AD CONVERSION RESULT
sublw MAX_HEATSINK_TEMP ;Max temp limit
btfsc STATUS,C ;IS temp > SET LIMIT?
return
bsf FLAGS,OVER_TEMPARATURE ;Yes, Take action
; call STOP_MOTOR
return
;*************************************************************************
;THIS ROUTINE WILL UPDATE THE PWM DUTY CYCLE ACCORDING TO THE
;OFFSET TO THE TABLE
;THIS ROUTINE SCALES THE PWM VALUE FROM THE TABLE BASED ON THE FREQUENCY TO KEEP V/F
;CONSTANT AND LOADS THEM IN APPROPRIATE REGISTER DEPENDING ON SETTING
;*************************************************************************
UPDATE_PWM_DUTYCYCLES
movlw LOW SINE_TABLE_RAM
movwf FSR ;BASE ADDRESS OF SINE TABLE IN RAM IS LOADED TO FSR
movf TABLE_OFFSET1,W ;TABLE_OFFSET1 IS COPIED TO WREG
addwf FSR,F ;ADRESS TO BE READ=SINE TABLE BASE ADRESS + TABLE_OFFSET1
BANKISEL SINE_TABLE_RAM
movf INDF,W ;COPY SINE TABLE VALUE, POINTED BY FSR, TO WREG
btfsc STATUS,Z ;CHECK IS VALUE READ ZERO?
goto PWM1_IS_0 ;YES, goto PWM1_IS_0
movwf NO_1_LSB ;NO, SINE TABEL VALUE X SET_FREQ TO SCALE TABLE VALUE BASED ON FREQUENCY SETTING
call MUL_8X8 ;CALL ROUTINE FOR UNSIGNED 8x8 BIT MULTIPLICATION
movf RESULT_MSB,W ;8 MSB OF 16 BIT RESULT IS STORED
movwf TEMP_LOC ;AT TEMP_LOC - THIS REPRESENT PWM DUTY CYCLE VALUE FOR PHASE 1
goto UPDATE_PWM2 ;GO FOR UPDATING PWM DUTY CYCLE FOR 2ND PHASE
PWM1_IS_0
clrf TEMP_LOC ;CLEAR PWM DUTY CYCLE VALUE FOR PHASE 1
UPDATE_PWM2
movlw LOW (SINE_TABLE_RAM)
movwf FSR ;BASE ADDRESS OF SINE TABLE IN RAM IS LOADED TO FSR
movf TABLE_OFFSET2,W ;TABLE_OFFSET2 IS COPIED TO WREG
addwf FSR,F ;ADRESS TO BE READ=SINE TABLE BASE ADRESS + TABLE_OFFSET2
BANKISEL SINE_TABLE_RAM
movf INDF,W ;COPY SINE TABLE VALUE, POINTED BY FSR, TO WREG
btfsc STATUS,Z ;CHECK IS VALUE READ ZERO?
goto PWM2_IS_0 ;YES, goto PWM2_IS_0
movwf NO_1_LSB ;NO, SINE TABEL VALUE X SET_FREQ TO SCALE TABLE VALUE BASED ON FREQUENCY SETTING
call MUL_8X8 ;CALL ROUTINE FOR UNSIGNED 8x8 BIT MULTIPLICATION
movf RESULT_MSB,W ;8 MSB OF 16 BIT RESULT IS STORED
movwf TEMP_LOC_1 ;AT TEMP_LOC_1 - THIS REPRESENT PWM DUTY CYCLE VALUE FOR PHASE 2
goto UPDATE_PWM3 ;GO FOR UPDATING PWM DUTY CYCLE FOR 3RD PHASE
PWM2_IS_0
clrf TEMP_LOC_1 ;CLEAR PWM DUTY CYCLE VALUE FOR PHASE 2
UPDATE_PWM3
movlw LOW SINE_TABLE_RAM
movwf FSR ;BASE ADDRESS OF SINE TABLE IN RAM IS LOADED TO FSR
BANKSEL TABLE_OFFSET3
movf TABLE_OFFSET3,W ;TABLE_OFFSET3 IS COPIED TO WREG
addwf FSR,F ;ADRESS TO BE READ=SINE TABLE BASE ADRESS + TABLE_OFFSET3
BANKISEL SINE_TABLE_RAM
movf INDF,W ;COPY SINE TABLE VALUE, POINTED BY FSR, TO WREG
btfsc STATUS,Z ;CHECK IS VALUE READ ZERO?
goto PWM3_IS_0 ;YES, goto PWM3_IS_0
movwf NO_1_LSB ;NO, SINE TABEL VALUE X SET_FREQ TO SCALE TABLE VALUE BASED ON FREQUENCY SETTING
call MUL_8X8 ;CALL ROUTINE FOR UNSIGNED 8x8 BIT MULTIPLICATION
movf RESULT_MSB,W ;8 MSB OF 16 BIT RESULT IS STORED
movwf TEMP_LOC_2 ;AT TEMP_LOC_2 - THIS REPRESENT PWM DUTY CYCLE VALUE FOR PHASE 3
goto SET_PWM12 ;GO FOR CHECKING DIRECTION OF MOTOR ROTATION REEQUIRED
PWM3_IS_0
clrf TEMP_LOC_2 ;CLEAR PWM DUTY CYCLE VALUE FOR PHASE 3
SET_PWM12
movf TEMP_LOC,W
movwf PWM1_DS_Buff
movf TEMP_LOC_1,W ;CCPR1L AND CCPR2L RESPECTIVELY FOR
movwf PWM2_DS_Buff
movf TEMP_LOC_2,W
movwf PWM3_DS_Buff
RETURN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -