Consider using indent.exe to fix it. It is vital for a C program to be indented correctly. It can raise the legibility by 100%.
As to the design of your code, clearly you only want to make output when the state of PINB.0 changes. For that consider how you can use the ^ operator. It is very good for spotting when a bit is "different from last time".
A #define has nothing to do with code generation so I don't see how it could influence cycles or memory usage. Of course after something is #define'd then where that macro is then used I guess it might have some influence on those things. But the answer to "did #define made different.." is "no".
As you've written it there the first is best because wherever you use that preprocessor macro it'll just generate a few opcodes to do the AND operation. For the function version it'll (potentially) add a CALL/RET to each invocation. However if you made the function "static inline" there'd be no such overhead and you may benefit from C parameter type checking (talking of which, your function version forgot to specify types).
As you've written it there the first is best because wherever you use that preprocessor macro it'll just generate a few opcodes to do the AND operation. For the function version it'll (potentially) add a CALL/RET to each invocation. However if you made the function "static inline" there'd be no such overhead and you may benefit from C parameter type checking (talking of which, your function version forgot to specify types).
Posted by JohanEkdahl: Sun. Oct 6, 2013 - 07:34 AM
1
2
3
4
5
Total votes: 0
Quote:
why dangerous? because we need to do "function prototype"?
No, because the y parameter can be any, potentially complex thing.
Assume you have
#define CLEARBITMASK(x,y) (x &= (~y))
char a, b, c;
and you
CLEARBITMASK(a, b&c);
This results in the following code actually being passed to the compiler:
(a &= (~b&c));
If the macro was instead defined as
#define CLEARBITMASK(x,y) (x &= ~(y))
this would be passed to the compiler
(a &= ~(b&c));
Quite some difference, right?
I suspect that you do not at all understand what macros are.
They are handled by the C preprocessor (CPP), which goes through the source code and does replacements in it before the compiler goes to work. It is nothing at all like writing e.g. a function and calling it.
There will be more on this in your C textbook. (If not you need to buy a better C textbook.)
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
ok tq, i know that, but i miss what Dean's means, because of my english, i coppy-paste frome Dean's tutorial code in 1st page.
so what about the diff. between void and define, am i right with my code up there (i scared that i miss again because of my english, so perhaps ex.code will clear it)
one more question
why i have to used
foo &= ~0x01;
can i used
foo &= 0xFE;
i understand exactly why i have to used
foo &= ~(1<<2);
because if we used
foo &= ~(0<<2);
because it will nothing change has made if we shift 0. but with
Posted by JohanEkdahl: Sun. Oct 6, 2013 - 09:30 AM
1
2
3
4
5
Total votes: 0
Quote:
so what about the diff. between void and define
They are just totally different things!
The void is specifying a return value from a function.
The #define is a directive to the preprocessor to modify certain text in the C source before the compilation.
Just because they are in the seemingly corresponding places in your two examples does not mean that they are variants of something. Again, they are totally unrelated.
I still suspect that you do not have any (correct) concept of what the preprocessor is and does, and what a macro is. And again, any decent C textbook will give you the details on such subjects.
Quote:
why i have to used
foo &= ~0x01;
can i used
foo &= 0xFE;
Yes. The outcome should be the same.
Quote:
but with
foo &= 0xFE;
its mean 0xnnnnnnnn AND with 0x11111110
but i found this not work, why?
It should work just fine. If you don't say anything more detailed than "not work" then we can not say anything more detailed either.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
Posted by JohanEkdahl: Sun. Oct 6, 2013 - 10:04 AM
1
2
3
4
5
Total votes: 0
Quote:
i guess the 2nd one have more cycle
Stop guessing. Look at the generated code. Get the timings for the individual instructions in the "AVR Instruction Set" document available at www.atmel.com .
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
Stop guessing. Look at the generated code. Get the timings for the individual instructions in the "AVR Instruction Set" document available at www.atmel.com .
ok, tq for the link
i guess because i read in forum that
Quote:
PORTB |= 0b00001111;
means PORT B is OR with 0b00001111;
and
Quote:
PORTB |= (1<<1);
is shift 1 to the left once and OR to the PORT B, so thats the reason why i guess it has more cycle because every change the bit need to shift the bit one by one and do OR operation for each bit.
Posted by JohanEkdahl: Sun. Oct 6, 2013 - 10:37 AM
1
2
3
4
5
Total votes: 0
Quote:
i guess it has more cycle
You're still guessing. The facts are available to you - if you study the generated assembly/machine code.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
Can you take this discussion to a separate thread please? You aren't really giving feedback about the 101 post but asking basic questions about your misunderstanding of the C language.
When you use the ternary operator you can only use it to deliver a value to be used not to delimit two complete statements. So either give up on the ternary and just use compound if/else or do use the ternary but use it to do both an AND and an OR. In one case make the OR do nothing (OR with 0 has no effect) and in the other case make the AND do nothing (AND with 0xFF has no effect on an 8bi target).
I'll leave you to work out how to re-jig the macros to achieve this.
Oh and PLEASE give the macros upper case names. Most programmers expect mixed/one case to be symbol names and all upper case to be #define'd macros.
Does that make sense to you? Are you understanding how the ternary operator (?:) is to be used?
Are you aware that ?: and &= have the same precedence (and in those cases left to right evaluation will occur), effectively making your expression this (note the parenthesis I added):
Now take a look at what the &= operator has to the left.
EDIT: Ow. I left the computer before I got to press Submit, Cliff. You are free to issue your "Gee, I wish I said that"
EDIT2: On close inspection I believe I am more correct than you on this. A closer inspection might very well prove me wrong. I will return..
EDIT3: What I am sceptical about is: "When you use the ternary operator you can only use it to deliver a value to be used not to delimit two complete statements". AFAIK the second and third operators should be expressions. An assignment statement is an expression. Add to this that the whole ternary is an expression, and that you are free to form an expression and let it fall on the floor so-to-say. Methinks it is quite ok to code e.g.
x ? y = 1 : y = 42;
It's a stupid way to do what should be an if-else, but I think it will work. The coder might think it will be more efficient since the source code is more compact but he would likely be wrong on that assumption. I will return...
EDIT4: Yup, tested. I have this snippet:
uint8_t x;
x = PORTB;
x ? (PORTD |= 1) : (PORTD &= ~1);
Compiles just fine.
The error message the "OP" sees is because he has missed parenthesis. For my more transparent example just above this would be
x ? PORTD |= 1 : PORTD &= ~1;
If we add parenthesis for the implied left-to-right-evaluation-for-same-precedence-operators we get
(x ? PORTD |= 1 : PORTD) &= ~1;
I have verified that this generates the same error.
So, the solution would simply be to follow the rule that you should always follow. Put parenthesis around the whole macro:
Example:
BAD:
#define yes PORTD |= 1
#define no PORTD &= ~1
void foo(void)
{
uint8_t x;
x = PORTB;
x ? yes : no;
.
.
For the above I get exactly the same error.
GOOD:
#define yes (PORTD |= 1)
#define no (PORTD &= ~1)
void foo(void)
{
uint8_t x;
x = PORTB;
x ? yes : no;
.
.
No error.
Again: I concur with Cliff that you should not use the ternary operator to disguise an if-statement. The result of the complete ternary expression should go somewheere, or you should not use it. Do not assume that shorter source code will necessarily lead to more compact or faster machine code.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
OK my hands up i was wrong about ternary and precedence and off-course use upper case in macro
but i just looking for clear and simple way to do something
like this:
PORTX.X=X;
I know that bit is not access in c so i use that macro....
These operators work on bits and not logical values. Take two 8 bit bytes, combine with any of these operators, and you will get another 8 bit byte according to the operator's function.
Strictly speaking, that is not true.
In C, such operations always produce at least 16 bits.
More than 16 if int is larger than 16 bits.
Excellent tutorial. This has helped me understand bit operations a lot better .I used to have to rewrite the whole port or register with a new hex value. This makes it easy.
Are there any good tutorials like this on fuses. I find them somewhat confusing?
They use sfrb PORTB=0x25; then later in the program they can say PORTB.1=1; I tried to do this but sfrb doesn't seem to be defined
That syntax is only supported by Codevision. While it is a very elegant syntax for microcontroller programming it is a violation of the C standard which says that symbol names after "." must start with an alpha. The closest you can get with most C compilers is PORT.b0 where 'b' stands for "bit" or something like that.
If you read back through this entire thread you will find posts from a user "danni" with an attachment called "sbit.h". That uses this syntax but then goes on to define symbols such as:
In C, 0, (that is, 0x00 or 0x0000 or whatever) is taken to be false.
ANYTHING else is taken as true.
So 0x80 combined using a bitwise-AND with 0x81 = 0x80 and will be TRUE.
On the other hand, 0x80 combined using a logical AND with 0x81 is also TRUE because both 0x80 and 0x81 are logically TRUE.
You are also confusing yourself when you talk about "digits". in the expression 0b10000000, there are 8 BITS, not 8 digits.
Jim
I take your point about the use of "digit" but the poor choice of wording isn't what was causing my confusion. "Digit" is the decimal equivalent of "bit" to a binary numeric system. That's the sense I meant to convey. The AND bitwise math is NOT what is confusing me. Subtle distinction I know, but the wording in the OP implied to me that only one bit was being evaluated and the rest was being ignored. It was but only by virtue of the mask value being 0x80. But, if you want to see how I was looking at it (wrong as it was), the if(foo & 0x80) to me looked like if(byte & bit) because 0x80 represents a single bit being 1. Convoluted I know, but it's how my brain processed what I read. That incorrect thinking led to me assuming that the second operand could only represent a single bit, though it was itself a byte.... meaning, there would only be 8 possible choices for the second operand, namely 0x80, 0x40, 0x20, 0x10 etc. So, when I asked about 0x81, a byte with two 'on' bits, it was an effort to try and clear up the understanding I had which didn't make sense to me.
My point about logical AND was based on the previous incorrect assumption. If we look at the mask 0x81 with two bits, either one evaluating to true would result in the if() being executed. THAT would be a logical OR. I was taking the bitwise AND in the if(0x80 & 0x81) to mean that both the LSB and the MSB in the result would need to evaluate as true in order for the if() to execute. It only takes one, though. I get it now.
<edit> MODERATOR: PLEASE MOVE THIS POST TO THE SPLIT THREAD. APPARENTLY, I WAS IN THE MIDDLE OF POSTING WHEN YOU SPLIT IT. SORRY FOR THE CONFUSION.
Just to add to your confusion. Things would be quite different if the & was, in fact &&. That would effectively reduce everything on each side to a simple 0/1, false/true and then perform AND on the two.
I do think it's worth a bit of time reading around about boolean logic (my favourite subject at university in fact) as it is pretty fundamental to the embedded C programmer.
Consider using indent.exe to fix it. It is vital for a C program to be indented correctly. It can raise the legibility by 100%.
As to the design of your code, clearly you only want to make output when the state of PINB.0 changes. For that consider how you can use the ^ operator. It is very good for spotting when a bit is "different from last time".
- Log in or register to post comments
TopThanks for the tips Cliff I will look into both.
I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie
"The critical shortage here is not stuff, but time." - Johan Ekdahl
"Step N is required before you can do step N+1!" - ka7ehk
"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman
"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?" - Lee "theusch"
Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-) - Source Unknown
Please Read: Code-of-Conduct
Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user
- Log in or register to post comments
Topdid #define made different cycle/mileage/time/memory usage or not?
what about void somthin(void); ?
- Log in or register to post comments
TopWhat #define?
Regards,
Steve A.
The Board helps those that help themselves.
- Log in or register to post comments
TopA #define has nothing to do with code generation so I don't see how it could influence cycles or memory usage. Of course after something is #define'd then where that macro is then used I guess it might have some influence on those things. But the answer to "did #define made different.." is "no".
- Log in or register to post comments
Topwhat is the difference
with
which the best one?
- Log in or register to post comments
TopAs you've written it there the first is best because wherever you use that preprocessor macro it'll just generate a few opcodes to do the AND operation. For the function version it'll (potentially) add a CALL/RET to each invocation. However if you made the function "static inline" there'd be no such overhead and you may benefit from C parameter type checking (talking of which, your function version forgot to specify types).
- Log in or register to post comments
TopThe macro version looks dangerous - move the inversion outside of the inner braces.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
Topso in another word
#define is like this
will change to this by uC
meanwhile void CLEARBITMASK(int x,int y) {x &= (~y)}
will change to
is that like that? :?
why dangerous? because we need to do "function prototype"?
- Log in or register to post comments
TopNo, because the y parameter can be any, potentially complex thing.
Assume you have
and you
This results in the following code actually being passed to the compiler:
If the macro was instead defined as
this would be passed to the compiler
Quite some difference, right?
I suspect that you do not at all understand what macros are.
They are handled by the C preprocessor (CPP), which goes through the source code and does replacements in it before the compiler goes to work. It is nothing at all like writing e.g. a function and calling it.
There will be more on this in your C textbook. (If not you need to buy a better C textbook.)
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
Topok tq, i know that, but i miss what Dean's means, because of my english, i coppy-paste frome Dean's tutorial code in 1st page.
so what about the diff. between void and define, am i right with my code up there (i scared that i miss again because of my english, so perhaps ex.code will clear it)
one more question
why i have to used
can i used
i understand exactly why i have to used
because if we used
because it will nothing change has made if we shift 0. but with
its mean 0xnnnnnnnn AND with 0x11111110
but i found this not work, why?
- Log in or register to post comments
TopThey are just totally different things!
The void is specifying a return value from a function.
The #define is a directive to the preprocessor to modify certain text in the C source before the compilation.
Just because they are in the seemingly corresponding places in your two examples does not mean that they are variants of something. Again, they are totally unrelated.
I still suspect that you do not have any (correct) concept of what the preprocessor is and does, and what a macro is. And again, any decent C textbook will give you the details on such subjects.
Yes. The outcome should be the same.
It should work just fine. If you don't say anything more detailed than "not work" then we can not say anything more detailed either.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
Topops, i found my code seems like something false (typoo) its supposed to 0bNNNNNNNN instead of 0xNNNNNNNN..my bad, it works just fine..
umm one more thing...
this is has same cycle or not?
with
i guess the 2nd one have more cycle :roll:
- Log in or register to post comments
TopStop guessing. Look at the generated code. Get the timings for the individual instructions in the "AVR Instruction Set" document available at www.atmel.com .
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
Topok, tq for the link
i guess because i read in forum that
means PORT B is OR with 0b00001111;
and
is shift 1 to the left once and OR to the PORT B, so thats the reason why i guess it has more cycle because every change the bit need to shift the bit one by one and do OR operation for each bit.
- Log in or register to post comments
TopYou're still guessing. The facts are available to you - if you study the generated assembly/machine code.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopCan you take this discussion to a separate thread please? You aren't really giving feedback about the 101 post but asking basic questions about your misunderstanding of the C language.
- Log in or register to post comments
Topno need clawson it is done, thank you for the link btw...
- Log in or register to post comments
Topi use this simple macro in my code :
but the result is error :
"lvalue required as left operand of assignment "
the problen is "Puthc164data(x) (x ? hc164data_high :hc164data_low)"
but i don't know why !
- Log in or register to post comments
TopAdd -save-temps to your build options and you will see why:
This creates:
What you really want it something more like:
Or perhaps:
When you use the ternary operator you can only use it to deliver a value to be used not to delimit two complete statements. So either give up on the ternary and just use compound if/else or do use the ternary but use it to do both an AND and an OR. In one case make the OR do nothing (OR with 0 has no effect) and in the other case make the AND do nothing (AND with 0xFF has no effect on an 8bi target).
I'll leave you to work out how to re-jig the macros to achieve this.
Oh and PLEASE give the macros upper case names. Most programmers expect mixed/one case to be symbol names and all upper case to be #define'd macros.
- Log in or register to post comments
TopYes. Let's assume you've coded
The preprocessor will expand the macros. First step will yield this:
There are still macros to be expanded. The result will be:
Does that make sense to you? Are you understanding how the ternary operator (?:) is to be used?
Are you aware that ?: and &= have the same precedence (and in those cases left to right evaluation will occur), effectively making your expression this (note the parenthesis I added):
Now take a look at what the &= operator has to the left.
EDIT: Ow. I left the computer before I got to press Submit, Cliff. You are free to issue your "Gee, I wish I said that"
EDIT2: On close inspection I believe I am more correct than you on this. A closer inspection might very well prove me wrong. I will return..
EDIT3: What I am sceptical about is: "When you use the ternary operator you can only use it to deliver a value to be used not to delimit two complete statements". AFAIK the second and third operators should be expressions. An assignment statement is an expression. Add to this that the whole ternary is an expression, and that you are free to form an expression and let it fall on the floor so-to-say. Methinks it is quite ok to code e.g.
It's a stupid way to do what should be an if-else, but I think it will work. The coder might think it will be more efficient since the source code is more compact but he would likely be wrong on that assumption. I will return...
EDIT4: Yup, tested. I have this snippet:
Compiles just fine.
The error message the "OP" sees is because he has missed parenthesis. For my more transparent example just above this would be
If we add parenthesis for the implied left-to-right-evaluation-for-same-precedence-operators we get
I have verified that this generates the same error.
So, the solution would simply be to follow the rule that you should always follow. Put parenthesis around the whole macro:
Example:
BAD:
For the above I get exactly the same error.
GOOD:
No error.
Again: I concur with Cliff that you should not use the ternary operator to disguise an if-statement. The result of the complete ternary expression should go somewheere, or you should not use it. Do not assume that shorter source code will necessarily lead to more compact or faster machine code.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopOK my hands up i was wrong about ternary and precedence and off-course use upper case in macro
but i just looking for clear and simple way to do something
like this:
PORTX.X=X;
I know that bit is not access in c so i use that macro....
thanks
- Log in or register to post comments
TopThen you haven't read all this thread have you? There is a technique given that allows you to do pretty much that.
hint: look for posts by "danni".
- Log in or register to post comments
TopIn C, such operations always produce at least 16 bits.
More than 16 if int is larger than 16 bits.
Iluvatar is the better part of Valar.
- Log in or register to post comments
TopExcellent tutorial. This has helped me understand bit operations a lot better .I used to have to rewrite the whole port or register with a new hex value. This makes it easy.
Are there any good tutorials like this on fuses. I find them somewhat confusing?
- Log in or register to post comments
TopSorry somehow my comments ended up in the wrong place so I deleted them but I am not allowed to delete the post entirely
It is better to light a candle than curse the darkness.
- Log in or register to post comments
TopThis looks like a really nice way of doing things! So readable and straight forward. I am learning micro-controller C from
a book that references the AVR compiler.
They use
sfrb PORTB=0x25;
then later in the program they can say
PORTB.1=1;
I tried to do this but sfrb doesn't seem to be defined
In your solution
Does LED0=1;
take any more time at run time than
PORTB=PORTB|0b00000010
Thanks
It is better to light a candle than curse the darkness.
- Log in or register to post comments
TopThat syntax is only supported by Codevision. While it is a very elegant syntax for microcontroller programming it is a violation of the C standard which says that symbol names after "." must start with an alpha. The closest you can get with most C compilers is PORT.b0 where 'b' stands for "bit" or something like that.
If you read back through this entire thread you will find posts from a user "danni" with an attachment called "sbit.h". That uses this syntax but then goes on to define symbols such as:
which in turn is defined as:
so in effect it says:
None of this matters because it just means you can write:
and you don't need to care how this is really achieved.
EDIT: The sbit.h you need is in post 134: https://www.avrfreaks.net/comment...
- Log in or register to post comments
TopTried it and it works quite well!. Thanks Clawson . I find the code much more readable using this style.
It is better to light a candle than curse the darkness.
- Log in or register to post comments
TopI take your point about the use of "digit" but the poor choice of wording isn't what was causing my confusion. "Digit" is the decimal equivalent of "bit" to a binary numeric system. That's the sense I meant to convey. The AND bitwise math is NOT what is confusing me. Subtle distinction I know, but the wording in the OP implied to me that only one bit was being evaluated and the rest was being ignored. It was but only by virtue of the mask value being 0x80. But, if you want to see how I was looking at it (wrong as it was), the if(foo & 0x80) to me looked like if(byte & bit) because 0x80 represents a single bit being 1. Convoluted I know, but it's how my brain processed what I read. That incorrect thinking led to me assuming that the second operand could only represent a single bit, though it was itself a byte.... meaning, there would only be 8 possible choices for the second operand, namely 0x80, 0x40, 0x20, 0x10 etc. So, when I asked about 0x81, a byte with two 'on' bits, it was an effort to try and clear up the understanding I had which didn't make sense to me.
My point about logical AND was based on the previous incorrect assumption. If we look at the mask 0x81 with two bits, either one evaluating to true would result in the if() being executed. THAT would be a logical OR. I was taking the bitwise AND in the if(0x80 & 0x81) to mean that both the LSB and the MSB in the result would need to evaluate as true in order for the if() to execute. It only takes one, though. I get it now.
<edit> MODERATOR: PLEASE MOVE THIS POST TO THE SPLIT THREAD. APPARENTLY, I WAS IN THE MIDDLE OF POSTING WHEN YOU SPLIT IT. SORRY FOR THE CONFUSION.
- Log in or register to post comments
TopJust to add to your confusion. Things would be quite different if the & was, in fact &&. That would effectively reduce everything on each side to a simple 0/1, false/true and then perform AND on the two.
I do think it's worth a bit of time reading around about boolean logic (my favourite subject at university in fact) as it is pretty fundamental to the embedded C programmer.
- Log in or register to post comments
TopI realize this must be some kind of record in late revival of a thread, but I couldn't help but notice an error in one of the macros here.
really should be
I couldn't see any other reply with a correction, so I couldn't help myself. Sorry...
- Log in or register to post comments
TopJohan pointed it out over 4 years ago in #211:
https://www.avrfreaks.net/comment/945424#comment-945424
"Experience is what enables you to recognise a mistake the second time you make it."
"Good judgement comes from experience. Experience comes from bad judgement."
"Wisdom is always wont to arrive late, and to be a little approximate on first possession."
"When you hear hoofbeats, think horses, not unicorns."
"Fast. Cheap. Good. Pick two."
"We see a lot of arses on handlebars around here." - [J Ekdahl]
- Log in or register to post comments
TopA cleanup is needed - who's going to wade through nearly 250 posts?!
Top Tips:
- Log in or register to post comments
TopPerhaps.
Who needs to? Took me 30 seconds to find it. Clicked the 'View All' button next to the page buttons, then CTRL-F for define CLEARBITMASK.
"Experience is what enables you to recognise a mistake the second time you make it."
"Good judgement comes from experience. Experience comes from bad judgement."
"Wisdom is always wont to arrive late, and to be a little approximate on first possession."
"When you hear hoofbeats, think horses, not unicorns."
"Fast. Cheap. Good. Pick two."
"We see a lot of arses on handlebars around here." - [J Ekdahl]
- Log in or register to post comments
TopRoss McKenzie ValuSoft Melbourne Australia
- Log in or register to post comments
TopPages