Home > Blockchain >  Change MSB and leave remaining bits unchanged
Change MSB and leave remaining bits unchanged

Time:08-19

The question is as follows:

Write a single line of C-code that sets the four MSB in DDRD to 1011 and leave the rest unchanged.

The best I can do is:

DDRD = (DDRD & 0xF) | (1<<7) | (1<<5) | (1<<4);

or just

DDRD = (DDRD & 0xF) | (0b1011 << 4);

It gets the job done, but it's certainly not the cleanest. Is there a better solution I'm not seeing?

CodePudding user response:

The most readable and conventional form ought to be something like:

#define DDRD7 (1u << 7)
#define DDRD6 (1u << 6)
...
DDRD = (DDRD & 0x0Fu) | DDRD7 | DDRD5 | DDRD4;

Alternatively the bit masks could also be named something application-specific like LED2 or whatever. Naming signals the same way in the firmware as in the schematic is very good practice.

"Magic numbers" should be avoided, except 0xF which is used for bit-masking purposes so it's fine to use and self-documenting. DDRD & (DDRD0|DDRD1|DDRD2|DDRD3) would be less readable.

1<< should always be avoided since left-shifting a signed integer (1 has type int) is pretty much always a bug. Use 1u<<.

Binary constants should be avoided since they are not (yet) standard and may not be supported. Plus they are very hard to read when numbers get large. Serious beginner programmers are expected to understand hex before writing their first line of code, so why more experienced programmers ever need to use binary, I don't know.

Regarding 0xFu vs 0x0Fu, they are identical, but the latter is self-documenting code for "I am aware that I'm dealing with an 8 bit register".

  • Related