📄 picclock.sdi
字号:
,,, LIST p=16F84 ; PIC16F844 is the target processor
,,,
,,, #include "P16F84.INC" ; Include header file
,,,
,,, CBLOCK 0x10 ; Temporary storage
,,, state
,,, secs
,,, mins
,,, hours
,,, ticks
,,, idc
,,, bcd
,,, ENDC
,,,
,,,; Constants for bit allocation. The BIT_x constants are actual bit numbers and
,,,; the MASK_x are bit masks for the same bit.
,,,BIT_HSEL EQU H'0000'
,,,BIT_TSET EQU H'0001'
,,,BIT_HSET EQU H'0002'
,,,BIT_MSET EQU H'0003'
,,,
,,,BIT_H24 EQU H'0000'
,,,BIT_PM EQU H'0001'
,,,BIT_SET EQU H'0002'
,,,BIT_HSB EQU H'0003'
,,,
,,,MASK_H24 EQU H'0001'
,,,MASK_PM EQU H'0002'
,,,MASK_SET EQU H'0004'
,,,MASK_HSB EQU H'0008'
,,,
,,,
,,,; Macro to generate a MOVLW instruction that also causes a model break:
,,,break MACRO arg
,,, DW 0x3100 | (arg & H'FF')
,,, ENDM
,,,
,,, ORG 0
0000,2805,entrypoint,entrypoint goto initialise
,,,
,,, ORG 4
0004,2821,intvector,intvector goto clock
,,,
0005,,initialise,initialise ; Register set up:
0005,0103,, clrw ; Zero.
0006,0085,, movwf PORTA ; Ensure PORTA is zero before we enable it.
0007,0086,, movwf PORTB ; Ensure PORTB is zero before we enable it.
0008,1683,, bsf STATUS,RP0 ; Select Bank 1
0009,301F,, movlw H'1F' ; Mask for PORTA inputs/outputs.
000A,0085,, movwf TRISA ; Set TRISA register.
000B,3001,, movlw H'01' ; Mask for PORTA inputs/outputs.
000C,0086,, movwf TRISB ; Set TRISB register.
000D,1283,, bcf STATUS,RP0 ; Reselect Bank 0.
,,,
,,, ; Initialise clock:
000E,0190,, clrf state
000F,1590,, bsf state,BIT_HSB
0010,3000,, movlw D'0'
0011,0093,, movwf hours
0012,3000,, movlw D'0'
0013,0092,, movwf mins
0014,3000,, movlw D'0'
0015,0091,, movwf secs
,,,
,,, ; Clear 50Hz tick count:
0016,0194,, clrf ticks
,,,
,,, ; Clear interrupt disable count (idc) semaphore:
0017,0195,, clrf idc
,,,
,,, ; Initialise display:
0018,20CE,, call wr_hours
0019,20BF,, call wr_mins
001A,20B0,, call wr_secs
001B,20DD,, call wr_state
,,,
,,, ; Finally initialise interrupts for clock on RB0/INT pin:
001C,3090,, movlw H'90'
001D,008B,, movwf INTCON
,,,
001E,,start,start ; When not processing an interrupt we sit and check input pins:
001E,2075,, call chk_tset ; Time set select active?
001F,2044,, call chk_hsel ; H12/H24 display format select active?
0020,281E,, goto start
,,,
,,,
,,,;------------------------------------------------------------------------------
,,,; Interrupt handler. We come here for every tick of the time base.
,,,
0021,,clock,clock ; Toggle half-second flag and set state outputs:
0021,0A94,, incf ticks,F ; Increment clock ticks.
0022,0814,, movf ticks,W ; Get ticks value.
0023,3C19,, sublw D'25' ; Is it 25 (W=25-W)?
0024,1D03,, btfss STATUS,Z ; Test zero flag.
0025,2841,, goto endclock ; Return.
,,,
0026,,toggle_hs,toggle_hs ; Half second - toggle HS flag, write it and return:
0026,0194,, clrf ticks ; Reset timebase,
0027,0810,, movf state,W ; Get state.
0028,3A08,, xorlw MASK_HSB ; Toggle half-second bit.
0029,0090,, movwf state ; Save it back to register.
002A,20DD,, call wr_state ; Display it.
002B,0810,, movf state,W ; Get state.
002C,1D90,, btfss state,BIT_HSB ; Is bit now clear?
002D,2841,, goto endclock ; Return.
,,,
002E,,inc_secs,inc_secs ; Incrmement seconds...
002E,0A91,, incf secs,F ; Increment seconds count.
002F,0811,, movf secs,W ; Get it into W.
0030,3C3C,, sublw D'60' ; Is it 60 (W=60-W)?
0031,1903,, btfsc STATUS,Z ; Test zero flag, skip clear if no set.
0032,2835,, goto reset_secs ; Clear seconds, increment minutes.
0033,20B0,, call wr_secs ; Write seconds it to display.
0034,2841,, goto endclock ; Done.
,,,
0035,0191,reset_secs,reset_secs clrf secs
0036,20B0,, call wr_secs ; Write seconds to display.
,,,
0037,0A92,, incf mins,F ; Increment minute count.
0038,0812,, movf mins,W ; Get it into W.
0039,3C3C,, sublw D'60' ; Is it 60 (W=60-W)?
003A,1903,, btfsc STATUS,Z ; Test zero flag, skip clear if no set.
003B,283E,, goto reset_mins ; Clear minutes, increment hours.
003C,20BF,, call wr_mins ; Write minutes it to display.
003D,2841,, goto endclock ; Done.
,,,
003E,0192,reset_mins,reset_mins clrf mins ; Reset minute count to zero.
003F,20BF,, call wr_mins ; Write minutes to display.
,,,
0040,2099,, call inc_hours ; Increment hours, display it with PM flag.
,,,
0041,3090,endclock,endclock movlw H'90'
0042,008B,, movwf INTCON
0043,0009,, retfie ; Return
,,,
,,,;------------------------------------------------------------------------------
,,,; Subroutine. Check the state of the HSEL input and set h12/h24 format as
,,,; required.
,,,
0044,1805,chk_hsel,chk_hsel btfsc PORTA,BIT_HSEL ; Test 12/24 select.
0045,2857,, goto set_h12 ; H12 set so switch to 12 hour format.
,,, ; fall through ; H12 not set so switch to 24 hour format.
,,,
0046,1810,set_h24,set_h24 btfsc state,BIT_H24 ; Are we on 12 hour format?
0047,3400,, retlw 0 ; No, so no need to do anything...
,,,
0048,138B,, bcf INTCON,GIE ; Disable interrupts.
0049,0A95,, incf idc,F ; Increment count of number of disables.
004A,1410,, bsf state,BIT_H24 ; Clear h12 flag.
,,,
004B,0813,, movf hours,W ; Get hours value.
004C,3C0C,, sublw D'12' ; Is it 12:xx?
004D,1903,, btfsc STATUS,Z ; Test zero flag.
004E,0193,, clrf hours ; Reset to zero.
004F,0813,, movf hours,W ; Get hours value.
0050,1890,, btfsc state,BIT_PM ; Is the PM indicator set?
0051,3E0C,, addlw D'12' ; Add 12 to get 24 hour value.
0052,0093,, movwf hours ; Save result (does nothing for AM).
0053,1090,, bcf state,BIT_PM ; Clear PM flag.
0054,20CE,, call wr_hours ; Write hours.
0055,20DD,, call wr_state ; Write H12 state and PM state.
0056,2870,, goto chk_hsel_iec ; Done.
,,,
0057,1C10,set_h12,set_h12 btfss state,BIT_H24 ; Are we on 12 hour format?
0058,3400,, retlw 0 ; Yes, so no need to do anything...
,,,
0059,138B,, bcf INTCON,GIE ; Disable interrupts.
005A,0A95,, incf idc,F ; Increment count of number of disables.
005B,1010,, bcf state,BIT_H24 ; Set h12 flag.
,,,
005C,0813,, movf hours,W ; Get hour value.
005D,3C0B,, sublw D'11' ; W=11-W. C is clear for a borrow (W>=12).
005E,1C03,, btfss STATUS,C ; Test carry flag.
005F,2868,, goto set_h12_pm ; Set PM.
,,,
0060,1090,set_h12_am,set_h12_am bcf state,BIT_PM ; Clear PM bit.
0061,0813,, movf hours,W ; Get hours.
0062,1903,, btfsc STATUS,Z ; Is it zero?
0063,3E0C,, addlw D'12' ; Yes, add 12 to get 00:xx to 12:xx.
0064,0093,, movwf hours ; Save any result.
0065,20CE,, call wr_hours ; Display hours.
0066,20DD,, call wr_state ; Display H12 and PM states.
0067,2870,, goto chk_hsel_iec ; Done.
,,,
0068,1490,set_h12_pm,set_h12_pm bsf state,BIT_PM ; Set PM bit.
0069,300C,, movlw D'12' ; Constant.
006A,0293,, subwf hours,F ; hours=hours-12 (23..12 -> 11..0).
006B,1903,, btfsc STATUS,Z ; Zero set?
006C,0093,, movwf hours ; Yes, so reset to '12'.
006D,20CE,, call wr_hours ; No, so leave hours alone and display it.
006E,20DD,, call wr_state ; Display H12 and PM states.
006F,2870,, goto chk_hsel_iec ; Done.
,,,
0070,0B95,chk_hsel_iec,chk_hsel_iec decfsz idc,F ; Decrement idc. If zero we can reenable interrupts.
0071,3401,, retlw 1 ; Return without enabling interrupts.
,,,
0072,3090,chk_hsel_done,chk_hsel_done movlw H'90' ; Constant for GIE and T0IE.
0073,008B,, movwf INTCON ; Set interrupt register.
0074,3401,, retlw 1 ; Return.
,,,
,,,;------------------------------------------------------------------------------
0075,1885,chk_tset,chk_tset btfsc PORTA,BIT_TSET ; Set mode?
0076,3400,, retlw 0
,,,
0077,138B,, bcf INTCON,GIE ; Disable interrupts.
0078,0A95,, incf idc,F ; Increment count of number of disables.
0079,1510,, bsf state,BIT_SET ; Set the 'set mode' bit.
007A,0191,, clrf secs ; Setting time resets seconds count.
007B,20B0,, call wr_secs ; Display it.
007C,1190,, bcf state,BIT_HSB ; Clear seconds toggle.
007D,20DD,, call wr_state ; Update the state output latch.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -