AVR Assembler Source Blog

Ремонт частотных преобразователей AVR Assembler Source Blog: Keypad_4x4_wakeup_AVR240_appnote

Tuesday, October 8, 2013

Keypad_4x4_wakeup_AVR240_appnote

ремонт платы управления частотного преобразователя
                              ;**** A P P L I C A T I O N   N O T E   A V R 2 4 0 ************************
                              ;* 
                              ;* Title:  4x4 keypad, wake-up on keypress
                              ;* Version:  1.1
                              ;* Last Updated: 98.10.22
                              ;* Target:  All AVR Devices 
                              ;*
                              ;* Support E-mail: avr@atmel.com
                              ;*
                              ;* DESCRIPTION
                              ;* This Application note scans a 4 x 4 keypad and uses sleep mode
                              ;* causing the AVR to wake up on keypress.  The design uses a minimum of
                              ;* external components. Included is a test program that wakes up the AVR
                              ;* and performs a scan when a key is pressed and flashes one of two LEDs 
                              ;* the number of the key pressed.  The external interrupt line is used for
                              ;* wake-up.  The example runs on the AT90S1200 but can be any AVR with suitable
                              ;* changes in vectors, EEPROM and stack pointer. The timing assumes a 4 MHz clock.
                              ;* A look up table is used in EEPROM to enable the same structure to be used
                              ;* with more advanced programs e.g ASCII output to displays.
                              ;***************************************************************************

                              ;***** Register used by all programs
                              ;******Global variable used by all routines

.def temp=r16                 ;general scratch space

                              ;Port B pins

.equ ROW1=3                   ;keypad input rows
.equ ROW2=2
.equ ROW3=1
.equ ROW4=0
.equ COL1=7                   ;keypad output columns
.equ COL2=6
.equ COL3=5 
.equ COL4=4 

                              ;Port D pins

.equ GREEN=0                  ;green LED
.equ RED=1                    ;red LED
.equ INT=2                    ;interrupt input

.include "1200def.inc"

                              ;***** Registers used by interrupt service routine


.def key=r17                  ;key pointer for EEPROM
.def status=r21               ;preserve sreg here

                              ;***** Registers used by delay subroutine
                              ;***** as local variables

.def fine=r18 ;loop delay counters
.def medium=r19 
.def coarse=r20

                              ;*****Look up table for key conversion******************************
.eseg                         ;EEPROM segment
.org 0

.db 1,2,3,15,4,5,6,14,7,8,9,13,10,0,11,12
                              ;****Source code***************************************************
.cseg                         ;CODE segment
.org 0
       rjmp reset             ;Reset handler
       rjmp scan              ;interrupt service routine 
       reti                   ;unused timer interrupt
       reti                   ;unused analogue interrupt

                              ;*** Reset handler **************************************************
reset:   
       ldi temp,0xFB          ;initialise port D as O/I
       out DDRD,temp          ;all OUT except PD2 ext.int.
       ldi temp,0x30          ;turn on sleep mode and power
       out MCUCR,temp         ;down plus interrupt on low level.
       ldi temp,0x40          ;enable external interrupts
       out GIMSK,temp
       sbi ACSR,ACD           ;shut down comparator to save power

main:  
       cli                    ;disable global interrupts 
       ldi temp,0xF0          ;initialise port B as I/O
       out DDRB,temp          ; 4 OUT  4 IN
       ldi temp,0x0F          ;key columns all low and
       out PORTB,temp         ;active pull ups on rows enabled
       ldi temp,0x07          ;enable pull up on PD2 and
       out PORTD,temp         ;turn off LEDs
       sei                    ;enable global interrupts ready
       sleep                  ;fall asleep
       rcall flash            ;flash LEDs for example usage
       ldi temp,0x40
       out GIMSK,temp         ;enable external interrupt
       rjmp main              ;go back to sleep after keyscan

                              ;****Interrupt service routine***************************************
scan:  
       in status,SREG         ;preserve status register
       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,0x0F          ;change port B I/O to
       out DDRB,temp          ;find column press
       ldi temp,0xF0          ;enable pull ups and
       out PORTB,temp         ;write 0s to rows
       rcall settle           ;allow time for port to settle
       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
       ldi temp,0xF0          ;reinitialise port B as I/O
       out DDRB,temp          ; 4 OUT  4 IN
       ldi temp,0x0F          ;key columns all low and
       out PORTB,temp         ;active pull ups on rows enabled
       out SREG,status        ;restore status register

       ldi temp,0x00
       out GIMSK,temp         ;disable external interrupt
                              ;have to do this, because we're
                              ;using a level-triggered interrupt

       reti                   ;go back to main for example program

                              ;***Example test program to flash LEDs using key press data************

flash:  
       out EEAR,key           ;address EEPROM
       sbi EECR,EERE          ;strobe EEPROM
       in temp,EEDR           ;set number of flashes
       tst temp               ;is it zero?
       breq zero              ;do RED LED

green_flash:
       cbi PORTD,GREEN        ;flash green LED 'temp' times
       rcall delay
       sbi PORTD,GREEN
       rcall delay
       dec temp
       brne green_flash

exit:
       ret
zero:  
       ldi temp,10

flash_again:  
       cbi PORTD,RED          ;flash red LED ten times
       rcall delay
       sbi PORTD,RED
       rcall delay
       dec temp
       brne flash_again
       rjmp exit

  
                              ;****Time Delay Subroutine for LED flash*********************************
delay:
       ldi coarse,8           ;triple nested FOR loop

cagain:  
       ldi medium,255         ;giving about 1/2 second

magain:   
       ldi fine,255           ;delay on 4 MHz clock

fagain:   
       dec fine
       brne fagain
       dec medium
       brne magain
       dec coarse
       brne cagain
       ret

                              ;***Settling time delay for port to stabilise****************************** 
settle:
       ldi temp,255

tagain:  
       dec temp
       brne tagain
       ret

No comments:

Post a Comment