I'm prepared to be corrected here but on the AVR architecture the ports are IO mapped and that requires different instructions at the assembler level, therefore I think you can't have a pointer to IO although UI guess there's no reason the compiler can't work around that.
Hardware is generally a volatile byte, so if indeed ports have a data type I would think it would be uint8_t*.
volatile uint8_t * test = &PORTB ;
whether or not it does what you want may be a different story.
where does one learn such things...? aside from trial and error
Trial and error I guess, and these days asking on forums
I just noticed this thread. I’ve been trying to do something similar for the past couple of days, and it works if you define the pointer correctly. First, if I use < int* ptr = &PORTB; > I don’t get a warning, I get a compile time error.
Secondly, use of the proper pointer works correctly - ie, all of the forms in loop() set the proper bit, and turn on the Led.
// UNO uses PortB.5 for the Led.
#define ledPIN 13
//int* ptr = &PORTB;
volatile uint8_t* ptr = &PORTB;
Serial.print(", PORTD: ");
// the following 8 forms all turn on the Led.
//*ptr |= 0b100000;
*ptr |= 1 << 5;
//PORTB |= 0x20;
//PORTB |= 0b100000;
//PORTB |= 1 << 5;
Thirdly, what I don’t understand about this is that PORTB and PORTD do not print out correctly using Serial.print(). Here are the results of the above program, so ???
PORTB: 0, PORTD: 0
I also found the pointer method to be incredibly slow, for some unknown reason, so ??? on that too.
Having a pointer to a PORT works fine. Having a pointer to an individual pin of a port is not possible.
(well, you COULD think of the Arduino pin-numbers, as being pointers to individual pins, but as you know, they use quite a bit of code to implement that. Some of the digitalWrite alternatives go so far as to make individual pins into C++ “objects”, which I think gives you the ability to say stuff like:
I’m prepared to be corrected here but on the AVR architecture the ports are IO mapped…
They’re both. All registers are memory mapped. The first 32 are also I/O mapped. There are machine instructions for accessing individual bits in the first 32 registers. But all bits in all registers can be memory accessed using a read-modify-write sequence (typically three to four instructions).
When possible, adding const to the pointer allows the compiler to choose which instruction sequence can be used…
The values shown in sec 14.4 of the 328 d/s, maybe PORTB = 0x05, PORTD = 0x0B, etc. There's gotta be some difference when doing something like the following, but something is happening here, and I obviously don't know what it is (would be nice to see the assembler code).
PORTB |= 0x20;
PORTD |= 0x20;
Bill [westfw], thanks for the references, will check them out tomorrow.