📄 avr_242_multiplexing_led_drive_and_4x4_keypad_sampling.asm
字号:
sbr flags,0x02 ;make load 2 active
rcall setrtc ;pickup new on time
mov ld2hron,hiset ;and store
mov ld2minon,loset
cbr flags,0x10 ;clear ld2on flag
rjmp case6
setld2off:
rcall setrtc ;pickup new on time
mov ld2hroff,hiset ;and store
mov ld2minoff,loset
cbr flags,0x20 ;clear ld2off flag
rjmp case7
;****Multiplexing routine to display time and scan keypad every*****
;****second pass,used by all routines taking digits from hibyte
;****and lobyte locations with each digit on for 5 ms
display: ser temp ;clear display
out PORTB,temp
;****Keypad scanning routine to update key flags*******************
keyscan: cbr flags,0x40 ;clear keyok flag
ldi key,0x10 ;set no key pressed value
ser temp ;set keypad port high prior to
out PORTB,temp ;reinitializing the port
in temp,PORTD ;turn off LEDs and leave loads
ori temp,0x0f ;untouched prior to
out PORTD,temp ;key scan
ldi temp,0x0f ;set columns output and
out DDRB,temp ;rows input with pull-ups
ldi temp,0xf0 ;enabled and all columns
out PORTB,temp ;low ready for scan
ldi temp,20 ;short settling time
tagain1: dec temp
brne tagain1
sbis PINB,ROW1 ;find row of keypress
ldi key,0 ;and set ROW pointer
sbis PINB,ROW2
ldi key,4
sbis PINB,ROW3
ldi key,8
sbis PINB,ROW4
ldi key,12
ldi temp,0xF0 ;change port B I/O to
out DDRB,temp ;find column press
ldi temp,0x0F ;enable pull ups and
out PORTB,temp ;write 0s to rows
ldi temp,20 ;short settling time
tagain2: dec temp
brne tagain2 ;allow time for port to settle
clr temp
sbis PINB,COL1 ;find column of keypress
ldi temp,0 ;and set COL pointer
sbis PINB,COL2
ldi temp,1
sbis PINB,COL3
ldi temp,2
sbis PINB,COL4
ldi temp,3
add key,temp ;merge ROW and COL for pointer
cpi key,0x10 ;if no key pressed
breq nokey ;escape routine, else
ldi temp,0x10
add key,temp ;change to table 2
out EEAR,key ;send address to EEPROM (0 - 15)
sbi EECR,EERE ;strobe EEPROM
in key,EEDR ;read decoded number for true key
convert: cpi key,10 ;is it SET key ?
brne notset ;no check next key
set ;yes set T flag in status register
notset: cpi key,11 ;is key CLEAR?
brne notclear ;no, check next key
sbi PORTD,LOAD1 ;yes, shut down all loads
sbi PORTD,LOAD2
cbr flags,0x03 ;deactivate both loads
notclear: cpi key,15 ;is key LD1ON?
brne notld1on ;no, check next key
sbr flags,0x04 ;yes, set LD1ON flag
notld1on: cpi key,14 ;is key LD1OFF?
brne notld1off ;no, check next key
sbr flags,0x08 ;yes, set LD1OFF flag
notld1off: cpi key,13 ;is key LD2ON?
brne notld2on ;no, check next key
sbr flags,0x10 ;yes, set LD2ON flag
notld2on: cpi key,12 ;is key LD2OFF?
brne notld2off ;no, check next key
sbr flags,0x20 ;yes, set LD2OFF flag
notld2off:
;***Tactile feedback note generation routine*****************
;***provides a 4 kHz TONE to the piezo sounder for 5 ms*****
tactile: cbr flags,0x80
cbi PORTD,PZ ;turn on piezo
ldi temp,125 ;for a short time
t1again: dec temp
brne t1again
sbi PORTD,PZ ;turn on piezo
ldi temp,125 ;for a short time
t2again: dec temp
brne t2again
sbrs flags,ms5 ;repeat for 5ms
rjmp tactile
notok: cpi bounce,40
brlo nokey
sbr flags,0x40 ;set bounce flag
nokey: ser temp
out DDRB,temp ;reinitialize port B as all Outputs
out PORTB,temp ;and clear LEDs
;***Display routine to multiplex all four LED digits****************
cbi PORTD,A1 ;turn digit 1 on
mov temp,lobyte ;find low minute
digit1:
cbr flags,0x80 ;clear 5 ms tick flag
andi temp,0x0f ;mask high nibble of digit
out EEAR,temp ;send address to EEPROM (0 - 15)
sbi EECR,EERE ;strobe EEPROM
in temp,EEDR ;read decoded number
sbrs flash,clear ;flash every 1/2 second
or temp,mask ;flash digit if needed
out PORTB,temp ;write to LED for 5 ms
led1: sbrs flags,ms5 ;5 ms finished?
rjmp led1 ;no, check again
sbi PORTD,A1 ;turn digit 1 off
ser temp ;clear display
out PORTB,temp
cbi PORTD,A2 ;
mov temp,lobyte ;find high minute
swap temp
digit2:
cbr flags,0x80 ;clear 5 ms tick flag
andi temp,0x0f ;mask high nibble of digit
out EEAR,temp ;send address to EEPROM (0 - 15)
sbi EECR,EERE ;strobe EEPROM
in temp,EEDR ;read decoded number
sbrs flash,clear ;flash every 1/2 second
or temp,mask ;flash digit if needed
out PORTB,temp ;write to LED for 5 ms
led2: sbrs flags,ms5 ;5 ms finished?
rjmp led2 ;no, check again
sbi PORTD,A2 ;
ser temp ;clear display
out PORTB,temp
cbi PORTD,A3 ;
mov temp,hibyte
digit3:
cbr flags,0x80 ;clear 5 ms tick flag
andi temp,0x0f ;mask high nibble of digit
out EEAR,temp ;send address to EEPROM (0 - 15)
sbi EECR,EERE ;strobe EEPROM
in temp,EEDR ;read decoded number
sbrs second,clear ;flash colon
andi temp,0x7f
sbrs flash,clear ;flash every 1/2 second
or temp,mask ;flash digit if needed
out PORTB,temp ;write to LED for 5 ms
led3: sbrs flags,ms5 ;5 ms finished?
rjmp led3 ;no, check again
sbi PORTD,A3
ser temp ;clear display
out PORTB,temp
cbi PORTD,A4 ;
mov temp,hibyte
swap temp
andi temp,0x0f ;is hi hour zero?
brne digit4
ldi temp,0xff ;yes,blank hi hour
digit4:
cbr flags,0x80 ;clear 5 ms tick flag
andi temp,0x0f ;mask high nibble of digit
out EEAR,temp ;send address to EEPROM (0 - 15)
sbi EECR,EERE ;strobe EEPROM
in temp,EEDR ;read decoded number
sbrs flash,clear ;flash every 1/2 second
or temp,mask ;flash digit if needed
out PORTB,temp ;write to LED for 5 ms
led4: sbrs flags,ms5 ;5 ms finished?
rjmp led4 ;no, check again
sbi PORTD,A4
ser temp ;clear display
out PORTB,temp
tst mask ;is flash complete?
breq outled ;yes, exit
cpi blink,50 ;is blink time done?
brlo outled ;no, exit
clr blink ;yes, clear blink rate counter
com flash ;and invert flash byte
outled: ret
;****Function to Set RTC/on-off hours and minutes from keypad
;****returns with minutes in 'loset' and hours in'hiset'
setrtc: ser mask ;set flashing display
ldi hibyte,0xdf ;place 'n' in hi hour
ser lobyte ;and blank in lo hr & minutes
hihrus: clr bounce
bounce1: rcall display ;display and check keypad
sbrs flags,keyok
rjmp bounce1
cbr flags,0x40 ;clear keyok flag
cpi key,0x03 ;is high hour > 2
brsh hihrus ;yes, read key again
hihrok: ;no, valid entry
swap key ;move hihour to hi nibble
mov hiset,key ;and store in hours
ldi hibyte,0x0d ;place 'n' in lo hour
add hibyte,hiset ;merge hihour and 'n'
lohrus: clr bounce
bounce2: rcall display ;display and check keypad
sbrs flags,keyok ;is key stable?
rjmp bounce2 ;no try again
cbr flags,0x40 ;yes, clear keyok flag
mov temp,hibyte ;check that total hours
andi temp,0xf0 ;are not > 24
add temp,key
cpi temp,0x24 ;is hour>24?
brsh lohrus ;yes, read key again
add hiset,key ;no, merge hi and lo hours
lohrok:
mov hibyte,hiset ;display hours as set
ldi lobyte,0xdf ;place 'n' in hi minutes
himinus: clr bounce
bounce3: rcall display ;display and check keypad
sbrs flags,keyok
rjmp bounce3
cbr flags,0x40 ;clear keyok flag
cpi key,6 ;is hi minutes >5
brsh himinus ;no, read key again
lominok:
swap key ;move himin to hi nibble
mov loset,key ;and store in minutes
ldi lobyte,0x0d ;place 'n' in lo minutes
add lobyte,loset ;merge with hi minute
lominus: clr bounce
bounce4: rcall display ;display and check keypad
sbrs flags,keyok
rjmp bounce4
cbr flags,0x40 ;clear keyok flag
cpi key,10 ;is key >9
brsh lominus ;no, read key again
add loset,key ;yes, merge hi and lo minutes
clr mask ;clear digits flash
ret ;and return with time set
;****Timer Overflow Interrupt service routine******************************
;****Updates 5 ms, flash and debounce counter to provide RTC time reference
tick:
in status,SREG ;preserve status register
inc tock ;add one to 5 ms 'tock' counter
inc blink ;and blink rate counter
inc bounce ;and bounce rate delay
sbr flags,0x80 ;set 5 ms flag for display time
cpi tock,200 ;is one second up?
breq onesec ;yes, add one to seconds
nop ;balance interrupt time
rjmp nosecond ;no, escape
onesec: inc second ;add one to seconds
clr tock ;clear 5 ms counter
nosecond: ldi timer,176 ;reload timer
out TCNT0,timer
out SREG,status ;restore status register
reti ;return to main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -