📄 keypad.a51
字号:
$NOMOD51
#include "reg66x.h"
NAME night_mode
EXTRN CODE (i2c_init, SPI_init, SC16_init, LCD_init, lcd_wrtdata, lcd_str, lcd_loc, lcd_clr)
PUBLIC sw_code, xy, ldata
?STACK SEGMENT IDATA
RSEG ?STACK
DS 30H ; reserve 30h bytes for stack
data_seg_name SEGMENT DATA
RSEG data_seg_name
xy: DS 1 ; desired location to write on LCD before provoke LCD_LOC routine
ldata: DS 1 ; 1 character data to write to LCD before provoke LCD_WRTDATA
sw_code: DS 1 ; contains switch data
redled EQU P1.0 ;red led is connected to pin 0 of port 1
yellowled EQU P1.4 ;yellow led is connected to pin 4 of port 1
keypad_0 EQU P0.0
keypad_1 EQU P0.1
keypad_2 EQU P0.2
keypad_3 EQU P0.3
data_ready EQU P0.4
bit_seg_name SEGMENT BIT
RSEG bit_seg_name
delay_on: DBIT 1 ;not used, for illustration only
CSEG AT 0
LJMP start
code_seg_name SEGMENT CODE
RSEG code_seg_name
USING 0
line1: DB 'Home System$'
line2: DB ' Enter Password$'
line3: DB ' Sensor: $'
line4: DB ' Wrong Password$'
line5: DB ' Wrong Code$'
line6: DB '*$'
line7: DB '**$'
line8: DB '***$'
line9: DB '***C$'
line10: DB ' Night Mode$'
;------------------------------------------------------------------------------
; Main program
;------------------------------------------------------------------------------
Start: MOV SP,#?STACK-1
CALL System_init ;system initialisation
CALL LCD_clr ;clear LCD
CLR redled
CLR yellowled
MOV xy, #00h ;display string starts at top line column 0
MOV DPTR, #line1 ;display 'Home Alarm System'
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #0Ah ;delay MSB in B
CALL TimerDelay ;short delay to display welcome message
CALL LCD_clr
SETB redled
SETB yellowled
MOV R0,#00h ;RO contain status of System
;RO=00h means system deactivated
;RO=01h means system in night mode
;R0=02h means system in away mode, NOT INCLUDE IN THIS PROGRAM
;RO=03h means system's alarm activated
MOV 0X71,#00h ;0X71 contain the 1st digit Password
MOV 0X72,#01h ;0X72 contain the 1st digit Password
MOV 0X73,#02h ;0X73 contain the 1st digit Password
check_alarm: ;check whether the system's alarm is activated or not
CJNE R0,#03h,check_armed
SJMP get_password ;system's alarm activated, check for deactivation code
check_armed: ;check whether the system is armed or not
CJNE R0,#00h,check_sensor
SJMP get_password ;system is not armed, no checking of senor is needed
check_sensor: ;check whether sensor activated for night mode only
MOV R1,#'1' ;R1 will contains the button number to display
MOV A, sw_code ;sw_code contains switch status
loop: RRC A ;Rotate right into carry to check bit by bit
JNC disp_key ;check if switch "R1" pressed, if yes check whether system armed
INC R1 ;if not increase "R1" to represent the next button
CJNE R1,#'8',loop ;finished
SJMP get_next
disp_key: ;active alarm and display sensor causing the activation
CLR redled
CALL LCD_clr
MOV xy, #00h ;Set to top line left column
MOV DPTR, #line3 ;display string "Sensor :"at top line
CALL lcd_str ;
MOV xy, #0Fh ;Display button number at last location
MOV ldata, R1
CALL lcd_loc ;set Lcd location
CALL lcd_wrtdata
MOV R0,#03h ;update RO of the activation of alarm
SJMP get_next
get_next: JB data_ready,check_alarm
get_password: ;get the 3 digits password
MOV R1,#00h ;R1 contain the number of time the password is enter wrongly
check_password: ;check whether the 3 digit password is correct
MOV xy, #00h ;display string starts at top line column 0
MOV DPTR, #line2 ;display 'Enter Password'
CALL lcd_str
CALL check_keypad ;value store in Acc
CJNE A,#0Ch,password_1
CALL LCD_clr
SJMP check_alarm ;'*' entered, cancel command and go back to starting
password_1: MOV R2,A ;R2 contain the 1st digit of Password
MOV xy, #10h ;display string starts at bottom line column 0
MOV DPTR, #line6 ;display 1st password
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #03h ;delay MSB in B
CALL TimerDelay ;short delay
CALL check_keypad ;value store in Acc
CJNE A,#0Ch,password_2
CALL LCD_clr
SJMP check_alarm ;'*' entered, cancel command and return to starting
password_2: MOV R3,A ;R3 contain the 2nd digit of Password
MOV xy, #10h ;display string starts at bottom line column 0
MOV DPTR, #line7 ;display 2nd password
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #03h ;delay MSB in B
CALL TimerDelay ;short delay
CALL check_keypad ;value store in Acc
CJNE A,#0Ch,password_3
CALL LCD_clr
LJMP check_alarm ;'*' entered, cancel command and return to starting
password_3: MOV R4,A ;R4 contain the 3nd digit of Password
MOV xy, #10h ;display string starts at bottom line column 0
MOV DPTR, #line8 ;display 3rd password
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #03h ;delay MSB in B
CALL TimerDelay ;short delay
password_check: ;check for error in the password
MOV A,R2
CJNE A,0X71,password_error ;check 1st digit
MOV A,R3
CJNE A,0X72,password_error ;check 2nd digit
MOV A,R4
CJNE A,0X73,password_error ;check 3rd digit
SJMP check_mode
password_error:
INC R1
CJNE R1,#03h,error_display
CLR redled ;activate alarm if password enter wrongly 3 times
MOV R0,#03h ;update RO of the activation of alarm
MOV R1,#00h
error_display:
CALL LCD_clr
MOV xy, #00h ;display string starts at top line column 0
MOV DPTR, #line4 ;display Error Wrong Password
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #05h ;delay MSB in B
CALL TimerDelay ;short delay to display error message
LJMP check_password
check_mode:
CALL check_keypad ;value store in Acc
CJNE A,#0Ch,check_deact
LJMP check_alarm ;'*' entered, cancel command and go back to starting
check_deact: ;check whether deactivation
CJNE A,#0Eh,check_alarmmode
SETB redled
SETB yellowled
MOV R0,#00h ;update RO of the deactivation of alarm and system
CALL LCD_clr
MOV a, #0FFh ;delay LSB in A
MOV b, #03h ;delay MSB in B
CALL TimerDelay ;short delay
LJMP get_password
check_alarmmode: ;check whether the system's alarm is on
CJNE R0,#03h,check_armingmode
SJMP code_error_display
check_armingmode:
CJNE A,#0Bh,code_error_display
MOV xy, #10h ;display string starts at bottom line column 0
MOV DPTR, #line9 ;display 3digit password with 'C'
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #03h ;delay MSB in B
CALL TimerDelay ;short delay
CALL check_keypad
CJNE A,#0Eh,code_error_display
CALL LCD_clr
MOV xy, #00h ;display string starts at top line column 0
MOV DPTR, #line10 ;display Night Mode
CALL lcd_str
clr yellowled
MOV R0,#01h
MOV a, #0FFh ;delay LSB in A
MOV b, #05h ;delay MSB in B
CALL TimerDelay ;short delay to display mode message
CALL LCD_clr
LJMP check_sensor
code_error_display: ;display error code
CALL LCD_clr
MOV xy, #00h ;display string starts at top line column 0
MOV DPTR, #line5 ;display Wrong Code
CALL lcd_str
MOV a, #0FFh ;delay LSB in A
MOV b, #05h ;delay MSB in B
CALL TimerDelay ;short delay to display error message
CALL LCD_clr
LJMP check_armed
;------------------------------------------------------------------------------
; Initialize the system upon power on
;------------------------------------------------------------------------------
System_init:
CALL SPI_init ;initialised Serial Peripheral Interface
CALL i2c_init ;initialised I2C interface
SETB EA ;use internal ROM
CALL LCD_init ;initialised LCD display
CALL SC16_init ;
MOV sw_code, #7Fh ;initialise switch status to off
RET
;------------------------------------------------------------------------------
; Delay routine (Input: A, B) uses Timer 0
;------------------------------------------------------------------------------
TimerDelay:
push AR0 ;push r0 into stack
anl tcon,#0cfh ; Clear T0 overflow & run flags only
anl tmod,#0f0h ; T0 enabled; T1 control unchanged
orl tmod,#01h ; set T0 to mode 1 (16 bit up counter)
onems:
mov TL0, #18h ;set T0 to count up from FC18h
mov TH0, #0fch
orl TCON, #10h ;start T0 timer
wait:
jbc Tf0, dwnab ; poll T0 overflow flag until set
sjmp wait ; loop until Overflow flag set
dwnab:
anl TCON, #0efh ;stop T0; other TCON bits unchanged
dec a ;count A down
cjne a, #0ffh, noroll ;
dec b ; count B down
noroll:
mov r0, b
cjne r0,#00h,onems
done: pop AR0 ; pop r0 out of stack
ret
;R2 is used to store the keypad pressed
check_keypad:
JB data_ready,check_keypad
CLR A
JNB keypad_0,check_keypad_1
ADD A,#01h ;value of keypad is XXX1 or P0.0=HIGH
check_keypad_1: JNB keypad_1,check_keypad_2
ADD A,#02h ;value of keypad is XX1X or P0.1=HIGH
check_keypad_2: JNB keypad_2,check_keypad_3
ADD A,#04h ;value of keypad is X1XX or P0.2=HIGH
check_keypad_3: JNB keypad_3,keypad_store
ADD A,#08h ;value of keypad is 1XXX or P0.3=HIGH
keypad_store: RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -