![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
Hey gang, I'm trying to interface a 4x4 keypad to a 16f877A and Im having some problems. I'm familar with the scanning routine and whatnot, I'm just having difficulty reading in the pins. I have pins B4-B7 connected as my outputs, and pins B0-B3 as my inputs, which have pullup resistors as well. I dont know how to read in just the lower half of port B, I have my code set up like this: Code: set_tris_b(0x0F); //upper half is output
output_bit( PIN_B7, 0);
output_bit( PIN_B6, 0);
output_bit( PIN_B5, 0);
output_bit( PIN_B4, 0);
while(1)
{
row=input_b();
printf("row %i\n\r",row);
delay_ms(1100);
}
__________________ Jeff To the optimist, the glass is half full. To the pessimist, the glass is half empty. To the engineer, the glass is twice as big as it needs to be. | |
| |
| | #2 |
|
You use AND to mask off the bits you don't need, in assembler the command would be 'ANDLW 0x0F' - I'm presuming your code is C?, as it has curly brackets.
| |
| |
| | #3 |
|
You either AND the lower half like Nigel suggested (with a binary value of 00001111) or read your compiler's documentation to find the ready-made function(s) to access individual bits. What compiler are you using?
__________________ Time is nature\'s way of keeping everything from happening at once. http://membres.lycos.fr/jrainville/ | |
| |
| | #4 | |
| Quote:
Something like this should work. (I'm guessing at the syntax.) Code: for (i = 0; i<=3; i++) {
output_b = ~(16<<i);
Row = input_b && 15;
printf("row %i\n\r",row);
}
The third line reads port b and discards the top bits. The value in Row is inverted - the bit is cleared if the key is pressed. HTH Mike. | ||
| |
| | #5 |
|
I tried anding the lower half, but it would cause the micro to freeze after printing 1 value. We're using the CCS-PIC compiler in my microcontrollers class. This is a 'side project' though. I'm going to have some freetime to work on it this afternoon. EDIT: I was able to play with it some more, it turns out that the compiler will read the entire port even if it is masked, I'm able to just read in each pin individually. here's the routine I came up with...(if anyone feels like making it alittle simpler, feel free...) Code: #include <16F877.h>
#use delay(clock=10000000) //External clock 10MHz
#fuses HS, NOWDT //High speed, no watchdog timer
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <stdio.h>
int read_columns();
void main()
{
int column;
set_tris_b(0x0F);
output_bit( PIN_B7, 0);
output_bit( PIN_B6, 0);
output_bit( PIN_B5, 0);
output_bit( PIN_B4, 0);
printf("test\n\r");
while(1)
{
column=read_columns();
output_bit( PIN_B7, 1);
if(column!=read_columns())
{
printf("row 1 col %i\n\r",column);
}
output_bit( PIN_B7, 0);
output_bit( PIN_B6, 1);
if(column!=read_columns())
{
printf("row 2 col %i\n\r",column);
}
output_bit( PIN_B6, 0);
output_bit( PIN_B5, 1);
if(column!=read_columns())
{
printf("row 3 col %i\n\r",column);
}
output_bit( PIN_B5, 0);
output_bit( PIN_B4, 1);
if(column!=read_columns())
{
printf("row 4 col %i\n\r",column);
}
output_bit( PIN_B4, 0);
delay_ms(500);
}
}
int read_columns()
{
int colcom=0;
if (input(PIN_B3)==0) //col1
colcom=1;
if (input(PIN_B2)==0) //col2
colcom=2;
if (input(PIN_B1)==0) //col3
colcom=3;
if (input(PIN_B0)==0) //col1
colcom=4;
// printf("colcom %i\n\r",colcom);
return colcom;
}
__________________ Jeff To the optimist, the glass is half full. To the pessimist, the glass is half empty. To the engineer, the glass is twice as big as it needs to be. | |
| |
| | #6 | |
| Quote:
| ||
| |
| | #7 |
|
You still have your bits the wrong way round. Because you have pullup resistors, you have to put a zero on the row that you wish to read and a one on all others. Your code should read:- Code: set_tris_b(0x0F);
output_bit( PIN_B7, 1);
output_bit( PIN_B6, 1);
output_bit( PIN_B5, 1);
output_bit( PIN_B4, 1);
printf("test\n\r");
while(1)
{
column=read_columns();
output_bit( PIN_B7, 0);
if(column!=read_columns())
{
printf("row 1 col %i\n\r",column);
}
output_bit( PIN_B7, 1);
output_bit( PIN_B6, 0);
if(column!=read_columns())
{
printf("row 2 col %i\n\r",column);
}
ETC
I.E. Code: void main()
{
set_tris_b(0x0F);
while(1)
{
output_b = 0x7f; // = 01111111 in binary
if(read_columns()!=0)
{
printf("row 1 col %i\n\r",column);
}
output_b = 0xbf; // = 10111111 in binary
if(read_columns()!=0)
{
printf("row 1 col %i\n\r",column);
}
output_b = 0xdf; // = 11011111 in binary
if(read_columns()!=0)
{
printf("row 1 col %i\n\r",column);
}
output_b = 0xef; // = 11101111 in binary
if(read_columns()!=0)
{
printf("row 1 col %i\n\r",column);
}
ETC
HTH Mike. | |
| |
|
| Tags |
| keypad |
| Thread Tools | |
| Display Modes | |
| |