Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Your question had fairly little to do with the AVR but some mistaken ideas about how compilers and microcontrollers work. That's not a complaint that it's a bad question - any question that helps you learn is good! </p> <p>(TLDR: "use bitwise operators" is only in contrast to AVR specific stuff, feel absolutely free to use all your normal operations.)</p> <p>First, you've expressed what you want to do - an equality test - in English. The whole point of a programming language like C is to allow you to express computed operations in a fairly readable manner, so use the most obvious (and thus clear) translation of <code>received_msg == 0xFF</code> - it is the compiler's job to convert this into code for the specific computer (AVR), and even if it does a horrible job of it it will waste no more than a few microseconds. (It doesn't, but if you make the code convoluted enough it can fail to do an excellent job.)</p> <p>Second, you've attempted to express the same operation - comparing every bit against a set value, and collecting the result to see if they were all equal - in two other manners. This gets tricky both to read and write, as is shown by the bugs in the second version, but more importantly the second version shows a misunderstanding of what C's bitwise operators do. Bitwise here means each bit of a value is processed independent of the other bits; they are still all processed. Therefore splitting it into a loop is not needed, and only makes the job of both programmer and compiler harder. The technique used to make bitwise operators only <em>affect</em> single bits, not to be confused with which they operate on, is known as masking; it relies on properties like "0 or n = n", "1 and n = n", and "0 xor n = n". </p> <p>I'm also getting the impression this was based around the idea that a microcontroller like the AVR would be working on individual bits all the time. This is extremely rare, but frequently emulated by PLCs. What we do have is operations making single bit work less costly than on general purpose CPUs. For instance, consider "PORTB |= 1&lt;&lt;3". This can be read as a few fundamental operations:</p> <pre><code>v0 := 1 // load immediate v1 := 3 v2 := v0 shiftleft v1 // shift left v3 := PORTB // load I/O register v4 := v3 or v2 PORTB := v4 // store back to I/O register </code></pre> <p>This interpretation would be an extremely reduced instruction set, where loads and stores never combine with ALU operations such as shift and or. You may even get such code out of the compiler if you ask it not to optimize at all. But since it's such a common operation for a microcontroller, the AVR has a single instruction to do this without spending registers on holding v0-v4:</p> <pre><code>SBI PORTB, 3 // (set bit in I/O register) </code></pre> <p>This brings us from needing two registers (from reusing vN which are no longer needed) and six instructions to zero registers and one instruction. Further gains are possible because once it's a single instruction, one can use a skip instead of a branch. But it relies on a few things being known, such as 1&lt;&lt;3 setting only a single, fixed bit, and PORTB being among the lowest 32 I/O registers. If the compiler did not know these things, it could never use the SBI instructions, and there was such a time. This is why we have the advice "use the bitwise operators" - you no longer need to write <code>sbi(PORTB,PB3);</code>, which is inobvious to people who don't know the AVR instruction set, but can now write <code>PORTB |= 1&lt;&lt;3;</code> which is standard C, and therefore clearer while being just as effective. Arguably better macro naming might make more readable code too, but many of these macros came along as typing shorthands instead - for instance <code>_BV(x)</code> which is equal to <code>1&lt;&lt;x</code>. </p> <p>Sadly some of the standard C formulations become rather tricky, like clearing bit N: <code>port &amp;= ~(1&lt;&lt;N);</code> It makes a pretty good case for a "clear_bit(port, bit)" macro, like Arduino's digitalWrite. Some microcontrollers (such as 8051) provide specific addresses for single bit work, and some compilers provide syntax extensions such as port.3. I sometimes wonder why AVR Libc doesn't declare <a href="http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;file=viewtopic&amp;p=952508" rel="nofollow">bitfields for bit manipulation</a>. Pardon the rant. There also remain some optimizations the compiler doesn't know of, such as converting <code>PORTB ^= x;</code> into <code>PINB = x;</code> (which really looks weird - PIN registers aren't writable, so they used that operation for another function). </p> <p>See also the <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html" rel="nofollow">AVR Libc manual section on bit manipulation</a>, particularly "Porting programs that use the deprecated sbi/cbi macros". </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload