Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 9 months ago.
Bitwise assignment operators
Does the mbed complier permit the use of bitwise assignment operators such as, " &= ", " |= ", or " <<= "? (the quotes are not part of the operators) Here's an example of how to use this operator, and what it's supposed to do:
EXAMPLE--
uint32_t bit_byte = 0x000FF000; printf("This is bit_byte before a twelve-bit shift: %#X\n\r", bit_byte); bit_byte <<= 12; printf("\n\rThis is bit_byte after a twelve-bit shift: %#X\n\r", bit_byte);
OUTPUT SHOULD BE--
This is bit_byte before a twelve-bit shift: 0x000FF000 This is bit_byte after a twelve-bit shift: 0xFF000000
BUT I GET--
This is bit_byte before a twelve-bit shift: 0x000FF000 This is bit_byte after a twelve-bit shift:
In other words, no output of the results of the shift and assignment.
I also don't get any warnings at compile time either.
Is there a library that I need to include and if so, why no warning?
There are other ways of doing this:
bit_byte = bit_byte << 12;
but using the bitwise assignment operators make for more compact, easily readable code.
I've already worked around this issue with something like the above code, but I miss that set of operators.
Thanks for reading.
Tom
1 Answer
9 years, 9 months ago.
The operators should work just fine. Have used them myself. Check the code following the printf. Perhaps there is a crash that causes the printf to stop also. You may also want to explicitly use:
// Host PC Communication channels Serial pc(USBTX, USBRX); pc.printf("\n\rThis is bit_byte after a twelve-bit shift: %#X\n\r", bit_byte); while(1);
Yes, they should, but they don't.
The printf() statements were never a problem. They were not added until a problem became apparent. I used those to set up an output for the reader to understand what was happening.
In mbed, the assignment operators neither assigned nor operated. Adding another line helped.
The larger focus of the program is to take raw data, (low-to high pulses from a sensor,) save that data, then convert that data into something the display driver can pass on to the 4-digit 7-segment display.
The code below takes an uint32_t value, splits it up into three 8-bit bytes, (the scale of the data is larger than two bytes, but smaller than three bytes,) then it puts this data in specific locations in the EEPROM. The EEPROM has 8-bit memory locations, so 32-bit data needs to be sliced and diced in an orderly way for storage and retrieval. The point of putting data in an EEPROM is that if the power is cut, there will be a record of how much fuel has been used from the cell. When power is resumed, the data can be shoved back into the display conversion routines and passed along to the display without missing a beat. So far it works fine without the bitwise assignment operators functioning the way I would expect.
Other areas of the program have more opportunities for bitwise assignment operators to work their magic. This is a sample that really only has one line where it would be handy.
void save_pulse_count(uint32_t signal_pulse){ uint32_t gas_can; char filler[2]; gas_can = signal_pulse >> 16; // Shift off lower 16 bits for high byte printf("this is gas_can high byte:\t\t%#X\n\r",gas_can); // Verify filler[0] = hi_addr; // Load array with address and data filler[1] = (uint8_t)gas_can; memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // EEPROM is slow reader needs a delay gas_can = signal_pulse & 0xFF00; // Mask off upper eight bits for middle byte gas_can = gas_can >> 8; // Shift off lower byte of data printf("this is gas_can middle byte:\t\t%#X\n\r",gas_can); // Verify filler[0] = md_addr; // Load result into a char array filler[1] = (uint8_t)gas_can; memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // Read War and Peace gas_can = signal_pulse & 0x0000FF; // Mask off upper 16 bytes for low byte printf("this is gas_can low byte:\t\t%#X\n\r",gas_can); // Verify filler[0] = lo_addr; // Load filler[1] = (uint8_t)gas_can; memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // Take a nap return;} // gas_can = gas_can >> 8; // This worked consistently without fail // gas_can >>= 8; // This did not and the compiler did not complain
Hmm, I dont see why the bitshift should go wrong. Maybe it is the \t\t in your printf? Anyhow, the code can probably be simplified even more:
void save_pulse_count(uint32_t signal_pulse){ char filler[2]; filler[0] = hi_addr; // Load array with address and data filler[1] = (signal_pulse >> 16) & 0xFF; printf("this is the high byte: %#X\n\r", filler[1] ); // Verify memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // EEPROM is slow reader needs a delay filler[0] = md_addr; // Load result into a char array filler[1] = (signal_pulse >> 8) & 0xFF; printf("this is the middle byte: %#X\n\r", filler[1] ); // Verify memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // Read War and Peace filler[0] = lo_addr; // Load filler[1] = (signal_pulse) & 0xFF; printf("this is the low byte: %#X\n\r", filler[1] ); // Verify memory.write(EEPROM_write,filler,2,0); // Write to EEPROM wait(0.01); // Take a nap return;}
You may even be able to write all bytes to the EEPROM in one go by defining an array of 6 bytes,
posted by 16 Mar 2015