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*.
This compiles
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;
void setup()
{
Serial.begin(57600);
pinMode(ledPIN, OUTPUT);
Serial.print("PORTB: ");
Serial.print(PORTB);
Serial.print(", PORTD: ");
Serial.print(PORTD);
}
void loop()
{
// the following 8 forms all turn on the Led.
//bitSet(*ptr, 5);
//*ptr |= 0b100000;
*ptr |= 1 << 5;
//PORTB |= 0x20;
//PORTB |= 0b100000;
//PORTB |= 1 << 5;
//bitSet(PORTB, 5);
//digitalWrite(ledPIN, HIGH);
delay(100);
digitalWrite(ledPIN, LOW);
delay(500);
}
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 ???
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:
Graynomad:
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...
oric_dan:
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
Why do you believe zero and zero are not the correct values? What values were you expecting?
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.
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).
Create a structure to encompass the contents of the entire port, with each bit represented by a 1-bit integer. Then create a pointer of that struct and assign the address of the port to it: