Læsning af 4x4 keypad med AVR

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Danish to

Threaded View
Hejsa

Jeg sidder og roder med et projekt med en AVR controller. Til dette
anvender jeg CodeVision.
Heri er der et kodeeksempel til læsning af et 4x4 keypad, som så læser
den trykkede tast ud på et LCD-display. Jeg smider lige koden ind
herunder:

/*
  4x4 Keypad Demo

  CodeVisionAVR C Compiler
  (C) 2000-2002 HP InfoTech S.R.L.
  www.hpinfotech.ro

  Chip: AT90S8515
  Connect the keypad matrix as follows:
  
  [STK500 PORTD HEADER]   [KEYS]  R1
  1 PD0 -----0----1----2----3----~~~~~---o+5V
             |    |    |    |     R2   |
  2 PD1 -----4----5----6----7----~~~~~-
             |    |    |    |     R3   |
  3 PD2 -----8----9----10---11---~~~~~-
             |    |    |    |     R4   |
  4 PD3 -----12---13---14---15---~~~~~-
         D1  |    |    |    |
  5 PD4 -|<|-     |    |    |
         D2       |    |    |
  6 PD5 -|<|------     |    |
         D3            |    |
  7 PD6 -|<|-----------     |  R1..R410%k..47k
         D4                 |
  8 PD7 -|<|----------------   D1..D4=1N4148
  
  Use an 2x16 alphanumeric LCD connected
  to PORTC as follows:

  [LCD]   [STK500 PORTC HEADER]
   1 GND- 9  GND
   2 +5V- 10 VCC  
   3 VLC- LCD contrast control voltage 0..1V
   4 RS - 1  PC0
   5 RD - 2  PC1
   6 EN - 3  PC2
  11 D4 - 5  PC4
  12 D5 - 6  PC5
  13 D6 - 7  PC6
  14 D7 - 8  PC7
*/

#asm
    .equ __lcd_port=0x15
#endasm

#include <lcd.h>
#include <stdio.h>
#include <delay.h>
#include <90s8515.h>

// quartz crystal frequency [Hz]
#define F_XTAL 3686400L
// PIND0..3 will be row inputs
#define KEYIN PIND
// PORTD4..7 will be column outputs
#define KEYOUT PORTD
// used for TIMER0 count initialization
#define INIT_TIMER0 TCNT0=0x100L-F_XTAL/64L/500L
#define FIRST_COLUMN 0x80
#define LAST_COLUMN 0x10

typedef unsigned char byte;
// store here every key state as a bit,
// bit 0 will be KEY0, bit 1 KEY1,...
unsigned keys;
// LCD display buffer
char buf[33];

// TIMER 0 interrupt at every 2 ms
interrupt [TIM0_OVF] void timer0_int(void)
{
static byte key_pressed_counter20%;
static byte key_released_counter,column=FIRST_COLUMN;
static unsigned row_data,crt_key;
// reinitialize TIMER0
INIT_TIMER0;
row_data<<=4;
// get a group of 4 keys in in row_data
row_data|=~KEYIN&0xf;
column>>=1;
if (column==(LAST_COLUMN>>1))
   {
   column=FIRST_COLUMN;
   if (row_data==0) goto new_key;
   if (key_released_counter) --key_released_counter;
   else
      {
      if (--key_pressed_counter==9) crt_key=row_data;
      else
         {
         if (row_data!=crt_key)
            {
            new_key:
            key_pressed_counter10%;
            key_released_counter=0;
            goto end_key;
            };
         if (!key_pressed_counter)
            {
            keys=row_data;
            key_released_counter20%;
            };
         };
      };
   end_key:;
   row_data=0;
   };
// select next column, inputs will be with pull-up
KEYOUT=~column;
}

// test if a key was pressed
unsigned inkey(void)
{
unsigned k;
if (k=keys) keys=0;
return k;
}

void init_keypad(void)
{
DDRD=0xf0;
INIT_TIMER0;
TCCR0=3;
TIMSK=2;
#asm("sei")
}

main() {
unsigned k;
init_keypad();
lcd_init(24);
lcd_putsf("CVAVR Keypad");
// read keys and display key code
while (1)
      {
      lcd_gotoxy(0,1);
      if (k=inkey())
         {
         sprintf(buf,"Key code=%d",k);
         lcd_puts(buf);
         }
      else lcd_putsf("NO KEY        ");
      delay_ms(500);
      }
}


Koden fungere således, af der, sålænge man ikke trykker på nogen tast,
skrives: "NO KEY" i displayet. Taster man i stedet på en vilkårlig
tast, skrives der: "Key code= ", og så den trykkede tast ca 1 sek,
hvorefter der atter skrives: "NO KEY". Dette er også, hvad jeg gerne
vil. Problemet er dog, at den pågældende tast skrives som 2^n, hvor
'n' så er den pågældende tast, så tast 1, skrives som '1', 2 som '2',
men 3 som '4', 4 som '8' osv. op til 16, der så skrives som 32768
(2^15). Jeg kan dog ikke lige se i koden, hvorfor dette sker, så jeg
håber, der er en herinde, som måske kan gennemskue koden og rette mig,
så tast 16 faktisk skriver '16' i displayet.

Håber nogen kan hjælpe mig.

På forhånd tak

Tomas


Re: Læsning af 4x4 keypad med AVR

Quoted text here. Click to load it

Hej

Jeg har ikke sat mig yderligere ind i koden, men jeg syntes ikke den er ret
overskuelig skrevet :(

Du kan evt. lave noget udregning der regner det om..

Jeg har lige vedhæftet noget andet kode, der måske kunne være interassant
for dig.
http://www.atmel-grenoble.com/dyn/resources/prod_documents/doc8013.pdf

http://www.atmel-grenoble.com/dyn/resources/prod_documents/AVR245.zip

Held og lykke med det
Kasper



Re: Læsning af 4x4 keypad med AVR
Quoted text here. Click to load it

Det kan jeg også kun give dig ret i, men den virker dog - blot
ikke helt med det output, jeg ønsker.

Quoted text here. Click to load it

Jeg har kigget lidt på et par af c-filerne, men de virker mig
desværre også lidt uoverskuelige :-(
Jeg synes dog dokumentationen er rigtig god. Er blot lidt i
tidspres, derfor ville jeg gerne anvende den funktion, som jeg
viste tal at scanne mit keyboard, da det er en ret essentiel
komponent i mit program.

--
Mvh.

Tomas


Site Timeline