avr-gcc keypad interfacing code problemMacros V/S inline functions while programming for avr-gccavr-gcc(4.4.2)/avr-libc linker issuesInterfacing a keypad with a microcontrollerAVR GCC : Global / Static Array not getting initialized properlyInterfacing Keypad to PIC16F877AWhy GCC compiler omitting some code?AVR sleep interrupt with keypadvhdl code interfacing keypad with fpgaavr-gcc float macro errorAVR-GCC initialization code
How do I get my boyfriend to remove pictures of his ex girlfriend hanging in his apartment?
What are some non-CS concepts that can be defined using BNF notation?
Is a list of the most common English words copyrightable?
Would preaching in a church be advantageous for becoming a lecturer?
Code Golf Measurer © 2019
Why do these two ways of understanding constant acceleration give different results?
I need an automatic way of making a lot of folders
Is the tap water in France safe to drink?
Is aerodynamics study compulsory for building a plane?
First author doesn't want a co-author to read the whole paper
Car as a good investment
How safe is the 4% rule if the U.S. goes back to the mean?
How do I reset the TSA-unlocked indicator on my lock?
Not returning after leave
Split mile limits to the thousandth based on ID
Why do Computer Science degrees contain a high proportion of mathematics?
How to prove that invoices are really unpaid?
Idiom for a situation or event that makes one poor or even poorer?
How can I communicate feelings to players without impacting their agency?
If I did not sign promotion bonus document, my career would be over. Is this duress?
I got this nail stuck in my tire, should I plug or replace?
Why isn't Hagrid removed from Hogwarts sooner in Harry's would-be 7th year?
Justify of equation to better explanation
Does a restocking fee still qualify as a business expense?
avr-gcc keypad interfacing code problem
Macros V/S inline functions while programming for avr-gccavr-gcc(4.4.2)/avr-libc linker issuesInterfacing a keypad with a microcontrollerAVR GCC : Global / Static Array not getting initialized properlyInterfacing Keypad to PIC16F877AWhy GCC compiler omitting some code?AVR sleep interrupt with keypadvhdl code interfacing keypad with fpgaavr-gcc float macro errorAVR-GCC initialization code
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
$begingroup$
I have this function to read key press from a 4x3 key-board:
uint8_t GetKeyPressed()
= 0X0F;
for(c=0;c<3;c++)
=(0X40>>c);
for(r=0;r<4;r++)
if(!(KEYPAD_PIN & (0X08>>r)))
return (r*3+c);
return 0XFF;//Indicate No key pressed
Some macro, I missed:
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
But I don't understand this code, pretty well, because of those bit shifting operations.
Can anyone help me with this code?
Compiler : avr-gcc
Micro-controller : ATmega328
microcontroller c avr-gcc keypad
New contributor
$endgroup$
add a comment
|
$begingroup$
I have this function to read key press from a 4x3 key-board:
uint8_t GetKeyPressed()
= 0X0F;
for(c=0;c<3;c++)
=(0X40>>c);
for(r=0;r<4;r++)
if(!(KEYPAD_PIN & (0X08>>r)))
return (r*3+c);
return 0XFF;//Indicate No key pressed
Some macro, I missed:
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
But I don't understand this code, pretty well, because of those bit shifting operations.
Can anyone help me with this code?
Compiler : avr-gcc
Micro-controller : ATmega328
microcontroller c avr-gcc keypad
New contributor
$endgroup$
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago
add a comment
|
$begingroup$
I have this function to read key press from a 4x3 key-board:
uint8_t GetKeyPressed()
= 0X0F;
for(c=0;c<3;c++)
=(0X40>>c);
for(r=0;r<4;r++)
if(!(KEYPAD_PIN & (0X08>>r)))
return (r*3+c);
return 0XFF;//Indicate No key pressed
Some macro, I missed:
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
But I don't understand this code, pretty well, because of those bit shifting operations.
Can anyone help me with this code?
Compiler : avr-gcc
Micro-controller : ATmega328
microcontroller c avr-gcc keypad
New contributor
$endgroup$
I have this function to read key press from a 4x3 key-board:
uint8_t GetKeyPressed()
= 0X0F;
for(c=0;c<3;c++)
=(0X40>>c);
for(r=0;r<4;r++)
if(!(KEYPAD_PIN & (0X08>>r)))
return (r*3+c);
return 0XFF;//Indicate No key pressed
Some macro, I missed:
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
But I don't understand this code, pretty well, because of those bit shifting operations.
Can anyone help me with this code?
Compiler : avr-gcc
Micro-controller : ATmega328
microcontroller c avr-gcc keypad
microcontroller c avr-gcc keypad
New contributor
New contributor
edited 8 hours ago
Danial
New contributor
asked 9 hours ago
DanialDanial
133 bronze badges
133 bronze badges
New contributor
New contributor
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago
add a comment
|
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago
add a comment
|
2 Answers
2
active
oldest
votes
$begingroup$
In an abstract manner the code does this:
for each pin PA6 to PA4 (column)
set pin as output, driving '0'
for each pin PA3 to PA0 (row)
if pin reads '0' then
return key code calculated as row*3+column
return 0xFF as key code, meaning "no key"
KEYPAD_PORT|= 0X0F;
should preset the output register of the port with '0's for PA6 to PA4. The other pins (bit 7 and bits 3 to 0) are not relevant. But here is an error because of the operator|=
: If any of the bits 7 to 4 is already 1, it will keep this value. The correct statement isKEYPAD_PORT &= 0x8F;
.The
KEYPAD_DDR
register selects the direction of the pins of your keypad port. Each bit corresponds to a pin. Setting a bit to 1 make the pin an output, 0 an input.The
KEYPAD_PIN
register is used to read the pins of your keypad port.
Now to the shifting operations:
KEYPAD_DDR|=(0X40>>c);
: The hex value 0x40
is shifted to the right by the value of c
. This results in values of 0x40
(0b01000000
), 0x20
(0b00100000
), and 0x10
(0b00010000
). This value is then ORed to KEYPAD_DDR
which was ANDed before with the complement of 0x7F
= 0x80
(0b10000000
). The results are 0xC0
(0b11000000
), 0xA0
(0b10100000
), and 0x90
(0b10010000
), resp.
!(KEYPAD_PIN & (0X08>>r))
: The hex value 0x08
is shifted to the right by the value of r
. This results in values of 0x08
(0b00001000
), 0x04
(0b00000100
), 0x02
(0b00000010
), and 0x01
(0b00000001
). The value read from KEYPAD_PIN
is ANDed with this value, giving zero if the "masked" pin is '0' and non-zero otherwise. By the unary operator !
a zero is converted to true
and a non-zero to false
. So the statement of the if
will be executed if the masked pin is '0'.
Note: I like a lowercase 'X'/'B' better than the uppercase for hex and binary constants. But this is a bit of personal taste.
Only you can tell about the pin PA7. That's why I ignored it.
$endgroup$
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
add a comment
|
$begingroup$
Here is your code with the comments that it should have had all along added in, plus tables showing exactly what the shift operations are doing (the latter shouldn't be necessary for any experienced C programmer):
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
uint8_t GetKeyPressed()
= 0X0F;
/* Scan through the three columns - 0, 1, 2
*/
for (c=0; c<3; c++)
/* Enable the output for the column we want to drive, but also be sure
* not to modify the existing DDR value for bit 7. This sets DDR to
* c == 0: ?1000000
* c == 1: ?0100000
* c == 2: ?0010000
*/
KEYPAD_DDR &= ~(0X7F);
KEYPAD_DDR
/* No keys pressed, return special code.
*/
return 0XFF;
Note that there's a subtle bug. The intent is to drive the column lines low one at a time, but we don't actually know what the port data is for those lines. The line
KEYPAD_PORT |= 0X0F;
Only sets bits 0-3, but doesn't affect bits 4-7. This is a useless operation, since we never enable those pins as outputs anyway. This line needs to be replaced by
KEYPAD_PORT &= 0X8F;
in order to force bits 4-6 low so that we can use the data to drive the columns one at a time. This leaves bit 7 alone, since we don't want to affect it, and we don't care about the data for bits 0-3.
$endgroup$
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("schematics", function ()
StackExchange.schematics.init();
);
, "cicuitlab");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "135"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Danial is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f462049%2favr-gcc-keypad-interfacing-code-problem%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
In an abstract manner the code does this:
for each pin PA6 to PA4 (column)
set pin as output, driving '0'
for each pin PA3 to PA0 (row)
if pin reads '0' then
return key code calculated as row*3+column
return 0xFF as key code, meaning "no key"
KEYPAD_PORT|= 0X0F;
should preset the output register of the port with '0's for PA6 to PA4. The other pins (bit 7 and bits 3 to 0) are not relevant. But here is an error because of the operator|=
: If any of the bits 7 to 4 is already 1, it will keep this value. The correct statement isKEYPAD_PORT &= 0x8F;
.The
KEYPAD_DDR
register selects the direction of the pins of your keypad port. Each bit corresponds to a pin. Setting a bit to 1 make the pin an output, 0 an input.The
KEYPAD_PIN
register is used to read the pins of your keypad port.
Now to the shifting operations:
KEYPAD_DDR|=(0X40>>c);
: The hex value 0x40
is shifted to the right by the value of c
. This results in values of 0x40
(0b01000000
), 0x20
(0b00100000
), and 0x10
(0b00010000
). This value is then ORed to KEYPAD_DDR
which was ANDed before with the complement of 0x7F
= 0x80
(0b10000000
). The results are 0xC0
(0b11000000
), 0xA0
(0b10100000
), and 0x90
(0b10010000
), resp.
!(KEYPAD_PIN & (0X08>>r))
: The hex value 0x08
is shifted to the right by the value of r
. This results in values of 0x08
(0b00001000
), 0x04
(0b00000100
), 0x02
(0b00000010
), and 0x01
(0b00000001
). The value read from KEYPAD_PIN
is ANDed with this value, giving zero if the "masked" pin is '0' and non-zero otherwise. By the unary operator !
a zero is converted to true
and a non-zero to false
. So the statement of the if
will be executed if the masked pin is '0'.
Note: I like a lowercase 'X'/'B' better than the uppercase for hex and binary constants. But this is a bit of personal taste.
Only you can tell about the pin PA7. That's why I ignored it.
$endgroup$
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
add a comment
|
$begingroup$
In an abstract manner the code does this:
for each pin PA6 to PA4 (column)
set pin as output, driving '0'
for each pin PA3 to PA0 (row)
if pin reads '0' then
return key code calculated as row*3+column
return 0xFF as key code, meaning "no key"
KEYPAD_PORT|= 0X0F;
should preset the output register of the port with '0's for PA6 to PA4. The other pins (bit 7 and bits 3 to 0) are not relevant. But here is an error because of the operator|=
: If any of the bits 7 to 4 is already 1, it will keep this value. The correct statement isKEYPAD_PORT &= 0x8F;
.The
KEYPAD_DDR
register selects the direction of the pins of your keypad port. Each bit corresponds to a pin. Setting a bit to 1 make the pin an output, 0 an input.The
KEYPAD_PIN
register is used to read the pins of your keypad port.
Now to the shifting operations:
KEYPAD_DDR|=(0X40>>c);
: The hex value 0x40
is shifted to the right by the value of c
. This results in values of 0x40
(0b01000000
), 0x20
(0b00100000
), and 0x10
(0b00010000
). This value is then ORed to KEYPAD_DDR
which was ANDed before with the complement of 0x7F
= 0x80
(0b10000000
). The results are 0xC0
(0b11000000
), 0xA0
(0b10100000
), and 0x90
(0b10010000
), resp.
!(KEYPAD_PIN & (0X08>>r))
: The hex value 0x08
is shifted to the right by the value of r
. This results in values of 0x08
(0b00001000
), 0x04
(0b00000100
), 0x02
(0b00000010
), and 0x01
(0b00000001
). The value read from KEYPAD_PIN
is ANDed with this value, giving zero if the "masked" pin is '0' and non-zero otherwise. By the unary operator !
a zero is converted to true
and a non-zero to false
. So the statement of the if
will be executed if the masked pin is '0'.
Note: I like a lowercase 'X'/'B' better than the uppercase for hex and binary constants. But this is a bit of personal taste.
Only you can tell about the pin PA7. That's why I ignored it.
$endgroup$
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
add a comment
|
$begingroup$
In an abstract manner the code does this:
for each pin PA6 to PA4 (column)
set pin as output, driving '0'
for each pin PA3 to PA0 (row)
if pin reads '0' then
return key code calculated as row*3+column
return 0xFF as key code, meaning "no key"
KEYPAD_PORT|= 0X0F;
should preset the output register of the port with '0's for PA6 to PA4. The other pins (bit 7 and bits 3 to 0) are not relevant. But here is an error because of the operator|=
: If any of the bits 7 to 4 is already 1, it will keep this value. The correct statement isKEYPAD_PORT &= 0x8F;
.The
KEYPAD_DDR
register selects the direction of the pins of your keypad port. Each bit corresponds to a pin. Setting a bit to 1 make the pin an output, 0 an input.The
KEYPAD_PIN
register is used to read the pins of your keypad port.
Now to the shifting operations:
KEYPAD_DDR|=(0X40>>c);
: The hex value 0x40
is shifted to the right by the value of c
. This results in values of 0x40
(0b01000000
), 0x20
(0b00100000
), and 0x10
(0b00010000
). This value is then ORed to KEYPAD_DDR
which was ANDed before with the complement of 0x7F
= 0x80
(0b10000000
). The results are 0xC0
(0b11000000
), 0xA0
(0b10100000
), and 0x90
(0b10010000
), resp.
!(KEYPAD_PIN & (0X08>>r))
: The hex value 0x08
is shifted to the right by the value of r
. This results in values of 0x08
(0b00001000
), 0x04
(0b00000100
), 0x02
(0b00000010
), and 0x01
(0b00000001
). The value read from KEYPAD_PIN
is ANDed with this value, giving zero if the "masked" pin is '0' and non-zero otherwise. By the unary operator !
a zero is converted to true
and a non-zero to false
. So the statement of the if
will be executed if the masked pin is '0'.
Note: I like a lowercase 'X'/'B' better than the uppercase for hex and binary constants. But this is a bit of personal taste.
Only you can tell about the pin PA7. That's why I ignored it.
$endgroup$
In an abstract manner the code does this:
for each pin PA6 to PA4 (column)
set pin as output, driving '0'
for each pin PA3 to PA0 (row)
if pin reads '0' then
return key code calculated as row*3+column
return 0xFF as key code, meaning "no key"
KEYPAD_PORT|= 0X0F;
should preset the output register of the port with '0's for PA6 to PA4. The other pins (bit 7 and bits 3 to 0) are not relevant. But here is an error because of the operator|=
: If any of the bits 7 to 4 is already 1, it will keep this value. The correct statement isKEYPAD_PORT &= 0x8F;
.The
KEYPAD_DDR
register selects the direction of the pins of your keypad port. Each bit corresponds to a pin. Setting a bit to 1 make the pin an output, 0 an input.The
KEYPAD_PIN
register is used to read the pins of your keypad port.
Now to the shifting operations:
KEYPAD_DDR|=(0X40>>c);
: The hex value 0x40
is shifted to the right by the value of c
. This results in values of 0x40
(0b01000000
), 0x20
(0b00100000
), and 0x10
(0b00010000
). This value is then ORed to KEYPAD_DDR
which was ANDed before with the complement of 0x7F
= 0x80
(0b10000000
). The results are 0xC0
(0b11000000
), 0xA0
(0b10100000
), and 0x90
(0b10010000
), resp.
!(KEYPAD_PIN & (0X08>>r))
: The hex value 0x08
is shifted to the right by the value of r
. This results in values of 0x08
(0b00001000
), 0x04
(0b00000100
), 0x02
(0b00000010
), and 0x01
(0b00000001
). The value read from KEYPAD_PIN
is ANDed with this value, giving zero if the "masked" pin is '0' and non-zero otherwise. By the unary operator !
a zero is converted to true
and a non-zero to false
. So the statement of the if
will be executed if the masked pin is '0'.
Note: I like a lowercase 'X'/'B' better than the uppercase for hex and binary constants. But this is a bit of personal taste.
Only you can tell about the pin PA7. That's why I ignored it.
edited 8 hours ago
answered 8 hours ago
the busybeethe busybee
3751 silver badge9 bronze badges
3751 silver badge9 bronze badges
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
add a comment
|
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
I have added those macros , can you see again please ?
$endgroup$
– Danial
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
Well, now we know the the port for the keypad is port A. What precisely are you missing still?
$endgroup$
– the busybee
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
user with reputation 15, can't upvote
$endgroup$
– Danial
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
$begingroup$
So your question is answered, right? Great, have a lot of fun, and good luck!
$endgroup$
– the busybee
8 hours ago
add a comment
|
$begingroup$
Here is your code with the comments that it should have had all along added in, plus tables showing exactly what the shift operations are doing (the latter shouldn't be necessary for any experienced C programmer):
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
uint8_t GetKeyPressed()
= 0X0F;
/* Scan through the three columns - 0, 1, 2
*/
for (c=0; c<3; c++)
/* Enable the output for the column we want to drive, but also be sure
* not to modify the existing DDR value for bit 7. This sets DDR to
* c == 0: ?1000000
* c == 1: ?0100000
* c == 2: ?0010000
*/
KEYPAD_DDR &= ~(0X7F);
KEYPAD_DDR
/* No keys pressed, return special code.
*/
return 0XFF;
Note that there's a subtle bug. The intent is to drive the column lines low one at a time, but we don't actually know what the port data is for those lines. The line
KEYPAD_PORT |= 0X0F;
Only sets bits 0-3, but doesn't affect bits 4-7. This is a useless operation, since we never enable those pins as outputs anyway. This line needs to be replaced by
KEYPAD_PORT &= 0X8F;
in order to force bits 4-6 low so that we can use the data to drive the columns one at a time. This leaves bit 7 alone, since we don't want to affect it, and we don't care about the data for bits 0-3.
$endgroup$
add a comment
|
$begingroup$
Here is your code with the comments that it should have had all along added in, plus tables showing exactly what the shift operations are doing (the latter shouldn't be necessary for any experienced C programmer):
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
uint8_t GetKeyPressed()
= 0X0F;
/* Scan through the three columns - 0, 1, 2
*/
for (c=0; c<3; c++)
/* Enable the output for the column we want to drive, but also be sure
* not to modify the existing DDR value for bit 7. This sets DDR to
* c == 0: ?1000000
* c == 1: ?0100000
* c == 2: ?0010000
*/
KEYPAD_DDR &= ~(0X7F);
KEYPAD_DDR
/* No keys pressed, return special code.
*/
return 0XFF;
Note that there's a subtle bug. The intent is to drive the column lines low one at a time, but we don't actually know what the port data is for those lines. The line
KEYPAD_PORT |= 0X0F;
Only sets bits 0-3, but doesn't affect bits 4-7. This is a useless operation, since we never enable those pins as outputs anyway. This line needs to be replaced by
KEYPAD_PORT &= 0X8F;
in order to force bits 4-6 low so that we can use the data to drive the columns one at a time. This leaves bit 7 alone, since we don't want to affect it, and we don't care about the data for bits 0-3.
$endgroup$
add a comment
|
$begingroup$
Here is your code with the comments that it should have had all along added in, plus tables showing exactly what the shift operations are doing (the latter shouldn't be necessary for any experienced C programmer):
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
uint8_t GetKeyPressed()
= 0X0F;
/* Scan through the three columns - 0, 1, 2
*/
for (c=0; c<3; c++)
/* Enable the output for the column we want to drive, but also be sure
* not to modify the existing DDR value for bit 7. This sets DDR to
* c == 0: ?1000000
* c == 1: ?0100000
* c == 2: ?0010000
*/
KEYPAD_DDR &= ~(0X7F);
KEYPAD_DDR
/* No keys pressed, return special code.
*/
return 0XFF;
Note that there's a subtle bug. The intent is to drive the column lines low one at a time, but we don't actually know what the port data is for those lines. The line
KEYPAD_PORT |= 0X0F;
Only sets bits 0-3, but doesn't affect bits 4-7. This is a useless operation, since we never enable those pins as outputs anyway. This line needs to be replaced by
KEYPAD_PORT &= 0X8F;
in order to force bits 4-6 low so that we can use the data to drive the columns one at a time. This leaves bit 7 alone, since we don't want to affect it, and we don't care about the data for bits 0-3.
$endgroup$
Here is your code with the comments that it should have had all along added in, plus tables showing exactly what the shift operations are doing (the latter shouldn't be necessary for any experienced C programmer):
#define KEYPAD A
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR DDR(KEYPAD)
#define KEYPAD_PIN PIN(KEYPAD)
uint8_t GetKeyPressed()
= 0X0F;
/* Scan through the three columns - 0, 1, 2
*/
for (c=0; c<3; c++)
/* Enable the output for the column we want to drive, but also be sure
* not to modify the existing DDR value for bit 7. This sets DDR to
* c == 0: ?1000000
* c == 1: ?0100000
* c == 2: ?0010000
*/
KEYPAD_DDR &= ~(0X7F);
KEYPAD_DDR
/* No keys pressed, return special code.
*/
return 0XFF;
Note that there's a subtle bug. The intent is to drive the column lines low one at a time, but we don't actually know what the port data is for those lines. The line
KEYPAD_PORT |= 0X0F;
Only sets bits 0-3, but doesn't affect bits 4-7. This is a useless operation, since we never enable those pins as outputs anyway. This line needs to be replaced by
KEYPAD_PORT &= 0X8F;
in order to force bits 4-6 low so that we can use the data to drive the columns one at a time. This leaves bit 7 alone, since we don't want to affect it, and we don't care about the data for bits 0-3.
answered 7 hours ago
Dave Tweed♦Dave Tweed
138k11 gold badges175 silver badges301 bronze badges
138k11 gold badges175 silver badges301 bronze badges
add a comment
|
add a comment
|
Danial is a new contributor. Be nice, and check out our Code of Conduct.
Danial is a new contributor. Be nice, and check out our Code of Conduct.
Danial is a new contributor. Be nice, and check out our Code of Conduct.
Danial is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Electrical Engineering Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f462049%2favr-gcc-keypad-interfacing-code-problem%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
This is a pretty broad question. If there is something specific about the shift operation that you don't understand then try to ask a more specific question. Can you describe, in words, what you do understand about how this keypad is used?
$endgroup$
– Elliot Alderson
9 hours ago
$begingroup$
@ElliotAlderson I know the basic principle of keypad, I have read the technique on slide... but not this code..
$endgroup$
– Danial
8 hours ago
$begingroup$
@MaifeeUlAsad here you go
$endgroup$
– Danial
8 hours ago