Please help with keypad entry 4x3 matrix(IN ASM)

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
Just needed some help with my code,
Im using ATMEGA8515 and a FM629 Board.

I need to enter a number on the keypad and output on the LED,
I got the LEDs and that down packed, i just need help, as my code seem to be only reading in the first Row, even if I enter any number from the second/third ROW

; 
; Lab5-a assembler program 
; 
.include "m8515def.inc" 

.def temp = r16
.def num = r17

; set 7-segment display labels 
.equ ZERO  = 0b00111111 
.equ ONE   = 0b00000110 
.equ TWO   = 0b01011011       
.equ THREE = 0b01001111
.equ FOUR  = 0b01100110
.equ FIVE  = 0b01101101
.equ SIX   = 0b01111101
.equ SEVEN = 0b00000111
.equ EIGHT = 0b01111111
.equ NINE  = 0b01101111
.equ STAR  = 0b01110110
.equ HASH  = 0b01001001
RESET: 
     ; *** set up Direction Registers *** 
ldi temp, 0b01110000
out DDRB, temp
ldi temp, 0b00001111
out PORTB, temp



LOOP:
	in temp,PINB
    ldi temp,0b00001111 ; PB4..PB6=Null, pull-Up-resistors to input lines
	out PORTB,temp    ; of port pins PB0..PB3
	nop  ; one nop delay inherent in AVR circuitry  
    nop  ; second nop delay to ensure correct values
	in temp,PINB     ; read key results
	ori temp,0b11110000 ; mask all upper bits with a one
	cpi temp,0b11111111 ; all bits = One?
	brne KEY         ; yes, no key is pressed
rjmp LOOP




KEY:
; checking  Column 1, Row 1-4 through PORTB  
ldi temp, 0b10111111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 

cpi temp, 0b00000111   ; compare with ....0111 (Row1=0) 
brne ROWA2         ; branch if not equal, to Next ROW  
ldi temp, ONE
out PORTA, temp
rjmp LOOP

ROWA2:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWA3
ldi temp, FOUR
out PORTA, temp
rjmp LOOP
ROWA3:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWA4
ldi temp, SEVEN
out PORTA, temp 
rjmp LOOP
ROWA4:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne COL2
ldi temp, STAR
out PORTA, temp
rjmp LOOP

COL2:

ldi temp, 0b11011111   ; set a mask with only column2 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00000111   ; compare with ....0111 (Row1=0) 
brne ROWB2         ; branch if not equal, to Next ROW  
ldi temp, TWO
out PORTA, temp
rjmp LOOP

ROWB2:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWB3
ldi temp, FIVE
out PORTA, temp
rjmp LOOP
ROWB3:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWB4
ldi temp, EIGHT
out PORTA, temp
rjmp LOOP
ROWB4:
in temp, PINB          ; now we can check "˜temp' for which row = 0 

andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne COL3
ldi temp, ZERO
out PORTA, temp
rjmp LOOP	  
COL3:
ldi temp, 0b11101111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00000111   ; compare with ....0111 (Row1=0) 
brne ROWC2         ; branch if not equal, to Next ROW  
ldi temp, THREE
out PORTA, temp
rjmp LOOP
ROWC2:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWC3
ldi temp, SIX
out PORTA, temp
rjmp LOOP
ROWC3:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWC4
ldi temp, NINE
out PORTA, temp
rjmp LOOP
ROWC4:
in temp, PINB          ; now we can check "˜temp' for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne NoKey
ldi temp, HASH
out PORTA, temp
	  
	  
	  
	  
	  
	  
	  
	  NoKey:
;	  *** Output value to LEDs ***
	  rjmp LOOP 

How do i modify this so the values are read in correct?

ps.
The column bits are used as outputs and Row bits as inputs.

Last Edited: Tue. May 1, 2012 - 01:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you looked up:
AVR242: 8-bit Microcontroller Multiplexing LED Drive and a 4 x 4 Keypad

or

AVR240: 4 x 4 Keypad - Wake-up on Keypress

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
.equ ZERO  = 0b00111111
.equ ONE   = 0b00000110
.equ TWO   = 0b01011011       
.equ THREE = 0b01001111
.equ FOUR  = 0b01100110
.equ FIVE  = 0b01101101
.equ SIX   = 0b01111101
.equ SEVEN = 0b00000111
.equ EIGHT = 0b01111111
.equ NINE  = 0b01101111
.equ STAR  = 0b01110110
.equ HASH  = 0b01001001 

When you see something like this you cannot help thinking it's crying out "make an array".

Put those values into flash as .db's then LPM them. That way you can easily index the data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That part is part of the specifications, we are told to just define it like that, I dont think the lenght of the code matters at this point, just the functionality.

Here is an updated code, but the Columns still dont want to get done.

; 
; Lab5-a assembler program 
; 
.include "m8515def.inc" 

.def temp = r16
.def num = r17

; set 7-segment display labels 
.equ ZERO  = 0b00111111 
.equ ONE   = 0b00000110 
.equ TWO   = 0b01011011       
.equ THREE = 0b01001111
.equ FOUR  = 0b01100110
.equ FIVE  = 0b01101101
.equ SIX   = 0b01111101
.equ SEVEN = 0b00000111
.equ EIGHT = 0b01111111
.equ NINE  = 0b01101111
.equ STAR  = 0b01110110
.equ HASH  = 0b01001001
RESET: 
     ; *** set up Direction Registers *** 
ldi temp, 0b01110000
out DDRB, temp
ldi temp, 0b00001111
out PORTB, temp



LOOP:
	in temp,PINB
    ldi temp,0b00001111 ; PB4..PB6=Null, pull-Up-resistors to input lines
	out PORTB,temp    ; of port pins PB0..PB3
	nop  ; one nop delay inherent in AVR circuitry  
    nop  ; second nop delay to ensure correct values
	in temp,PINB     ; read key results
	ori temp,0b11110000 ; mask all upper bits with a one
	cpi temp,0b11111111 ; all bits = One?
	brne KEY         ; yes, no key is pressed
rjmp LOOP




KEY:
; checking  Column 1, Row 1-4 through PORTB  
ldi temp, 0b00111111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 
cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWA1         ; branch if not equal, to Next ROW  
breq COL2

ROWA1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWA2
ldi temp, ONE
out PORTA, temp
rjmp LOOP

ROWA2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWA3
ldi temp, FOUR
out PORTA, temp
rjmp LOOP
ROWA3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWA4
ldi temp, SEVEN
out PORTA, temp 
rjmp LOOP
ROWA4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne LOOP
ldi temp, STAR
out PORTA, temp
rjmp LOOP

COL2:

ldi temp, 0b11011111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 

cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWB1         ; branch if not equal, to Next ROW  
breq COL3

ROWB1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWB2
ldi temp, TWO
out PORTA, temp
rjmp LOOP

ROWB2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWB3
ldi temp, FIVE
out PORTA, temp
rjmp LOOP
ROWB3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWB4
ldi temp, EIGHT
out PORTA, temp
rjmp LOOP
ROWB4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 

andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne END
ldi temp, ZERO
out PORTA, temp
rjmp LOOP	  

END:
rjmp LOOP

COL3:
ldi temp, 0b11101111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 
cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWC1         ; branch if not equal, to Next ROW  
breq END1

END1:
rjmp LOOP

ROWC1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWC2  
ldi temp, THREE
out PORTA, temp
rjmp LOOP
ROWC2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWC3
ldi temp, SIX
out PORTA, temp
rjmp LOOP
ROWC3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWC4
ldi temp, NINE
out PORTA, temp
rjmp LOOP
ROWC4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne END2
ldi temp, HASH
out PORTA, temp

END2:	  
rjmp LOOP 

I get that this keypad is a ginat set of switches and when a number is pressed that column is electrically connected to the row.
If no key is pressed, the row lines are at plus. Any pressed key pulls down the row lines to zero volts.

To detect, which one of the 12 keys is pressed, I need to pull down the three column lines one by one to 0V (the other two column lines to plus) and read the resulting four row-lines.

