Pages: [1]   Go Down
Author Topic: *pointer PINB1 ... is there a way?  (Read 555 times)
0 Members and 1 Guest are viewing this topic.
West palm beach, FL
Offline Offline
Sr. Member
****
Karma: 1
Posts: 325
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

is there a way to assign the address of a pin to a pointer?
works perfectly with data direction registers.

if not how does one make a function that asks for a pin number , with out having to resort to
if x ==1 then PINB1
if x = 2 then PINB2

one more question when  compiling this line gives me a warning, it still works as desired but im just wondering what the warning means
Code:
int *test = &PORTB ;

"Warning   1   initialization from incompatible pointer type [enabled by default]"

what data type are the ports?? and where does one learn such things...? aside from trial and error
« Last Edit: August 05, 2013, 11:43:13 pm by eddiea6987 » Logged

I could print the Arduino logo on a box of cereal and sell it as "Arduin-O's"

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8500
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Quote
where does one learn such things...? aside from trial and error
Trial and error I guess, and these days asking on forums smiley

_____
Rob
« Last Edit: August 06, 2013, 12:08:14 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
// 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 ???
Quote
PORTB: 0, PORTD: 0

I also found the pointer method to be incredibly slow, for some unknown reason, so ???? on that too.
http://forum.arduino.cc/index.php?topic=181482.msg1347130#msg1347130
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 132
Posts: 6746
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
myled = pin(13);
  :
myled = 1;
delay(1000);
myled = 0;
But I think most of those are aimed at speed rather than doing the full set of reasonable operator overloading.
http://forum.arduino.cc/index.php?topic=150325.0  for example.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12853
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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...

Code:
volatile uint8_t * const test = &PORTB ;
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12853
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Code:
PORTB |= 0x20;
PORTD |= 0x20;

Bill [westfw], thanks for the references, will check them out tomorrow.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 206
Posts: 12853
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The values shown in sec 14.4 of the 328 d/s, maybe PORTB = 0x05, PORTD = 0x0B, etc.

Code:
 Serial.print("PORTB: ");
  Serial.println( _SFR_IO_ADDR( PORTB ) );
  Serial.print(", PORTD: ");
  Serial.println( _SFR_IO_ADDR( PORTD ) );

Quote
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).

Code:
PORTB |= 0x20;
Code:
sbi 0x05, 5

Code:
PORTD |= 0x20;
Code:
sbi 0x0b, 5
Logged

UK
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
struct port {
  union {
    unsigned char valuue;
    struct {
      unsigned p0:1;
      unsigned p1:1;
      unsigned p2:1;
      unsigned p3:1;
      unsigned p4:1;
      unsigned p5:1;
      unsigned p6:1;
      unsigned p7:1;
    } __attribute__((packed));
  } __attribute__((packed));
} __attribute__((packed));

struct port *myPort = (struct port *)&PORTB;

myPort.p3 = 1;
Serial.println(myPort.p7);
(untested, but something I do often)
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Pages: [1]   Go Up
Jump to: