新會員
Joined
: 2008/2/21 21:16 最後登入時間
: 2009/4/20 10:13
Group:
註冊會員
Level : 1 HP : 0 / 0 MP : 0 / 0 EXP : 0
|
題目:<<利用訊號產生器輸出0Hz~10kHz方波,將訊號顯示在LCD螢幕上>>
問題1.我寫出的值並不準(誤差太大),直到1.600k左右才會好 一點. 問題2.我轉換的值無法馬上顯示在LCD上,都會延遲.
哪位善心人士可以小弟我一點建議,或給我一點方向
;===========以 下 是 我 的 程 式===============
LIST P=16F877 #INCLUDE<P16F877.INC>
;PIC使用---------------------- D1 EQU 0X20 D2 EQU 0X21 D3 EQU 0X22 W_TEMP EQU 0X23 STATUS_TEMP EQU 0X24 D1_TEMP EQU 0X25 D2_TEMP EQU 0X26 D3_TEMP EQU 0X27
;LCD使用----------------------- LCD_DATA EQU 0X28 RS EQU 5 EN EQU 4 LCD_BUS EQU PORTD LCD_CMD EQU PORTB IDX EQU 0X29
;DATA使用---------------------- COUNT1 EQU 0X30 COUNT10 EQU 0X31 COUNT100 EQU 0X32 COUNT1K EQU 0X33 COUNT10K EQU 0X34 DATA1 EQU 0X35 DATA10 EQU 0X36 DATA100 EQU 0X37 DATA1K EQU 0X38 DATA10K EQU 0X39
COUNT0 EQU 0X3A SETBIT EQU 0X40
ORG 0X00 GOTO INITIAL_IO ORG 0X04 GOTO INTSUB
INITIAL_IO: BCF PIR1,0 MOVLW .10 MOVWF IDX ;I/O設定----------------> BSF STATUS,RP0 BSF TRISC,2 CLRF TRISD CLRF TRISB ;全域及週邊中斷致能-----> BSF INTCON,GIE BSF INTCON,PEIE ;中斷腳位設定-----------> BSF PIE1,CCP1IE BSF PIE1,TMR1IE ;-----------------------> BCF STATUS,RP0 MOVLW 0X6D MOVWF TMR1H MOVLW 0X84 MOVWF TMR1L
;清除中斷旗標-----------> BCF PIR1,CCP1IF BCF PIR1,TMR1IF ;其實清不掉 ;設定預除比及清除暫存器-> MOVLW B'00000101' ;每個正緣發生中斷 MOVWF CCP1CON MOVLW B'00110001' ;預除比1:8 MOVWF T1CON ;LCD初始設定---------------------------------|| INITLCD: CALL LCD_CLEAR CLEAR: CALL LCD_CURSOR CALL LCD_ENTRY CALL LCD_ONOFF CALL LCD_FUNC
CLRF CCPR1H CLRF CCPR1L ;清除所有暫存器---------> CLRF COUNT0 CLRF SETBIT CLRF COUNT1 CLRF COUNT10 CLRF COUNT100 CLRF COUNT1K CLRF COUNT10K
CLRF DATA1 CLRF DATA10 CLRF DATA100 CLRF DATA1K CLRF DATA10K
;等待副程式----------------------------------|| CLRF SETBIT WAIT: BTFSC SETBIT,0 ;判斷是否CCP中斷 GOTO CCP_0 ;YES BTFSC SETBIT,7 ;判斷是否TIME1中斷 GOTO TIME1_0 ;YES GOTO WAIT ;NO未發生任何中斷
;已知CCP發生中斷,暫存器開始儲值-> CCP_0: BTFSC SETBIT,6 INCF COUNT1,F ;個位數+1 INCF COUNT1,F ;個位數+1
MOVLW .9 SUBWF COUNT1,W BTFSS STATUS,Z ;判斷Z旗標是否致能(COUNT1已經=10) GOTO CCP_1
CLRF COUNT1 ;清除個位數 INCF COUNT10,F ;十位數+1 MOVLW .9 SUBWF COUNT10,W BTFSS STATUS,Z ;判斷Z旗標是否致能(COUNT10已經=10) GOTO CCP_1
CLRF COUNT10 ;清除十位數 INCF COUNT100,F ;佰位數+1 MOVLW .9 SUBWF COUNT100,W BTFSS STATUS,Z ;判斷Z旗標是否致能(COUNT100已經=10) GOTO CCP_1
CLRF COUNT100 ;清除佰位數 INCF COUNT1K,F ;1K位數+1 MOVLW .9 SUBWF COUNT1K,W BTFSS STATUS,Z ;判斷Z旗標是否致能(COUNT1K已經=10) GOTO CCP_1
CLRF COUNT1K ;清除1K位數 INCF COUNT10K,F ;10K位數+1 MOVLW .9 SUBWF COUNT10K,W BTFSS STATUS,Z ;判斷Z旗標是否致能(COUNT10K已經=10)
CCP_1: CLRF SETBIT ;清除暫存器 GOTO WAIT
;已知TIME1發生中斷,各暫存器將儲值轉換成ASCII碼並存入DATA-> TIME1_0: MOVF COUNT1,W CALL TABLE MOVWF DATA1
MOVF COUNT10,W CALL TABLE MOVWF DATA10
MOVF COUNT100,W CALL TABLE MOVWF DATA100
MOVF COUNT1K,W CALL TABLE MOVWF DATA1K
MOVF COUNT10K,W CALL TABLE MOVWF DATA10K ;清除所有暫存器---------> CLRF COUNT1 CLRF COUNT10 CLRF COUNT100 CLRF COUNT1K CLRF COUNT10K
CLRF SETBIT ;清除暫存器 BSF SETBIT,6
GOTO WRITLCD ;呼叫寫入副程式 GOTO WAIT
;寫入副程式--------------------------------> WRITLCD: NOP TEST1: MOVLW 0X30 ;0 SUBWF DATA10K,W BTFSC STATUS,Z ;判斷DATA10K是否為0 GOTO TEST2 ;NO.5=0 CASE1: MOVF DATA10K,W MOVWF LCD_DATA CALL WRDR MOVF DATA1K,W MOVWF LCD_DATA CALL WRDR
MOVLW 0X2E ; . MOVWF LCD_DATA CALL WRDR
MOVF DATA100,W MOVWF LCD_DATA CALL WRDR
MOVF DATA10,W MOVWF LCD_DATA CALL WRDR
MOVF DATA1,W MOVWF LCD_DATA CALL WRDR
MOVLW 0X6B ; k MOVWF LCD_DATA CALL WRDR GOTO CLEAR
TEST2: MOVLW 0X30 ;0 SUBWF DATA1K,W BTFSC STATUS,Z ;判斷DATA1K是否為0 GOTO TEST3 ;NO.5,4=0
CASE2: MOVF DATA1K,W MOVWF LCD_DATA CALL WRDR
MOVLW 0X2E ; . MOVWF LCD_DATA CALL WRDR
MOVF DATA100,W MOVWF LCD_DATA CALL WRDR
MOVF DATA10,W MOVWF LCD_DATA CALL WRDR
MOVF DATA1,W MOVWF LCD_DATA CALL WRDR
MOVLW 0X6B ; k MOVWF LCD_DATA CALL WRDR GOTO CLEAR
TEST3: MOVLW 0X30 ;0 SUBWF DATA100,W BTFSC STATUS,Z ;判斷DATA100是否為0 GOTO TEST4 ;NO.5,4,3=0
CASE3: MOVF DATA100,W MOVWF LCD_DATA CALL WRDR
MOVF DATA10,W MOVWF LCD_DATA CALL WRDR
MOVF DATA1,W MOVWF LCD_DATA CALL WRDR GOTO CLEAR
TEST4: MOVLW 0X30 ;0 SUBWF DATA10,W BTFSC STATUS,Z ;判斷DATA100是否為0 GOTO CASE5 ;NO.5,4,3,2=0
CASE4: MOVF DATA10,W MOVWF LCD_DATA CALL WRDR
MOVF DATA1,W MOVWF LCD_DATA CALL WRDR GOTO CLEAR
CASE5: MOVF DATA1,W MOVWF LCD_DATA CALL WRDR GOTO CLEAR
;LCD CLEAR(清除顯示器)------------------> LCD_CLEAR: MOVLW B'00000001' MOVWF LCD_DATA CALL WRIR RETURN
;LCD CURSOR(游標歸位)-------------------> LCD_CURSOR: MOVLW B'00000010' MOVWF LCD_DATA CALL WRIR RETURN
;LCD ENTRY MODE(進入模式設定)-----------> LCD_ENTRY: MOVLW B'00000110' MOVWF LCD_DATA CALL WRIR RETURN
;LCD ON/OFF(顯示)-----------------------> LCD_ONOFF: MOVLW B'00001100' MOVWF LCD_DATA CALL WRIR RETURN
;LCD FUNCTION SETUP(功能設定)-----------> LCD_FUNC: MOVLW B'00111000' MOVWF LCD_DATA CALL WRIR RETURN
;指令寫入暫存器-------------------------> WRIR: BCF LCD_CMD,RS MOVF LCD_DATA,W MOVWF LCD_BUS BSF LCD_CMD,EN CALL DELAY BCF LCD_CMD,EN RETURN
;資料寫入暫存器--------------------------> WRDR: BSF LCD_CMD,RS MOVF LCD_DATA,W MOVWF LCD_BUS BSF LCD_CMD,EN CALL DELAY BCF LCD_CMD,EN RETURN ;TABLE------------------------> TABLE: ADDWF PCL,F RETLW 0X30 ; 0 RETLW 0X31 RETLW 0X32 RETLW 0X33 RETLW 0X34 RETLW 0X35 RETLW 0X36 RETLW 0X37 RETLW 0X38 RETLW 0X39 ; 9 ;LCD延遲副程式----------------------------> DELAY: MOVLW .2 MOVWF D3 DLY1: MOVLW .244 MOVWF D2 DLY2: DECFSZ D1,F GOTO DLY2 DECFSZ D2,F GOTO DLY2 DECFSZ D3,F GOTO DLY1 RETURN
;中斷-----------------------------------> INTSUB: MOVWF W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP
SWAPF D1,W MOVWF D1_TEMP SWAPF D2,W MOVWF D2_TEMP SWAPF D3,W MOVWF D3_TEMP ;判斷是CCP中斷或TEMP1中斷----> BTFSC PIR1,CCP1IF GOTO CCP_INT ;呼叫CCP中斷副程式 BTFSC PIR1,TMR1IF GOTO TIME_INT ;TEMP1中斷副程式 A: SWAPF D1_TEMP,W MOVWF D1 SWAPF D2_TEMP,W MOVWF D2 SWAPF D3_TEMP,W MOVWF D3
SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE ;CCP中斷副程式-----------------------------> CCP_INT: INCF COUNT0 CLRF CCPR1H CLRF CCPR1L
BSF SETBIT,0 BCF PIR1,CCP1IF GOTO A ;TEMP1中斷副程式---------------------------> TIME_INT: DECFSZ IDX,F GOTO NO BSF SETBIT,7 BSF SETBIT,6
MOVLW .10 MOVWF IDX NO: MOVLW 0X6D MOVWF TMR1H MOVLW 0X84 MOVWF TMR1L BCF PIR1,TMR1IF GOTO A
END
發表於: 2008/3/6 16:58
|