I'm programming a industrial plc and I have to manipulate bits for a profi-bus communication with a VFD. I get a 2byte status and have to send 2byte commands. For this operations I have to set bits to get the VFD operating. For example:
Byte n+1 Byte n
PLC --> --------------------- --------------- --> VFD
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
---------+--------- | | | | -+- | | +- 0: Reglersperre / Freigabe
| | | | | | | +--- 1: Freigabe / Schnellstopp
| | | | | | +----- 2: Freigabe / Halt
| | | | | +-------- 3..4: reserviert = 0
| | | | +------------5: Parametersatz-Umschaltung
| | | +------------- 6: Reset
| | +--------------- 7: reserviert = 0
| |
| +----------------- 8: Lüften der Bremse ohne Antreibsfreigabe
+---------------------------- 9..15: reserviert = 0
So I have to set bit 0 to set the VFD in operation mode. Then I need to set bit 2 to start the drive.
Now I found a question where bit-maipulation is described and I figured out that this solution should work, but I don't really understand it.
Can someone please explain why this works or doesn't work?
uint16_t change_bit(uint16_t command, unsigned int bit_nr, unsigned int val) {
/* command = 2byte command; bit_nr = bit to manipulate;
val = value bit should get (1;0) */
command ^= (-val ^ command) & (1U << bit_nr);
return command;
}