📄 p16demo.asm
字号:
sublw 0x40
btfss STATUS,Z ;is temp ready ??
goto get_temp ;NO, try again
movlw 0x00 ;YES, send temp command
banksel cmd_byte ;send temp register command
movwf cmd_byte
goto temp_now
convert_temp
movwf temperature
call bin_bcd ;NO, get temp ready for LCD
call LCDLine_1
movlw A'T' ;send "Temp=" to LCD
movwf temp_wr
call d_write
movlw A'e'
movwf temp_wr
call d_write
movlw A'm'
movwf temp_wr
call d_write
movlw A'p'
movwf temp_wr
call d_write
movlw 0x20 ;space
movwf temp_wr
call d_write
movlw A'='
movwf temp_wr
call d_write
movlw 0x20 ;space
movwf temp_wr
call d_write
movf MSD,w ;send high digit
movwf temp_wr
call d_write
movf MsD,w ;send middle digit
movwf temp_wr
call d_write
movf LSD,w ;send low digit
movwf temp_wr
call d_write
movlw A'C' ;send "C" for Celsius
movwf temp_wr
call d_write
movlw 0x20 ;space
movwf temp_wr
call d_write
movlw 0x20 ;space
movwf temp_wr
call d_write
movlw 0x20 ;space
movwf temp_wr
call d_write
call LCDLine_2 ;send "RB0 = Exit" to LCD
banksel ptr_pos
movlw .144
movwf ptr_pos
call stan_char_2
btfss select ;wait for RB0 release
goto $-1
call delay_100ms
btfss select ;exit ?
goto menu_clock ;YES, goto main menu
btfsc PIR1, TMR1IF ;2 second overflow occur ??
call write_eeprom ;YES
goto get_temp ;NO, get temperature again
;----------------- CLOCK ------------------------------------------
clock
btfss select ;wait for RB0 button release
goto $-1
banksel T1CON
movlw 0x0F ;intitialize TIMER1
movwf T1CON
clrf seconds
clrf minutes
clrf hours
overflow
bcf PIR1,TMR1IF
movlw 0x80
movwf TMR1H ;load regs for 1 sec overflow
clrf TMR1L
incf seconds,f ;increment seconds
movf seconds,w
sublw .60
btfss STATUS,Z ;increment minutes ?
goto clk_done
incf minutes,f
clrf seconds
movf minutes,w
sublw .60
btfss STATUS,Z ;increment hours ?
goto clk_done
incf hours,f
clrf minutes
movf hours,w
sublw .13
btfss STATUS,Z
goto clk_done
movlw .1 ;start a new 12 hour period
movwf hours
clk_done
movf hours,w ;send hours to LCD
call bin_bcd
call LCDLine_1 ;place time on line 1
movf MsD,w ;send middle digit
movwf temp_wr
call d_write
movf LSD,w ;send low digit
movwf temp_wr
call d_write
movlw 0x3A ;send : colon
movwf temp_wr
call d_write
movf minutes,w ;send minutes to LCD
call bin_bcd
movf MsD,w ;send middle digit
movwf temp_wr
call d_write
movf LSD,w ;send low digit
movwf temp_wr
call d_write
movlw 0x3A ; send : colon
movwf temp_wr
call d_write
movf seconds,w ;send seconds to LCD
call bin_bcd
movf MsD,w ;send middle digit
movwf temp_wr
call d_write
movf LSD,w ;send low digit
movwf temp_wr
call d_write
movlw 0x20 ;send 3 spaces after 00:00:00
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
banksel ptr_pos ;send "RA4=Dn RB0=Menu" to LCD
movlw .112
movwf ptr_pos
call stan_char_2
banksel PORTA
btfss scroll ;set time ??
goto set_time
btfss select ;return to main menu ??
goto menu
btfss PIR1,TMR1IF ;has timer1 overflowed ?
goto $-1 ;NO, wait til overflow
goto overflow ;YES
return
;*******************************************************************
;************************** ROUTINES ******************************
;******************************************************************
;******************************************************************
;----Standard code, Place characters on line-1--------------------------
stan_char_1
call LCDLine_1 ;mvoe cursor to line 1
banksel ptr_count
movlw .16 ;1-full line of LCD
movwf ptr_count
stan_next_char_1
movlw HIGH stan_table
movwf PCLATH
movf ptr_pos,w ;character table location
call stan_table ;retrieve 1 character
movwf temp_wr
call d_write ;send character to LCD
banksel ptr_pos ;get next character for LCD
incf ptr_pos,f
decfsz ptr_count,f ;move pointer to next char
goto stan_next_char_1
banksel TXREG ;move data into TXREG
movlw "\n" ;next line
movwf TXREG
banksel TXSTA
btfss TXSTA,TRMT ;wait for data TX
goto $-1
banksel TXREG ;move data into TXREG
movlw "\r" ;carriage return
movwf TXREG
banksel TXSTA
btfss TXSTA,TRMT ;wait for data TX
goto $-1
banksel PORTA ;bank 0
return
;----Standard code, Place characters on line-2--------------------------
stan_char_2
call LCDLine_2 ;move cursor to line 2
banksel ptr_count
movlw .16 ;1-full line of LCD
movwf ptr_count
stan_next_char_2
movlw HIGH stan_table
movwf PCLATH
movf ptr_pos,w ;character table location
call stan_table ;retrieve 1 character
movwf temp_wr
call d_write ;send character to LCD
banksel ptr_pos ;get next character for lCD
incf ptr_pos,f
decfsz ptr_count,f ;move pointer to next char
goto stan_next_char_2
banksel TXREG ;move data into TXREG
movlw "\n" ;next line
movwf TXREG
banksel TXSTA
btfss TXSTA,TRMT ;wait for data TX
goto $-1
banksel TXREG ;move data into TXREG
movlw "\r" ;carriage return
movwf TXREG
banksel TXSTA
btfss TXSTA,TRMT ;wait for data TX
goto $-1
banksel PORTA ;bank 0
return
;----------------------------------------------------------------------
;------------------ 100ms Delay --------------------------------
delay_100ms
banksel temp_1
movlw 0xFF
movwf temp_1
movlw 0x83
movwf temp_2
decfsz temp_1,f
goto $-1
decfsz temp_2,f
goto $-3
return
;---------------- 1s Delay -----------------------------------
delay_1s
banksel temp_1
movlw 0xFF
movwf temp_1
movwf temp_2
movlw 0x05
movwf temp_3
decfsz temp_1,f
goto $-1
decfsz temp_2,f
goto $-3
decfsz temp_3,f
goto $-5
return
;---------------- Set Current Time ----------------------------
set_time
banksel ptr_pos ;send "RA4= --> RBO= ++" to LCD
movlw .128
movwf ptr_pos
call stan_char_2
set_time_again
btfss scroll ;wait for RA4 button release
goto $-1
call LCDLine_1 ;start at 0x00 on LCD
btfss select ;wait for RB0 button release
goto $-1
call delay_100ms
btfss select ;increment hours (tens) ?
goto inc_hours
goto next_digit
inc_hours
incf hours
movf hours,w ;check if hours has passed 12 ?
sublw .13
btfss STATUS,Z
goto $+2
clrf hours ;YES, reset hours to 00
next_digit
btfss scroll ;move to next digit
goto inc_mins
movf hours,w
call bin_bcd ;get hours ready for display
movf MsD,w ;send tens digit
movwf temp_wr
call d_write
movf LSD,w ;send ones digit
movwf temp_wr
call d_write
movlw 0x3A ;send : colon
movwf temp_wr
call d_write
goto set_time_again
inc_mins
btfss scroll ;wait for RA4 button release
goto $-1
call LCDLine_1
movlw 0x14 ;shift cursor to right 3 places
movwf temp_wr
call i_write
movlw 0x14
movwf temp_wr
call i_write
movlw 0x14
movwf temp_wr
call i_write
btfss select ;wait for RB0 button release
goto $-1
call delay_100ms
btfss select ;increment minutes (tens) ?
goto inc_minutes
goto next_digit?
inc_minutes
incf minutes
movf minutes,w ;check if hours has passed 12 ?
sublw .60
btfss STATUS,Z
goto $+2
clrf minutes
next_digit?
btfss scroll ;move to next digit
goto set_time_done
movf minutes,w
call bin_bcd ;get minutes ready for display
movf MsD,w ;send tens digit
movwf temp_wr
call d_write
movf LSD,w ;send ones digit
movwf temp_wr
call d_write
movlw 0x3A ;send : colon
movwf temp_wr
call d_write
goto inc_mins
set_time_done
btfss scroll ;wait for RA4 button release
goto $-1
goto overflow
;---------------- Binary (8-bit) to BCD -----------------------
; 255 = highest possible result
bin_bcd
banksel MSD
clrf MSD
clrf MsD
movwf LSD ;move value to LSD
ghundreth
movlw .100 ;subtract 100 from LSD
subwf LSD,w
btfss STATUS,C ;is value greater then 100
goto gtenth ;NO goto tenths
movwf LSD ;YES, move subtraction result into LSD
incf MSD,f ;increment hundreths
goto ghundreth
gtenth
movlw .10 ;take care of tenths
subwf LSD,w
btfss STATUS,C
goto over ;finished conversion
movwf LSD
incf MsD,f ;increment tenths position
goto gtenth
over ;0 - 9, high nibble = 3 for LCD
movf MSD,w ;get BCD values ready for LCD display
xorlw 0x30 ;convert to LCD digit
movwf MSD
movf MsD,w
xorlw 0x30 ;convert to LCD digit
movwf MsD
movf LSD,w
xorlw 0x30 ;convert to LCD digit
movwf LSD
retlw 0
;---------------- Binary (16-bit) to BCD -----------------------
; xxx = highest possible result
bin16_bcd ; Takes number in NumH:NumL
; Returns decimal in TenK:Thou:Hund:Tens:Ones
swapf NumH,w
andlw 0x0F
addlw 0xF0
movwf Thou
addwf Thou,f
addlw 0xE2
movwf Hund
addlw 0x32
movwf Ones
movf NumH,w
andlw 0x0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0xE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf NumL,w
andlw 0x0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf NumL,w
andlw 0x0F
addwf Ones,f
rlf Thou,f
movlw 0x07
movwf TenK
movlw 0x0A ; Ten
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
retlw 0
;---------------------------- EEPROM WRITE -------------------------------
write_eeprom
banksel SSPCON2 ;write to EEPROM
bsf SSPCON2,SEN ;start bit
btfsc SSPCON2,SEN
goto $-1
movlw B'10100000' ;send control byte (write)
banksel SSPBUF
movwf SSPBUF
call ssprw
banksel SSPCON2
btfsc SSPCON2,ACKSTAT ;ack?
goto $-1
movlw 0x00 ;send slave address HIGH byte
banksel SSPBUF
movwf SSPBUF
call ssprw
banksel SSPCON2
btfsc SSPCON2,ACKSTAT ;ack?
goto $-1
movlw 0x05 ;send slave address LOW byte(0x0005)
banksel SSPBUF
movwf SSPBUF
call ssprw
banksel SSPCON2
btfsc SSPCON2,ACKSTAT ;ack?
goto $-1
banksel temperature
movf temperature,w ;send slave DATA = temperature
movwf SSPBUF
call ssprw
banksel SSPCON2
btfsc SSPCON2,ACKSTAT ;ack?
goto $-1
bsf SSPCON2,PEN ;stop bit
btfsc SSPCON2,PEN
goto $-1
banksel TMR1L
bcf PIR1,TMR1IF ;clear TIMER1 overflow flag
clrf TMR1L ;clear registers for next overflow
clrf TMR1H
return
;------------------------ IDLE MODULE -------------------------------------
ssprw ;check for idle SSP module
movlw 0x00
banksel SSPCON2
andwf SSPCON2,w
sublw 0x00
btfss STATUS,Z
goto $-4
btfsc SSPSTAT,R_W
goto $-1
return
;---------------------------------------------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -