Ok... Back on track.
The next tutorial we need to read a 4 x 3 ( 12 key ) keypad...
If we attach a keypad to port 0 and place some resistors as external pull up’s we can read can read the 12 possible on the keypad on only 7 pins... 4 pins as columns and 3 pins as rows.. Here is the connection I used... I have included a 7 segment LED as a simple visual response...
The pinout is shown above... We don't have enough power to sink the current so I used a line driver.. The 74C245 is a bidirectional buffer... We can output a small current on the micro and the buffer will allow more current to be used for the LED's, the maximum current is 24mA on each pin so with a 470 ohm current limiting resistor will still give a good visual output on the display..
Attach a common cathode display to our circuit like so..
The keypad will require pullup resistors ( I have used 1k ) on the row pins... The way I read a keypad is by making each column negative ( 0 volts ) in turn, then if a key is being pressed it will show on the 4 row pins 0~3..
Here is the code in ASM to read a keypad and display the same value on the display.
Code 7
This is getting near to pixel output... The patterns to create the digits 0 ~ C are stored similar to bitmaps... The code bitmaps are for common cathode displays.. If you use a common anode (as I have done ) then the complement “cpl A” command inverts the output...
The key pad read function is looped three times whilst keeping an eye on the four row inputs.
As the resistors keep the pins in a high state, the columns are pulsed low in turn, if the pin s 0 ~ 3 are low then a key press is detected and whilst we keep a track of the loop the count stored in A will give us the actual key pressed.
There are some low level things we can't do in C so we have little work rounds.. Take this command.
rlc A. We can't rotate left with carry, In C the shift left operator '<<' will clear the LSBit . ie.. 11101111 ( 0xEF) after the shift will become 11011110 ( 0xBE) so we have to remember in this
instance to add one to make the shift work as we want...
Here is the C version..
Code 8
Hopefully you can now start to see a difference in C when you are entering code..
C has 28 lines of code and ASM has 46... We can optimise the ASM. code to use mackro's and use symbols for better readability, but with C identifiers we can read it quite well without remarks.. I know we can do the same in ASM but the readability is still not as good as C.
The keypad function returns a key which can be used directly with the display function..
This is the second tutorial in this little series... I'll post the next as soon as I havea little more time...
The next tutorial we need to read a 4 x 3 ( 12 key ) keypad...
If we attach a keypad to port 0 and place some resistors as external pull up’s we can read can read the 12 possible on the keypad on only 7 pins... 4 pins as columns and 3 pins as rows.. Here is the connection I used... I have included a 7 segment LED as a simple visual response...
The pinout is shown above... We don't have enough power to sink the current so I used a line driver.. The 74C245 is a bidirectional buffer... We can output a small current on the micro and the buffer will allow more current to be used for the LED's, the maximum current is 24mA on each pin so with a 470 ohm current limiting resistor will still give a good visual output on the display..
Attach a common cathode display to our circuit like so..
The keypad will require pullup resistors ( I have used 1k ) on the row pins... The way I read a keypad is by making each column negative ( 0 volts ) in turn, then if a key is being pressed it will show on the 4 row pins 0~3..
Here is the code in ASM to read a keypad and display the same value on the display.
Code 7
Code:
org 0 ; Reset vector
sjmp Start
org 30H ; Code starts here
Start:
clr A ; A = 0
While:
acall keypad ; Fetch keypress ( mono...only one key at a time )
acall delay ; delay so we see it
acall Display ; Show on display
sjmp While ; do it again ( Forever loop )
keypad:
mov R1,#0EFH ; keymask
mov R2,#3 ; Three columns
mov A,#1
OLoop:
clr C
mov P0,R1 ; ready keypad mask
jb P0.0,row2 ; Key pressed? row 1
sjmp keydone ; found a key
row2:
jb P0.1,row3 ; Key pressed? row 2
add A,#1
sjmp keydone ; found a key
row3:
jb P0.2,row4 ; Key pressed? row 3
add A,#2
sjmp keydone ; found a key
row4:
jb P0.3,nextcol ; Key pressed? row 4
add A,#3
sjmp keydone ; found a key
nextcol:
add A,#4 ; add row count...0,4,8 + key press
push Acc ; save count
mov A,R1 ; get mask
setb C ; Rotate with
rlc A ; carry R1 mask
mov R1,A ; store new mask
pop Acc ; restore the count
djnz R2,OLoop ; Last column???
clr A ; No keys detected...
keydone: ; return with keypad condition
ret
Display:
mov DPTR,#digits ; Use A to get 7 segment pattern
movc A,@A+DPTR ;
;cpl A ; Common cathode... Uncomment for common anode.
mov P1,A ; put pattern on port 1
ret
delay: mov R2,#225 ; 2 clock cycles (call) = 2
mov R1,#0 ; 2 clock cycles (loading) = 2
d1:
djnz R1,d1 ; 2 * 256 clock cycles *225 = 115200
djnz R2,d1 ; 2 * 225 clock cycles = 450
ret ; 2 clock cycles (return) = 2
digits: db 03FH,006H,005BH,04FH,066H,06DH,07DH,007H,07FH,06FH,077H,07CH,039H ; 7 segment patterns 0 to C
end
This is getting near to pixel output... The patterns to create the digits 0 ~ C are stored similar to bitmaps... The code bitmaps are for common cathode displays.. If you use a common anode (as I have done ) then the complement “cpl A” command inverts the output...
The key pad read function is looped three times whilst keeping an eye on the four row inputs.
As the resistors keep the pins in a high state, the columns are pulsed low in turn, if the pin s 0 ~ 3 are low then a key press is detected and whilst we keep a track of the loop the count stored in A will give us the actual key pressed.
There are some low level things we can't do in C so we have little work rounds.. Take this command.
rlc A. We can't rotate left with carry, In C the shift left operator '<<' will clear the LSBit . ie.. 11101111 ( 0xEF) after the shift will become 11011110 ( 0xBE) so we have to remember in this
instance to add one to make the shift work as we want...
Here is the C version..
Code 8
C:
#include<8051.h> // definition file.
unsigned char digits[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D
,0x07,0x7F,0x6F,0x77,0x7C,0x39};
void delay(void) // How to get 125mS..
{
int x = 10500; // The while statement consumes 11.89uS (11 clock cycles )
while(x--); // So 10500 * 11.89uS = nearly 125mS.
}
char keypad(void)
{
unsigned char keymask = 0xEF;
char key = 0, x;
for(x=0;x<3;x++) // Three columns.
{
P0 = keymask; // check each
if(!P0_0) key = 1; // bit for
if(!P0_1) key = 2;
if(!P0_2) key = 3; // key detect.
if(!P0_3) key = 4;
if(key)
{ // If we see a key press we
key += (x*4); // need to add in the loop.
return key;
}
keymask<<=1; // We have no status control in C so we manually
keymask++; // shift a bit into the mask register..
} // or the LSBit will be an output !sizzle!..
return key;
}
void display(unsigned char dt)
{
P1 = ~digits[dt]; // Common anode uses '~' delete for common cathode.
}
void main(void) // Main entry point
{
while(1) // Forever loop
{
display(keypad()); // we can nest functions in C like this
delay(); // delay..
}
}
Hopefully you can now start to see a difference in C when you are entering code..
C has 28 lines of code and ASM has 46... We can optimise the ASM. code to use mackro's and use symbols for better readability, but with C identifiers we can read it quite well without remarks.. I know we can do the same in ASM but the readability is still not as good as C.
The keypad function returns a key which can be used directly with the display function..
This is the second tutorial in this little series... I'll post the next as soon as I havea little more time...