I was wondering if someone could help me solve one problem, because I am very new to this and I was given the code of a former programmer to work with.
I'm trying to figure out the value of 0x8008 & ~(1<<15).
Maybe someone could also tell me what's the purpose of writing a value in this manner?
Code:
// STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; URXINV disabled; UEN TX_RX;
U1MODE = (0x8008 & ~(1<<15)); // disabling UARTEN bit
From what I understand:
0x8008 =わ 1000000000001000
1<<15 =わ 1000000000000000
~(1<<15) = 0111111111111111
so: 1000000000001000 & 0111111111111111 =わ 00000000000001000
This answer bugs me, because judging by it - UART is disabled, which is definitely not true.
datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/70000582e.pdf
I did some digging in the code and I found this line:
U1MODEbits.UARTEN = 1;
Still don't get what's the purpose of disabling the UART first and then enabling it.
1 Answer 1
This is an obtuse bit of code, and doesn't really have any virtue. It combines a shift with a magic number, so it's even less clear than just directly writing the value...
You would usually define somewhere the meaningful bit name(s), in this case UARTEN, with its index in the register. It would be more usual to do a read-modify-write sequence (unless you're initialising registers). So, copy the original, modify the bit, and then re-write to the register. This would look something like:
#define UARTEN 15
U1MODE = U1MODE & ~(1<<UARTEN); // clear UARTEN
U1MODE = U1MODE | (1<<UARTEN); // set UARTEN
As the mask is a constant, the compiler should optimise out the shift and negation and then do a simple bitwise mask (although check the disassembled output).
-
\$\begingroup\$ Depending upon the hardware design, read-modify-write sequences may not behave as intended. In a good design, registers that are readable and writable should generally behave sanely when given a read-modify-write sequence, but not all designs are good. Writing an exact combination of bits will generally avoid trouble even when using badly designed devices. \$\endgroup\$supercat– supercat2018年06月14日 17:23:03 +00:00Commented Jun 14, 2018 at 17:23
-
\$\begingroup\$ @supercat - indeed, the code above does hide the internals of what is happening, but should suffice to explain this situation. \$\endgroup\$awjlogan– awjlogan2018年06月14日 18:01:18 +00:00Commented Jun 14, 2018 at 18:01
Explore related questions
See similar questions with these tags.
U1MODEbits.UARTEN = 0
, and it would work (in the 8-bit case translating to a bcf or bsf instruction). Isn't that the case with the 16-bit PICs? \$\endgroup\$