請教各位大大 由於我剛接觸PIC 想請問我如果要更改下面程式的PWM週期 要從哪裡更改 請我指點一下
list p=12F683 ; list directive to define processor
#include <p12F683.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG 0x33E4
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
;***** VARIABLE DEFINITIONS
INT_VAR UDATA_SHR 0x70
w_temp RES 1 ; variable used for context saving
status_temp RES 1 ; variable used for context saving
PWMCount RES 1 ; holds count for software PWM
Temp RES 1
DimDuty RES 1 ; Duty cycle for PWM dimming
Status RES 1 ; Status,0 -> Over voltage flag
; Status,1 -> Potentiometer detection flag
RestartDly RES 1 ; Delay counter
;*********************************************************************************
RESET_VECTOR CODE 0x000 ; processor reset vector
goto Main ; go to beginning of program
;Interrupt Service Routine
INT_VECTOR CODE 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
bcf INTCON,T0IF ; clear TMR0 interrupt flag
banksel TMR0
movlw .128 ;
addwf TMR0,F ; set interrupt period to 50usec
CheckPeriod:
incf PWMCount
movlw .63
subwf PWMCount,W ; W = PWMCount - 63
btfsc STATUS,Z ; Is result 0?
clrf PWMCount ; Yes, clear count variable
CheckDimDuty:
movf DimDuty,W
btfsc STATUS,Z ; Is duty 0?
goto DimOutputOff ; Yes, force output to 0
subwf PWMCount,W ; W = PWMCount - Duty
btfsc STATUS,C
goto DimOutputOff
DimOutputOn:
banksel GPIO
btfss Status,0 ; Is overvoltage flag set?
bsf GPIO,5 ; Don't turn on power supply if it is
goto ExitISR
DimOutputOff:
banksel GPIO
bcf GPIO,5
ExitISR:
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;*********************************************************************************
Main:
movlw 0x70 ; set internal oscillator to 8MHz.
bsf STATUS,RP0
movwf OSCCON
CLOCK_STABLE?
btfss OSCCON,HTS ; frequency stable?.
goto CLOCK_STABLE? ; no, wait.
call InitPort ; Call port setup initiallisation.
call InitPWM ; Call the PWM setup routine.
call InitADC ; Call ADC setup routine
clrf Status ; Initialization
movlw 0x3F
movwf DimDuty
clrf PWMCount
; Potentiometer detection on GP1
btfss GPIO,1 ; Test GP1 and set flag if a pot is connected
goto SetPotFlag
bcf Status,1 ; Clear pot flag if not connected
goto EnableInterrupts
SetPotFlag:
banksel WPU ; Bank1
bcf WPU,1
banksel CMCON0 ; Set AN1 for Analog input
clrf CMCON0
banksel ANSEL
bsf ANSEL,1
banksel GPIO ; Bank0
bsf Status,1 ; Set Potentiometer flag
EnableInterrupts: ; Enable Interrupt
bsf INTCON,T0IE
bsf INTCON,GIE
;*********************************************************************************
MainLoop:
; banksel TMR0 ; uncomment next 4 lines for
; movf TMR0,W ; software clock dithering
; banksel OSCTUNE
; movwf OSCTUNE
StartADC:
banksel ADCON0 ; Bank0
bsf ADCON0,GO ; Start ADC
WaitADC:
btfsc ADCON0,GO ; Is conversion over?
goto WaitADC ; No, wait for the conversion to over
btfsc ADCON0,3 ; is the mux set to CH1 or CH3?
goto ProcessCH3
;*********************************************************************************
; ADC Channel 1, AN1
ProcessCH1: ; CH1 monitors pot for dimming
bsf ADCON0,3 ; change to to CH3
btfss Status,1 ; Check if a pot is connected by testing a flag
goto GetFullDimDuty ; If a pot is not connected, Drive LED with full brightness
; If a pot is connected, drive LED with the ADC result
GetPotResult:
movlw 0xff ; Invert ADC result so that
xorwf ADRESH,W ; 0V = full brightness
movwf Temp ; Shift result to get 6 LSB's
rrf Temp
rrf Temp
movf Temp,W
andlw 0x3F ; Mask upper 2 bits
; If ADC result is less than 10%, switch off LEDs
movwf Temp
sublw .06 ; Is ADC result less than 10%?
btfss STATUS,C
goto GetDimDuty ; No, drive LED with ADC result
banksel CCPR1L ; Yes, switch off clock to the MCP1630
movlw .4
movwf CCPR1L
banksel GPIO
goto MainLoop
; If ADC result is more than 10%, switch on LEDs
GetDimDuty:
banksel CCPR1L ; restart clock to the MCP1630
clrf CCPR1L
banksel GPIO
movf Temp,W ; Drive LED with ADC result
movwf DimDuty
goto MainLoop
; If pot is not connected
GetFullDimDuty:
movlw 0xFF
movwf DimDuty
goto MainLoop
;*********************************************************************************
; ADC Channel 3, AN3
ProcessCH3: ; CH3 monitors bus voltage for
; over-voltage protection
bcf ADCON0,3 ; change MUX to CH1
btfsc Status,0
goto RestartWait
movlw .225
subwf ADRESH,W ; Is it over voltage?
btfsc STATUS,C
goto OverVoltage ; Yes, go for over voltage protection
goto MainLoop ; No, normal operation
; If over voltage detected, switch off the clock and reference to MCP1630
; provide delay and restart clock and reference to the MCP1630
OverVoltage:
banksel CCPR1L
movlw .4
movwf CCPR1L ; disable clock to MCP1630
banksel GPIO
bcf GPIO,5 ; turn off reference to MCP1630
bsf Status,0 ; Set overvoltage flag
movlw .200 ; Initialize delay counter
movwf RestartDly
goto MainLoop
; Wait for the delay counter to expire
RestartWait:
decfsz RestartDly ; If restart delay hasn't expired,
goto MainLoop
banksel CCPR1L ; restart clock to the MCP1630
clrf CCPR1L
bcf Status,0 ; Clear overvoltage flag
goto MainLoop
;*********************************************************************************
; Port, PWM and ADC initialization
InitPWM:
banksel PR2 ; Select the PR2 register for PWM Period.
movlw 0x03 ; Write to PR2 register for setting PWM
movwf PR2 ; Period.
banksel CCP1CON ; Select CCP1CON for duty cycle.
movlw 0x3C ; Load CCP1CON<5,4> with lower two bits.
movwf CCP1CON
banksel CCPR1L ; Select CCPR1L for duty cycle
movlw 0x00 ; Load the upper 8 bits for a 10 bit
movwf CCPR1L ; resolution duty cycle.
banksel T2CON ; Select T2CON for PWM Timer.
bsf T2CON,TMR2ON ; Set Timer2 as the PWM time base for PWM mode
return ; of CCP module.
InitPort
banksel GPIO ; Bank 0
CLRF GPIO ; Init GPIO
movlw 0x07
movwf CMCON0 ; Set AN0, AN1, AN2 as digital I/O
banksel ANSEL ; Bank 1
movlw 0x28 ; AN3 Analog input
movwf ANSEL ; ADC clock is Fosc/16
banksel TRISIO
movlw 0x1A ; GP0 as output for scope flag
movwf TRISIO ; Set GP2 and GP5 as out ports
movlw b'00001000' ; TMR0 prescaler 1:1, internal clock
movwf OPTION_REG
bsf WPU,1 ; set weak pull up for a potentiometer
; detection
banksel GPIO ; Bank 0
return
InitADC
banksel ADCON0 ; turn on ADC, CH1
movlw 0x05
movwf ADCON0
bsf ADCON0,GO
return