I thought thats what I am doing here, but obviously im wrong somewere, unless im not entering the test numbers correctly onto Pinb, its hard without the actual equipment and only AVR studio =(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I dont think the lenght of the code matters at this point, just the functionality.

Eh? What kind of way is that to learn programming? Oh well modern teachers apparently claim to know what they are doing so I guess it must be right.

As for row an column scanning it's pretty much the same in any language especially on AVRS where the built in pull-ups make open lines reading 1 the natural choice. You drive a 0 bit across the output lines one at a time (some kind of shift such as LSL or LSR will come into play here). Then after you've set each output you read the inputs in turn for any that show signs of non-zero (that is the masked part of the input is not all 1's). Knowing the current output (low) bit and the current input (low) bit then lets you index (usually) a table to tell you what the represented character is.

It's usually best to sketch this out in a few sentences of English or, dare I say it, even a flow diagram then actually coding that is trivial.

In the old days the job of programming was split between system analysts and programmers. The system analysts were the ones paid the big bucks and well respected who analysed the problem down to implementable blocks then the programmers were little more than typists who then coded from their specification. It was actually a system that worked well. These days we're all called programmers and we must do both jobs. But it's the thinking bit up front, not the coding (then debugging) out the back end that pays the mortgage.

Last Edited: Mon. Apr 30, 2012 - 06:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
To detect, which one of the 12 keys is pressed, I need to pull down the three column lines one by one to 0V (the other two column lines to plus) and read the resulting four row-lines.

I pull the three column lines one by one to VCC("plus"), while holding the other two lines low (0V or GND).

I don't understand how you can detect the keypress with your method.

Further you say "just avr studio" does that mean you don't have the matrix keypad and an AVR on hand?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You might want to examine a couple of Atmel
app notes: AVR240 and AVR242, are app notes
that give you a couple of ideas to study.

I'll believe corporations
are people when Texas executes one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You might want to examine a couple of Atmel
app notes: AVR240 and AVR242
WOW I wish I had thought of that .... :wink:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
WOW I wish I had thought of that .... Wink

:oops: I didn't grasp the app note post in your post John.
Maybe the OP will think if more than one
made the suggestion it might help. :D

It was on my mind when I read through the thread . Some years ago I coded the app note using 'C' but used a timer interrupt to
check the keypad inputs and did not have to
use the extra gate to trigger the external
interrupt used in the app note.
Worked great :)

I'll believe corporations
are people when Texas executes one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can someone add [in asm] to the title so us non avr asm dudes dont have to wade thru it? Thanx. Isn't asm almost over yet?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Isn't asm almost over yet?
It will NEVER die just like 8 bits micros. :wink:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well I found this AVR tutorial,
http://www.avr-asm-tutorial.net/...

And I based my code on it.

; 
; Lab5-a assembler program 
; 
.include "m8515def.inc" 

.def temp = r16
.def num = r17

; set 7-segment display labels 
.equ ZERO  = 0b00111111 
.equ ONE   = 0b00000110 
.equ TWO   = 0b01011011       
.equ THREE = 0b01001111
.equ FOUR  = 0b01100110
.equ FIVE  = 0b01101101
.equ SIX   = 0b01111101
.equ SEVEN = 0b00000111
.equ EIGHT = 0b01111111
.equ NINE  = 0b01101111
.equ STAR  = 0b01110110
.equ HASH  = 0b01001001
RESET: 
     ; *** set up Direction Registers *** 
ldi temp, 0b01110000
out DDRB, temp
ldi temp, 0b00001111
out PORTB, temp



LOOP:
	in temp,PINB
    ldi temp,0b00001111 ; PB4..PB6=Null, pull-Up-resistors to input lines
	out PORTB,temp    ; of port pins PB0..PB3
	nop  ; one nop delay inherent in AVR circuitry  
    nop  ; second nop delay to ensure correct values
	in temp,PINB     ; read key results
	ori temp,0b11110000 ; mask all upper bits with a one
	cpi temp,0b11111111 ; all bits = One?
	brne KEY         ; yes, no key is pressed
rjmp LOOP




KEY:
; checking  Column 1, Row 1-4 through PORTB  
ldi temp, 0b00111111   ; PB6 = 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 
cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWA1         ; branch if not equal, to Next ROW  
breq COL2

ROWA1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWA2
ldi temp, ONE
out PORTA, temp
rjmp LOOP

ROWA2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWA3
ldi temp, FOUR
out PORTA, temp
rjmp LOOP
ROWA3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWA4
ldi temp, SEVEN
out PORTA, temp 
rjmp LOOP
ROWA4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne LOOP
ldi temp, STAR
out PORTA, temp
rjmp LOOP

COL2:

ldi temp, 0b01011111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 

cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWB1         ; branch if not equal, to Next ROW  
breq COL3

ROWB1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWB2
ldi temp, TWO
out PORTA, temp
rjmp LOOP

ROWB2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWB3
ldi temp, FIVE
out PORTA, temp
rjmp LOOP
ROWB3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWB4
ldi temp, EIGHT
out PORTA, temp
rjmp LOOP
ROWB4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 

andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne END
ldi temp, ZERO
out PORTA, temp
rjmp LOOP	  

END:
rjmp LOOP

COL3:
ldi temp, 0b01101111   ; set a mask with only column1 to 0  
out PORTB, temp        ; output to PortB  
nop  ; one nop delay inherent in AVR circuitry  
nop  ; second nop delay to ensure correct values  
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
ori temp, 0b11110000  ; just righthand nibble 
cpi temp, 0b11111111   ; compare with ....0111 (Row1=0) 

brne ROWC1         ; branch if not equal, to Next ROW  
breq END1

END1:
rjmp LOOP

ROWC1:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWC2  
ldi temp, THREE
out PORTA, temp
rjmp LOOP
ROWC2:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001011   ; compare with ....0111 (Row1=0) 
brne ROWC3
ldi temp, SIX
out PORTA, temp
rjmp LOOP
ROWC3:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001101   ; compare with ....0111 (Row1=0) 
brne ROWC4
ldi temp, NINE
out PORTA, temp
rjmp LOOP
ROWC4:
in temp, PINB          ; now we can check ‘temp’ for which row = 0 
andi temp, 0b00001111  ; just righthand nibble 
cpi temp, 0b00001110   ; compare with ....0111 (Row1=0) 
brne END2
ldi temp, HASH
out PORTA, temp

END2:	  
rjmp LOOP 

What do I enter in AVR studio to test it correctly? Because my tests thus far are not making the program work, and checking it, the masking makes sense.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
LOOP:
   in temp,PINB
    ldi temp,0b00001111 ; PB4..PB6=Null, pull-Up-resistors to input lines

The first instruction is pointless since the second wipes out the value in temp.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
Isn't asm almost over yet?

But what would you write your precious C compiler with??? 8)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But what would you write your precious C compiler with???

Umm C?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The downside of setting the port bits high and low is if yo get multiple keys pressed at one, this may short your column (or row) output bits together. Thr method I emply is to twiddle the DDR bits to either enable or diasble the output bits with the bits written to 0 in the PORT register. Basically this becomes open collector and shorting the lines has no negative effect (apart from ghost keys).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But what would you write your precious C compiler with???
The important question is "how would you know how to write your precious C compiler without a knowledge of assembly language?".

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I might mention that at the level that the keypad code is at it might be easier to implement a real keyboard. The old purple connector PS2 keyboards are straightforward to interface to an AVR. The newer USB keyboards are much more difficult.
A PS2 keyboard interface has three parts. First is an interrupt routine in INT0 to get the byte value from the serial bit data coming from the keyboard. Second is a convertor from scancodes to keypress data. The third part is the main code that uses the ASCII keypress sent to it.
I have uploaded code for a PS2 keyboard to the projects section here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its ok, my code is correct, besides the wrong masking of finding Row 1, i didnt realise, that i do now, is that the keyboard when held is constantly loading a value into PINB in real life, In AVR studio the PIN B gets constantly masked by anything in PORTB and DDR, so to account for that, the PINB has to be retoggled when the PINB is loaded for the column check, to emulate the "holding down" of the key

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The OP might want to look at the IC
74C922 device. It takes two external caps, one for bounce and the other to control the scan time.
The data sheet should be able to be located , use a Internet source.

As I recall, it had several methods to
communicate the 4 bit pressed key value
(output in hex) and could also generate
a signal that could be used by the AVR
as a interrupt source.

Of course this does add another device to the project , but the AVR code for multiplexing , scan times and decoding the individual key press is eliminated.
The output of the chip is a 4 bit value
which contains the hex value of the key press.

Some years back, I used this device and I recall that it worked without any issues.

Just another thought/suggestion.

I would also be interested in anyone else who has used this device in the past.

I'll believe corporations
are people when Texas executes one.