Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- list p=16F877A
- #include <p16f877A.inc> ; Include file locate at defult directory
- ; CONFIG
- ; __config 0xFF7A
- __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
- ;
- VAL_US equ .40 ; 1ms delay valum
- VAL_MS equ .100
- count equ 0x20 ; Defined temp reg. for 1ms delay
- count_ms equ 0x21 ; Defined delay reg.
- VAL_500u equ .80 ; 1ms delay valum
- count_500u equ 0x37 ; Defined temp reg. for 1ms delay
- ADDR_POLL equ 0x25 ;掃描顯示
- ADDR_DISP equ 0x26 ;轉 7 Segment
- ADDR_SOU equ 0x27 ;轉BCD (個位)
- ADDR_TEN equ 0x28 ;轉BCD 十位
- ADDR_CLOCK_SEC equ 0x22 ;秒
- ;ADDR_CLOCK_MIN equ 0x23 ;分
- ;ADDR_CLOCK_HUR equ 0x24 ;小時
- VAL_SEG_LEN equ .1 ;共顯示n位
- ADDR_SEG_DIG0 equ 0x31 ;第一位顯示
- ADDR_SEG_DIG1 equ 0x32 ;第二位顯示
- ADDR_SEG_DIG2 equ 0x33 ;第三位顯示
- ADDR_SEG_DIG3 equ 0x34 ;第四位顯示
- ADDR_SEG_DIG4 equ 0x35 ;第五位顯示
- ADDR_SEG_DIG5 equ 0x36 ;第六位顯示
- ADDR_SEG_DIG6 equ 0x37 ;第七位顯示
- ADDR_SEG_DIG7 equ 0x38 ;第八位顯示
- ;##### ISR #####
- ;### Temp For Interrupt
- ADDR_TEMP_STATUS equ 0x2D
- ADDR_TEMP_W equ 0x2E
- ;##### Timer 2 #####
- ;(1/4M)*4*16*16*(X+1)*Y = 10s
- VAL_TMR2_INIT equ .194 ;X
- VAL_TMR2_DIV equ .200 ;中斷Y次
- ADDR_TMR2_DIV equ 0x2F
- ;
- ;***************************************
- ; Program start *
- ;***************************************
- org 0x00 ; reset vector
- nop ; Reserve for MPLAB-ICD
- goto Initial
- org 0x04
- goto INTSUB
- Initial:
- clrw ; W =0
- clrf PCLATH
- banksel TRISA ; Select to bank1
- movlw 0x06
- movwf ADCON1
- clrf TRISA
- clrf TRISD
- clrf TRISE;TEST
- movlw b'11111111'
- movwf TRISB
- ;####################
- ;# Interupt Configure
- ;####################
- ;Timer 2 Configure
- bsf PIE1,TMR2IE
- movlw VAL_TMR2_INIT
- movwf PR2
- banksel PORTA ; Select to bank0
- bsf PORTE,0
- bsf PORTE,1
- movlw .0
- movwf ADDR_POLL
- ;Global & Timer 0 Interupt Configure
- movlw b'11000000'
- movwf INTCON
- ; <5> TMR0 Overflow Interrupt Enable bit
- ;##### Timer 2 Configuration
- movlw b'01111111'
- movwf T2CON
- clrf TMR2 ; Timer 2 的X
- bcf PIR1,TMR2IF
- ;##### Other
- clrf ADDR_CLOCK_SEC
- movlw b'11000000'
- ;movwf ADDR_DISP
- ;call bcd_to_segment
- ;movf ADDR_DISP,0
- movwf ADDR_SEG_DIG0
- movwf ADDR_SEG_DIG1
- movwf ADDR_SEG_DIG2
- movwf ADDR_SEG_DIG3
- movwf ADDR_SEG_DIG4
- movwf ADDR_SEG_DIG5
- ;movlw b'10110011'
- movwf ADDR_SEG_DIG6
- movwf ADDR_SEG_DIG7
- movlw VAL_TMR2_DIV
- movwf ADDR_TMR2_DIV
- ;
- ;************ Main *********************
- ;
- start:
- ;call test
- ;call task_button ;按鈕工作
- call task_display_time ;轉換工作 (BCD to Seg Code)
- ; call task_running_indcator
- call digi_polling ;掃描顯示工作 (Invoked to TMR0)
- call delay_1ms ; Call delay routine
- goto start
- task_display_time: ;顯示時間至7段
- ;更新秒
- movf ADDR_CLOCK_SEC,0
- call val_to_segment
- movf ADDR_SOU,0
- movwf ADDR_SEG_DIG0
- movf ADDR_TEN,0
- movwf ADDR_SEG_DIG1
- return
- val_to_segment: ;原值轉 7 段顯示碼
- movwf ADDR_SOU
- call BCD
- movf ADDR_SOU,0 ;個位轉SEG
- movwf ADDR_DISP
- call bcd_to_segment
- movwf ADDR_SOU
- movf ADDR_TEN,0 ;十位轉SEG
- movwf ADDR_DISP
- call bcd_to_segment
- movwf ADDR_TEN
- return
- digi_polling: ;掃描顯示
- ;Polling the digits pin
- incf ADDR_POLL
- movlw VAL_SEG_LEN
- subwf ADDR_POLL,W
- btfss STATUS,C
- goto digi_polling_fin
- clrf ADDR_POLL
- digi_polling_fin:
- movlw b'00111111'
- movwf PORTA
- movlw b'00000011'
- movwf PORTE
- movf ADDR_POLL,0
- addwf ADDR_POLL,0
- addwf ADDR_POLL,0
- addwf PCL
- movf ADDR_SEG_DIG0,0
- bcf PORTE,1
- goto seg_out
- movf ADDR_SEG_DIG1,0
- bcf PORTE,0
- goto seg_out
- movf ADDR_SEG_DIG2,0
- bcf PORTA,5
- goto seg_out
- movf ADDR_SEG_DIG3,0
- bcf PORTA,4
- goto seg_out
- movf ADDR_SEG_DIG4,0
- bcf PORTA,3
- goto seg_out
- movf ADDR_SEG_DIG5,0
- bcf PORTA,2
- goto seg_out
- movf ADDR_SEG_DIG6,0
- bcf PORTA,1
- goto seg_out
- movf ADDR_SEG_DIG7,0
- bcf PORTA,0
- goto seg_out
- seg_out:
- movwf PORTD
- return
- bcd_to_segment: ;BCD 轉 7 段碼
- ;Edge Check
- movlw ADDR_DISP
- sublw .9
- btfsc STATUS,0
- return
- movf ADDR_DISP,0
- addwf PCL
- retlw b'11000000' ;0
- retlw b'11111001' ;1
- retlw b'10100100' ;2
- retlw b'10110000' ;3
- retlw b'10011001' ;4
- retlw b'10010010' ;5
- retlw b'10000010' ;6
- retlw b'11111000' ;7
- retlw b'10000000' ;8
- retlw b'10010000' ;9
- BCD: ;轉 BCD 碼
- clrf ADDR_TEN
- BCD_TEN:
- movlw .10
- subwf ADDR_SOU,0
- btfss STATUS,0
- return
- movwf ADDR_SOU
- incf ADDR_TEN,1
- goto BCD_TEN
- INTSUB:
- ;Backup
- movwf ADDR_TEMP_W
- swapf STATUS,W
- movwf ADDR_TEMP_STATUS
- btfss PIR1,TMR2IF
- goto INTSUB_RESTORE
- T0A:
- ;軟除頻
- decfsz ADDR_TMR2_DIV
- goto T0_RESTORE
- movlw VAL_TMR2_DIV
- movwf ADDR_TMR2_DIV
- T0_INCREASE: ;開始遞增
- incf ADDR_CLOCK_SEC
- movlw .6
- subwf ADDR_CLOCK_SEC,w
- btfsc STATUS,Z
- clrf ADDR_CLOCK_SEC
- T0_RESTORE:
- bcf PIR1,TMR2IF
- clrf TMR2
- goto INTSUB_RESTORE
- INTSUB_RESTORE:
- swapf ADDR_TEMP_STATUS,W
- movwf STATUS
- swapf ADDR_TEMP_W,F
- swapf ADDR_TEMP_W,W
- RETFIE
- ;-------- 100 ms delay routine ----------
- delay_100ms:
- movlw VAL_MS
- movwf count_ms
- loop_ms
- call delay_1ms
- decfsz count_ms,f
- goto loop_ms
- return
- ;-------- 1 ms delay routine -----------
- delay_500us:
- movlw VAL_500u
- movwf count_500u
- dec_loop_500u
- call D_short
- decfsz count_500u,f
- goto dec_loop_500u
- return
- ;-------- 1 ms delay routine -----------
- delay_1ms:
- movlw VAL_US
- movwf count
- dec_loop
- call D_short
- decfsz count,f
- goto dec_loop
- return
- ;
- ;-------- Delay 5uS ------------- 25ms
- D_short
- call D_ret ; 1uS * 4 + 1uS = 10uS
- call D_ret
- call D_ret
- call D_ret
- nop
- nop
- D_ret return
- ;
- end
Add Comment
Please, Sign In to add comment