;********************************************************************** ; * ; 檔案名稱: PWM-C.asm * ; 日期: 06/14/2001 * ; 檔案版本: 1.00 * ; * ; 設計者: 陳宗佑 macross@scanace.com * ; 公司名稱: * ; * ; * ;********************************************************************** ; * ; 其它檔案: 無 * ; * ; * ; * ;********************************************************************** ; * ; 說明: * ; 這個範例程式會產生兩個簡單的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 ; processor specific variable definitions __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'