2

I am wanting to write to a register.

The register holds 1 byte of information. I wish to change bit 6 for argument's sake.

The way I am accomplishing this right now is to read the register, then do a set/clear.

This way I only change the bit I am interested in, and leave the rest untouched.

E.g.:

// Read register uint8_t reading = read_reg(0x00); // Set 6th bit if (wanting_to_set) { reading |= (1 << 6); } if (wanting_to_reset) { reading &= ~(1 << 6); } // Write back to register write_reg(0x00, reading); 

Is there a way I can set or reset the nth bit without knowing that the byte is? This way I can avoid having to read the register first.

2
  • Some microcontrollers have set/clear registers/instructions that allow single bits to be manipulated in a bound hardware register in one operation, so avoiding read/modify/write that can lead to issues with multiple threads and/or interrupt handlers. Commented Sep 12, 2021 at 13:59
  • ARM Cortex-M0, M3 and M4 based devices support bit-banding where you can do exactly that. To get an answer you will have to be more specific about the device part you are using. Commented Sep 12, 2021 at 21:02

2 Answers 2

4

Is there a way I can set or reset the nth bit without knowing that the byte is? This way I can avoid having to read the register first.

There is no standard way to perform such a thing in C. Even in the event that you have a machine with individually addressable bits, the C language does not define any means of accessing memory in units smaller than 8 bits, no matter what the capabilities of the underlying hardware.

Therefore, in standard C, if you want to modify an individual bit without modifying any of the other bits nearby then you must accomplish it by at the same time overwriting at least seven bits near that one with the same values they already have. That means you must either have the current values of those bits or not care what values are written to them.

Sign up to request clarification or add additional context in comments.

8 Comments

That means you must have the current values of those bits. When writing code like *x ^= 4; - is *x necessarily read? Can't the underlying instruction be something like xor [eax], 4 which doesn't read the current value?
@DanielKleinstein, that cannot be expressed in C. Moreover, although it does not necessarily read *x in that instruction, it does rely on *x having been previously read into eax, and therefore to be known.
Perhaps on some architectures, but on x86 for instance you can reference memory directly (like xor [eax], 4, which only requires you to store the address in eax). But you're right that this is beyond C as a language, and doesn't seem to help OP's case where he has limited register reading/writing abilities.
Even then, @DanielKleinstein, the CPU must read the current value from memory in order to compute the result.
"no computer system you are likely to meet supports addressing individual bits" ; ARM Cortex-M0, M3 and M4 all support bit addressable memory and peripheral registers via bit-banding and 8051 architecture devices has 256 bits of bit addressable space. Some MCUs have GPIO with separate set and clear registers to address groups of individual bits. Bearing in mind that this is tagged [embedded] it is in fact rather common within the domain and not really about general purpose "computers".
|
3

As an addition to @John's answer:

Very popular ARM Cortex-M(3,4) uCs have bit-banding memory area. All bits in this area are individually addressable. So you can simply read or write one bit by simple resing or writing to that address.

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.