Searching \ for 'matrix keyboards' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=matrix+keyboards
Search entire site for: 'matrix keyboards'.

Truncated match.
PICList Thread
'matrix keyboards'
1998\03\11@171544 by myke predko

flavicon
face
Hi Ed,

I've copied my reply to the PICList simply because I think there are some
points here that would be relavent to other people.

>I recently purchased your book and I think you did an great job.
>You covered the PIC material well, gave insight on how to use developing
>tools.  You didn't miss a thing.  I only wish I would have found your
>book before I bought both PIC'n books.

I'm glad you enjoyed the book and found it complete.

{Quote hidden}

When you say "Motorola", I am presuming you are talking about a Motorola
68HCxx device, which is truly Von Neumann and is what is often taught in the
schools for introductory assembler programming.  There are a lot of
excellent texts on this and I find that most instructors are very familiar
with how they are programmed.

The PIC is a completely different beast all together because it is "Harvard"
Architecture.  A very efficient program in the PIC can be just about
impossible to understand what is happening.  The PIC is more of an industry
standard archtitecture (as opposed to achedemia) and there are fewer
resources and trained instructors - which is a pity because there are some
real advantages to the Harvard Architecture for small devices like
microcontrollers.

When I read your paragraph above, I think we did things pretty similarly,
but there are a few differences.  The biggest difference is, I used a full
keyboard and not a 4x4 keypad.  This will cause huge differences in the code
(as I will show below).  As well, in my code, I support multiple keys
pressed at the same time.

I outlined the algorithm I used in PROG40 in figure 9-25, but I guess I
should have been clearer on what happens when I scan the column.  If I find
a row that doesn't have all high bits, I set the "KeyPreviously" to the
Column.

Lastly, the PIC and the 68HCxx devices are radically different devices, as I
said above and this drastically affects how the code works.


To bring the PIC and 68HCxx into line, here is an example of how I could
read a 4x4 keypad with a PIC.  I would use an 8 bit port for the interface,
which had pull ups on the most significant four lines (which were set to
output) and the tristatable Bits on the least significant four lines set to
input (which read the columns for the selected row).  In the PIC, I could
accomplish this with the code below (assuming that "KeyColumn" was defined
as the port (PORTB in this example), "Save" and "Count" were defined as bytes):

KeyLoop:                                ;  Come Back Here when Key Reset

 movlw  0x0FF                          ;  Reset the KeyColumn
 movwf  PORTB

Loop                                    ;  Loop Here Continuously

;  #### - Put in Delay Here

 incf   PORTB, w                       ;  Is KeyColumn == 0x0FF == -1
 btfss  STATUS, Z
  goto  CheckScan                      ;  It's not, Check for the Next Byte

 bcf    PORTB, 4                       ;  PORTB = 0x0EF to Start the Scan

ScanLoop                                ;  Loop Here

 movlw  1                              ;  See if the Lower 4 Bits are Still Set
 addwf  PORTB, w                       ;  If they Are, the DC Flag will be Set
 btfsc  STATUS, DC                     ;  Do we Have all 4 Bits Set
  goto  NoScan                         ;   Yes, Loop Around Again

 movf   PORTB, w                       ;  Save the Value for Checking
 movwf  Save

 clrf   Count                          ;  Reset the Count Value

 goto   Loop                           ;  Now, Keep Polling

NoScan                                  ;  Nothing, Loop Around Again?

 btfss  PORTB, 7                       ;  Is the High Bit Reset?
  goto  KeyLoop                        ;   Yes, Skip Over

 bsf    STATUS, C                      ;  Set the Carry Flag
 rlf    PORTB                          ;  Shift Through PORTB

 goto   ScanLoop


CheckScan                               ;  Check to See if the Scan is the Same

 movf   Save, w                        ;  Still have the Same Value in "Save"?
 xorwf  PORTB, w
 btfss  STATUS, Z                      ;  If Zero Set, then the Same
  goto  KeyLoop                        ;   Not the Same, Start Polling Over

 incf   Count                          ;  Have we Loop 4x yet?
 btfss  Count, 2
  goto  Loop                           ;  Nope

;  #### - Convert the Value in PORTB to a 4 bit number for the Keystroke

 goto   KeyLoop

This code takes up 27 instructions to read a 4x4 matrix keyboard on PORTB.
"Dlay" should be 5-7 msecs and the conversion routine can be a table
although I would probably figure out the value arithmetically.

Could you compare your 68HCxx example after taking out the delay routine and
the character conversion routines.  I'll bet the PIC code is a lot shorter.
You gave the measurement of 60 lines of code, I would be interested in the
number of instructions.  Comparing this snippet to your code is much more
appropriate than comparing PROG40 to your code.


Now, this might seem like a bit of an artificial example designed to make
the PIC look better, but I would argue that you should be designing your
application around making the code and wiring as simple as possible.  This
code takes advantage of a number of features of the PIC that are not
necessarily available in the 68HCxx (although many of them are).  By the
same token, you could design your hardware to be more in line with the
68HCxx architecture for the compare.

Note that I use PORTB as the "KeyCount" variable and when I shift or use it,
I simply access it like a register variable.  I also assume that PORTB can
be pulled up.

I used the least significant four bits of PORTB as the column read because I
know that adding 1 to them would set the Digit Carry Flag if they are still
high (ie no button pressed).

You should also note that I use "Count" as a variable, but only check bit 2,
which indicates that "Count" is equal to four (after the increment).


I'm not sure if I've answered your question or not or confused you even more.

I guess your question about the validity of using your algorithm for the PIC
is answerable with a "Yes".  My code above works slightly differently
because I take advantage of using a single port for the Drivers and
Receivers and using it to keep track of the current scan code.


Rather than worrying about what you understand and don't understand about
the PIC compared to what you know with other architectures, try to
understand the architecture and what can be done with it.  This is why I
tried building up the architecture in the book, so that you can get an idea
of how the PIC works and then writing applications from this understanding.
Don't look at it from the perspective of the Motorola architecture and try
to translate what is done in the 68HCxx and apply it to PIC code, instead,
look at it from the high level and then try to figure out how to do
something in the PIC.

I realize that this is pretty Zen, but it really is the best way to learn
the PIC (and actually any processor architecture) and be able to program in
it efficiently.


myke

"If people don't know what you're doing, they don't know what you're doing
wrong." - Sir Humphrey Appleby K.C.B

1998\03\11@171548 by myke predko

flavicon
face
Ooops.  I just realized that I should have pointed out that in the example
code, the pull ups should be on the LEAST Significant four bits, not the
most significant four as I indicated in the original note.

myke


Hi Ed,

I've copied my reply to the PICList simply because I think there are some
points here that would be relavent to other people.

>I recently purchased your book and I think you did an great job.
>You covered the PIC material well, gave insight on how to use developing
>tools.  You didn't miss a thing.  I only wish I would have found your
>book before I bought both PIC'n books.

I'm glad you enjoyed the book and found it complete.

{Quote hidden}

When you say "Motorola", I am presuming you are talking about a Motorola
68HCxx device, which is truly Von Neumann and is what is often taught in the
schools for introductory assembler programming.  There are a lot of
excellent texts on this and I find that most instructors are very familiar
with how they are programmed.

The PIC is a completely different beast all together because it is "Harvard"
Architecture.  A very efficient program in the PIC can be just about
impossible to understand what is happening.  The PIC is more of an industry
standard archtitecture (as opposed to achedemia) and there are fewer
resources and trained instructors - which is a pity because there are some
real advantages to the Harvard Architecture for small devices like
microcontrollers.

When I read your paragraph above, I think we did things pretty similarly,
but there are a few differences.  The biggest difference is, I used a full
keyboard and not a 4x4 keypad.  This will cause huge differences in the code
(as I will show below).  As well, in my code, I support multiple keys
pressed at the same time.

I outlined the algorithm I used in PROG40 in figure 9-25, but I guess I
should have been clearer on what happens when I scan the column.  If I find
a row that doesn't have all high bits, I set the "KeyPreviously" to the
Column.

Lastly, the PIC and the 68HCxx devices are radically different devices, as I
said above and this drastically affects how the code works.


To bring the PIC and 68HCxx into line, here is an example of how I could
read a 4x4 keypad with a PIC.  I would use an 8 bit port for the interface,
which had pull ups on the most significant four lines (which were set to
output) and the tristatable Bits on the least significant four lines set to
input (which read the columns for the selected row).  In the PIC, I could
accomplish this with the code below (assuming that "KeyColumn" was defined
as the port (PORTB in this example), "Save" and "Count" were defined as bytes):

KeyLoop:                                ;  Come Back Here when Key Reset

 movlw  0x0FF                          ;  Reset the KeyColumn
 movwf  PORTB

Loop                                    ;  Loop Here Continuously

;  #### - Put in Delay Here

 incf   PORTB, w                       ;  Is KeyColumn == 0x0FF == -1
 btfss  STATUS, Z
  goto  CheckScan                      ;  It's not, Check for the Next Byte

 bcf    PORTB, 4                       ;  PORTB = 0x0EF to Start the Scan

ScanLoop                                ;  Loop Here

 movlw  1                              ;  See if the Lower 4 Bits are Still Set
 addwf  PORTB, w                       ;  If they Are, the DC Flag will be Set
 btfsc  STATUS, DC                     ;  Do we Have all 4 Bits Set
  goto  NoScan                         ;   Yes, Loop Around Again

 movf   PORTB, w                       ;  Save the Value for Checking
 movwf  Save

 clrf   Count                          ;  Reset the Count Value

 goto   Loop                           ;  Now, Keep Polling

NoScan                                  ;  Nothing, Loop Around Again?

 btfss  PORTB, 7                       ;  Is the High Bit Reset?
  goto  KeyLoop                        ;   Yes, Skip Over

 bsf    STATUS, C                      ;  Set the Carry Flag
 rlf    PORTB                          ;  Shift Through PORTB

 goto   ScanLoop


CheckScan                               ;  Check to See if the Scan is the Same

 movf   Save, w                        ;  Still have the Same Value in "Save"?
 xorwf  PORTB, w
 btfss  STATUS, Z                      ;  If Zero Set, then the Same
  goto  KeyLoop                        ;   Not the Same, Start Polling Over

 incf   Count                          ;  Have we Loop 4x yet?
 btfss  Count, 2
  goto  Loop                           ;  Nope

;  #### - Convert the Value in PORTB to a 4 bit number for the Keystroke

 goto   KeyLoop

This code takes up 27 instructions to read a 4x4 matrix keyboard on PORTB.
"Dlay" should be 5-7 msecs and the conversion routine can be a table
although I would probably figure out the value arithmetically.

Could you compare your 68HCxx example after taking out the delay routine and
the character conversion routines.  I'll bet the PIC code is a lot shorter.
You gave the measurement of 60 lines of code, I would be interested in the
number of instructions.  Comparing this snippet to your code is much more
appropriate than comparing PROG40 to your code.


Now, this might seem like a bit of an artificial example designed to make
the PIC look better, but I would argue that you should be designing your
application around making the code and wiring as simple as possible.  This
code takes advantage of a number of features of the PIC that are not
necessarily available in the 68HCxx (although many of them are).  By the
same token, you could design your hardware to be more in line with the
68HCxx architecture for the compare.

Note that I use PORTB as the "KeyCount" variable and when I shift or use it,
I simply access it like a register variable.  I also assume that PORTB can
be pulled up.

I used the least significant four bits of PORTB as the column read because I
know that adding 1 to them would set the Digit Carry Flag if they are still
high (ie no button pressed).

You should also note that I use "Count" as a variable, but only check bit 2,
which indicates that "Count" is equal to four (after the increment).


I'm not sure if I've answered your question or not or confused you even more.

I guess your question about the validity of using your algorithm for the PIC
is answerable with a "Yes".  My code above works slightly differently
because I take advantage of using a single port for the Drivers and
Receivers and using it to keep track of the current scan code.


Rather than worrying about what you understand and don't understand about
the PIC compared to what you know with other architectures, try to
understand the architecture and what can be done with it.  This is why I
tried building up the architecture in the book, so that you can get an idea
of how the PIC works and then writing applications from this understanding.
Don't look at it from the perspective of the Motorola architecture and try
to translate what is done in the 68HCxx and apply it to PIC code, instead,
look at it from the high level and then try to figure out how to do
something in the PIC.

I realize that this is pretty Zen, but it really is the best way to learn
the PIC (and actually any processor architecture) and be able to program in
it efficiently.


myke

"If people don't know what you're doing, they don't know what you're doing
wrong." - Sir Humphrey Appleby K.C.B

More... (looser matching)
- Last day of these posts
- In 1998 , 1999 only
- Today
- New search...