Hi. Can I mix PORT wide and bit wide commands, or do I need to "register" pins as pinMode(0, OUTPUT) for each pin that I want to address by bit ?
Can I do boolean operations on output registers like PORTD = PORTD << 1
DDRC = 0b00011110; // bits 1, 2, 3, 4 o/p. Bit zero is Pot input.
PORTC = 0b00000000; // all relays off.
DDRD = 0b00011111; // bits 0, 1, 2, 3, 4 o/p
PORTD = 0b00011110; // CS_
delay (5000);
digitalWrite(1, LOW); // CS display
You can mix as you like, but to me this is one of those questions where if you need to ask then perhaps you shouldn't be doing it. No matter, play around and see what works.
You will need to explain what you mean by "PORT wide" and "bit wide".
No. pinMode() function manipulates the ports for you, one at a time, but you can achieve the same thing for many pins in a single operation, or a few operations.
Direct port manipulation can be significantly faster than using pinMode(), digitalWrite() etc., but compared to the speed a relay operates at, both are ridiculously fast.
Go ahead and enjoy playing with direct port manipulation, but be aware that the additional speed is almost certainly completely pointless in most scenarios, including yours.
The downside of direct port manipulation is that it limits your code to running on the particular model of MCU that you coded it for, and probably won't work on other MCUs, even those in the same family, without alteration. But the standard Arduino functions pinMode(), digitalWrite() etc will run on any Arduino compatible board.
with one port, I want to set 5 pins as output, then shift a low across them to Chip-select a series of (4) thermocouple amps. I think shifting a 1 across a register, then do an XOR with FF and equate a port with the result. PORTD = shiftRegister ^ FF; // bitwise complement
On another port, I want to switch individual pins depending on a test of the thermocouple values. Note: how do people evaluate execution times ?
For pin manipulation, I used an oscilloscope and measure the time between transitions in a loop. digitalWrite() on an AVR takes less than 10us (direct port manipulation can take as little as about 125ns.)
See also: Arduino toggle speed
Of course, using bytewide operations with direct port manipulation is faster, since it does multiple bits at once. The hypothetical PORTD = PORTD<<1 could take as little as 187.5ns (more if you need to mask the bits you're not using.)
(All of those times are probably very small compared to the time it'll take for a thermocouple ADC to take a reading...)
On the UNO and other AVR microprocessors, writing 1s to the PINx register toggles the corresponding bits in the PORTx register, so toggle can be written
This can actually be used to set bitfields in an IO port in an efficient manner (and it's even relevant to the original question!) RPi Pico uses it in their sdk, but I don't see any reason that it won't work with any chip that has a pin toggle register...
It'd look like:
PIND = (PORTD ^ newvalues) & mask;
Basically, bits that are either already the correct value, or not in the mask, are left alone (not toggled), while the masked bits with the wrong values are toggled to the desired value.
Assembles to 4 instructions, assuming the new value is already in a register:
I wonder if a compiler would see the common pattern
PORTx = (PORTx & ~mask) | (newvalues & mask);
and use it.
The PIC microprocessors had all kindsa tricks the assembly language programmers exploited; an industrial strength compiler I had access to "knew" and use them beyond what I would have hoped.