📄 avr_242_multiplexing_led_drive_and_4x4_keypad_sampling.asm
字号:
;**** A P P L I C A T I O N N O T E A V R ??? ************************
;*
;* Title: Multiplexing LED drive and 4x4 keypad sampling
;* Version: 1.0
;* Last Updated: 98.07.24
;* Target: All AVR Devices
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This Application note covers a program to provide a 24 hr Industrial
;* timer or real-time clock using I/O pins for dual functions.
;* With input via a 4 x 4 matrix keypad, output to a multiplexed
;* four digit LED display and two ON/OFF outputs to drive loads via additional
;* interface circuitry. LED loads are driven in this example but it could drive
;* any load with the addition of suitable components. Tactile feedback is provided
;* on every key press by a piezo sounder which beeps when a key is pressed.
;* Included is a main program that allows clock setting via the keypad
;* and one ON/OFF time setting per 24 hours for each load, functions for the
;* real time clock, key scanning, and adjustment routines. The example runs on
;* the AT90S1200 to demonstrate how limited I/O can be overcome, but can
;* be any AVR with suitable changes in vectors, EEPROM and stack pointer.
;* The timing assumes a 4.096 MHz crystal is employed (a 4 MHz crystal produces
;* an error of -0.16% if 178 instead of 176 used in the timer load sequence, but this
;* could be adjusted in software at regular intervals). Look up tables are
;* used in EEPROM to decode the display data, with additional characters provided
;* for time and ON/OFF setting displays and a key pad conversion table.
;* If the EEPROM is needed for your application the tables could be moved
;* to ROM in the larger AVR devices.
;***************************************************************************
;***** Registers used by all programs
;******Global variables used by routines
.def loset =r1 ;storage for timeset minutes
.def hiset =r2 ;storage for timeset hours
.def ld1minon=r3 ;storage for load on and off times
.def ld1hron =r4 ;set from keypad entry
.def ld1minoff=r5 ;and tested in the housekeeping function
.def ld1hroff=r6 ;and stores on or off times for the loads
.def ld2minon=r7
.def ld2hron =r8
.def ld2minoff=r9
.def ld2hroff=r10
.def temp =r16 ;general scratch space
.def second =r17 ;storage for RTC second count
.def minute =r18 ;storage for RTC minute count
.def hour =r19 ;storage for RTC hour count
.def mask =r20 ;flash mask for digits flashing
.def blink =r21 ;colon blink rate counter
.def bounce =r22 ;keypad debounce counter
.def flash =r23 ;flash delay counter
.def lobyte =r24 ;storage for display function minutes digits
.def hibyte =r25 ;storage for display function hours digits
.def key =r26 ;key number from scan
;***'key' values returned by 'keyscan'***************************
;VALUE 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
;KEY 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C NONE
;FUNC 1 2 3 LD1ON 4 5 6 LD1OFF 7 8 9 LD2ON SET 0 CLEAR LD2OFF
.def tock =r27 ;5 ms pulse
.def flags =r28 ;flag byte for keypad command keys
; 7 6 5 4 3 2 1 0
; 5ms keyok ld2off ld2on ld1off ld1on ld2 ld1
; tick 0 = off, 1 = on
.equ ms5 =7 ;ticks at 5 ms intervals for display time
.equ keyok =6 ;sets when key is debounced, must be cleared again
.equ ld2off =5 ;set by load ON/OFF key press and flags
.equ ld2on =4 ;up the need for action
.equ ld1off =3 ;in the housekeeping routine
.equ ld1on =2
.equ ld2 =1 ;when set tells the housekeeping routine to
.equ ld1 =0 ;check load on/off times.
;***the T flag in the status register is used as a SET flag for time set
.equ clear =0 ;RTC modification demand flag
;Port B pins
.equ col1 =0 ;LED a segment/keypad col 1
.equ col2 =1 ;LED b segment/keypad col 2
.equ col3 =2 ;LED c segment/keypad col 3
.equ col4 =3 ;LED d segment/keypad col 4
.equ row1 =4 ;LED e segment/keypad row 1
.equ row2 =5 ;LED f segment/keypad row 2
.equ row3 =6 ;LED g segment/keypad row 3
.equ row4 =7 ;LED decimal point/keypad row 4
;Port D pins
.equ A1 =0 ;common anode drives (active low)
.equ A2 =1 ;
.equ A3 =2 ;
.equ A4 =3 ;
.equ LOAD1 =4 ;Load 1 output (active low)
.equ LOAD2 =5 ;Load 2 output (active low)
.equ PZ =6 ;Piezo sounder output (active low)
.include "1200def.inc"
;***** Registers used by timer overflow interrupt service routine
.def timer =r31 ;scratch space for timer loading
.def status =r0 ;low register to preserve status register
;*****Look up table for LED display decoding **********************
.eseg ;EEPROM segment
.org 0
table1: .db 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
;digit 0 1 2 3 4 5 6 7 8 9
.db 0x86,0x8E,0xA3,0xAB,0XFF,0XFF
;digit E f o n BLANK special characters
;****Look up table for key value conversion into useful numbers****
;key 1 2 3 F 4 5 6 E 7 8 9 D A 0 B C
table2: .db 1, 2, 3,15, 4, 5, 6,14, 7, 8, 9, 13, 10, 0, 11, 12
;value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
;****Source code***************************************************
.cseg ;CODE segment
.org 0
rjmp reset ;Reset handler
nop ;unused ext. interrupt
rjmp tick ;timer counter overflow (5 ms)
nop ;unused analogue interrupt
;*** Reset handler **************************************************
;*** to provide initial port, timer and interrupt setting up
reset:
ser temp ;
out DDRB,temp ;initialize port B as all Outputs
out DDRD,temp ;initialize port D as all Outputs
out PORTB,temp ;key columns all high/LEDs off
out PORTD,temp ;turn off LEDs and loads off
ldi temp,0x04 ;timer prescalar /256
out TCCR0,temp
ldi timer,176 ;load timer for 5 ms
out TCNT0,timer ;(256 - n)*256*0.2441 us
ldi temp,0x02 ;enable timer interrupts
out TIMSK,temp
clr flags ;clear control flags
clr tock ;clear 5 ms tick
clr bounce ;clear key bounce counter
clr flash
clr blink
sei ;enable global interrupts
;****Flash EEEE on LEDS as test and power down warning**************
;****repeats until SET key is pressed on keypad
timesetting: ldi hibyte,0xaa ;show "EEEE" on LED
ldi lobyte,0xaa ;display and
ser mask ;set flashing display
notyet: rcall display ;display until time set
brtc notyet ;repeat until SET key pressed
rcall setrtc ;and reset time
mov hour,hiset ;and reload hours
mov minute,loset ;and minutes
clt ;clear T flag
;*****Main clock house keeping loop*****************************
do:
clr mask ;do housekeeping
cpi blink,100 ;is half second up
brne nohalf
clr blink
com flash ;invert flash
nohalf:
cpi second,60 ;is one minute up?
brne nochange ;no
clr second ;yes clear seconds and
inc minute ;add one to minutes
mov temp,minute
andi temp,0x0f ;mask high minute
cpi temp,10 ;is it ten minutes?
brne nochange ;no
andi minute,0xf0 ;clear low minutes
ldi temp,0x10
add minute,temp ;increment high minutes
cpi minute,0x60 ;is it 60 minutes?
brne nochange ;no
clr minute ;yes, clear minutes and
inc hour ;add one to hours
mov temp,hour
andi temp,0x0f ;mask high hour
cpi temp,10 ;is 10 hours up?
brne nochange ;no
andi hour,0xf0 ;yes, increment
ldi temp,0x10
add hour,temp ;high hours
nochange:
cpi hour,0x24 ;is it 24 hours?
brne sameday ;no,
clr hour ;yes, clear time variables
clr minute ;to start new day
clr second
sameday: ;update times
mov lobyte,minute
mov hibyte,hour
rcall display ;show time for 20 ms
brtc case1 ;if not SET
rcall setrtc ;and reset time
mov hour,hiset ;and reload hours
mov minute,loset ;and minutes
clt ;else, clear T flag
case1: sbrc flags,ld1 ;is load 1 active?
rjmp chkload1 ;yes, check load 1
case2: sbrc flags,ld2 ;is load 2 active
rjmp chkload2 ;yes, check load 2
case3: sbrc flags,ld1on ;is load 1 on time reset
rjmp setld1on ;yes reset on time
case4: sbrc flags,ld1off ;is load 1 off time reset
rjmp setld1off ;yes reset off time
case5: sbrc flags,ld2on ;is load 2 on time reset
rjmp setld2on ;yes reset on time
case6: sbrc flags,ld2off ;is load 2 on time reset
rjmp setld2off ;yes reset on time
case7: rjmp do ;repeat housekeeping loop
;****case routines to service load times and key presses********
chkload1: cp hour,ld1hroff ;is load 1 off time reached?
brne onload1
cp minute,ld1minoff
brne onload1
sbi PORTD,LOAD1 ;yes, turn load 1 off
onload1:
cp hour,ld1hron ;is load 1 on time reached?
brne case2
cp minute,ld1minon
brne case2
cbi PORTD,LOAD1 ;yes,turn load 1 on
rjmp case2 ;repeat with load on
chkload2: cp hour,ld2hroff ;is load 2 off time reached?
brne onload2
cp minute,ld2minoff
brne onload2
sbi PORTD,LOAD2 ;yes, turn load 2 off
onload2:
cp hour,ld2hron ;is load 2 on time reached?
brne case3
cp minute,ld2minon
brne case3
cbi PORTD,LOAD2 ;yes,turn load 2 on
rjmp case3 ;repeat with load on
setld1on:
sbr flags,0x01 ;make load 1 active
rcall setrtc ;pickup new on time
mov ld1hron,hiset ;and store
mov ld1minon,loset
cbr flags,0x04 ;clear ld1on flag
rjmp case4
setld1off:
rcall setrtc ;pickup new off time
mov ld1hroff,hiset ;and store
mov ld1minoff,loset
cbr flags,0x08 ;clear ld1off flag
rjmp case5
setld2on:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -