;**********************************************************************
; *
; 檔案名稱: PWM-C.asm *
;**********************************************************************
; *
; 其它檔案: 無 *
;**********************************************************************
; *
; 說明: *
; 這個範例程式會產生兩個簡單的PWM脈波輸出 *
; 設定暫存器'PWM_WORK_CFG1' 和 'PWM_WORK_CFG2' *
; 將會改變PIN_PWM1和PIN_PWM2的工作周期 *
; 請注意,'PWM_WORK_CFG1'和'PWM_WORK_CFG2'和'PWM_FULL' *
; 暫存器的設定值需介於1-255之間. *
; PWM1輸出腳PORTB.0 PWM2輸出腳PORTB.1 *
;**********************************************************************
list p=16F84 ; list directive to define processor
#include
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _RC_OSC
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;********************** CONST DEFINITIONS******************************
FULL_WORK = 10 ; 最大工作周期預設值
DEF_WORK1 = 2 ; PWM1工作周期預設值
DEF_WORK2 = 8 ; PWM2工作周期預設值
PORT_OUT = PORTB ; PWM輸出埠
PIN_PWM1 = 0 ; PWM1輸出腳位
PIN_PWM2 = 1 ; PWM2輸出腳位
;********************** VARIABLE DEFINITIONS***************************
CBLOCK 0x0C
w_temp ; variable used for context saving
status_temp ; variable used for context saving
PWM_FULL ; 最大工作周期計數器(下數)
PWM_WORK_CFG1 ; PWM1 工作周期設定暫存器
PWM_WORK_CFG2 ; PWM2 工作周期設定暫存器
PWM_WORK_CNT1 ; PWM1 工作周期計數器(下數)
PWM_WORK_CNT2 ; PWM2 工作周期計數器(下數)
ENDC
;**********************************************************************
;****************** 晶片重置後程式進入點 ***********************
;**********************************************************************
ORG 0x000 ; processor reset vector
ResetStart
goto main ; go to beginning of program
;**********************************************************************
;****************** 中斷服務程式進入點 *************************
;**********************************************************************
ORG 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
bsf STATUS,RP0
bcf INTCON,T0IF ; 清除計時器中斷旗號
bcf STATUS,RP0
decfsz PWM_FULL,F ; 檢查是否完成一個周期
goto ISR_PWM1
bsf PORT_OUT,PIN_PWM1 ; PWM1/PWM2回復High電位
bsf PORT_OUT,PIN_PWM2
movlw FULL_WORK ; 重新設定各工作周期計數器
movwf PWM_FULL
movf PWM_WORK_CFG1,W
movwf PWM_WORK_CNT1
movf PWM_WORK_CFG2,W
movwf PWM_WORK_CNT2
goto ISR_EXIT
ISR_PWM1
decfsz PWM_WORK_CNT1,F ; 檢查PWM1工作周期
goto ISR_PWM2
bcf PORT_OUT,PIN_PWM1 ; 工作周期結束,將輸出設為Low電位
ISR_PWM2
decfsz PWM_WORK_CNT2,F ; 檢查PWM2工作周期
goto ISR_EXIT
bcf PORT_OUT,PIN_PWM2 ; 工作周期結束,將輸出設為Low電位
ISR_EXIT
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
;**********************************************************************
;****************** 初始化PWM *******************************
;**********************************************************************
InitPWM
bsf STATUS,RP0 ; 設定PWM1/PWM2腳為輸出
bcf PORT_OUT,PIN_PWM1
bcf PORT_OUT,PIN_PWM2
bcf STATUS,RP0
bsf PORT_OUT,PIN_PWM1 ; 預設PWM1/PWM2輸出高電位
bsf PORT_OUT,PIN_PWM2
movlw FULL_WORK ; 設定各暫存器之預設值
movwf PWM_FULL
movlw DEF_WORK1
movwf PWM_WORK_CFG1
movwf PWM_WORK_CNT1
movlw DEF_WORK2
movwf PWM_WORK_CFG2
movwf PWM_WORK_CNT2
retlw 0
;**********************************************************************
;****************** 初始化計時器 *******************************
;**********************************************************************
InitTimer
bsf STATUS,RP0
bsf OPTION_REG,T0CS ; 停止振盪器脈波輸入
bsf OPTION_REG,PSA ; 設定不使用脈波預除器
bsf INTCON,GIE ; 打開全域中斷開關(中斷總開關)
bcf INTCON,T0IF ; 清除計時器中斷旗號
bcf STATUS,RP0
retlw 0
;**********************************************************************
;****************** 啟動計時器 *******************************
;**********************************************************************
StartTimer
bsf STATUS,RP0
bcf OPTION_REG,T0CS ; 設定振盪器脈波輸入(1/4 osc)
bsf INTCON,T0IE ; 打開計時器中斷
bcf STATUS,RP0
retlw 0
;**********************************************************************
;****************** 停止計時器 *******************************
;**********************************************************************
StopTimer
bsf STATUS,RP0
bsf OPTION_REG,T0CS ; 停止振盪器脈波輸入
bcf INTCON,T0IE ; 關上計時器中斷
bcf STATUS,RP0
retlw 0
;**********************************************************************
;****************** 主程式進入點 *******************************
;**********************************************************************
main
bcf STATUS,RP0 ; select Page 0 for Port Access
call InitPWM
call InitTimer
call StartTimer
goto $
;**********************************************************************
END ; directive 'end of program'
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』