Manipulating Port C on Arduino Due

Hi All,

Having trouble working out how to manipulate Arduino Due ports, as they go higher than 8bit, so couldn't workout if there was a different way of dealing with that.

Looking at the Schematic of the Arduino Due, Port C has 31 pins (with bits 0-30). I have attached LEDs from pins 44-51 (bits 12 - 19 on Port C).

I want to manipulate them, so when a variable increases in number, it changes which LED is on. Currently I have...

     if (Variable == 0)
     {
      PORTC = B0000000000000000000000000000000;  //way of writing 1...
     }
     else if (Variable == 1)
     {
      PORTC = 0x0C;  //way of writing 2...
     }
     else if (Variable == 2)
     {
      PORTC = 0x0D;
     }
     //ETC... there are 8 LED's in total...

The problem I have is that there are potentially other components using pins on PORTC and I do not wish to influence them, just bits 12 - 19. How would I go about that?

Could I write something like:

PORTC = BXXXXXXXXXXXX00000100XXXXXXXXXXXX; //The X indicating leave that bit alone

or

PORTC 12-19 = B00000100;

Cheers!

Bump*

What I do on the 8-bit parts is this: PORTC = PORTC & 0b11110111; // clear bit 3, leave rest alone. 1 AND x = x, 0 AND x = 0

PORTC = PORT | 0b00001000; // set bit 3, leave rest alone/ 0 OR x = x, 1 OR x = 1

I imagine similar would work on a 16 or 32 bit port. All bits must be accounted for.

You can also do this: PORTC = PORTC & 0b00001111; // clear upper bits variable = 0b10100000 & 0b11110000; // define new upper 4 bits, make sure lower 4 are clear (if needed) PORTC = PORTC | variable; // OR in new upper bits

Hey thanks for replying!

PORTC doesn't work? I keep getting errors on the IDE to the effect of PORTC isnt a recognised word? I am using a Due btw

Like I said, that's what I do on the 8-bit parts. The Due may have slightly different syntax, I've not used one.

The registers on the Due have different names, and there are more of them per port, since the IO facilities on the SAM chips are more advanced. You still manipulate the registers the same way, as discussed above - just the names of the registers will be different, and you may need to set more of them.

Refer to the datasheet for register names and details of what each one does.

As has been said, the Port syntax for the Due is different, and PORTC will not work.

A forumn search on "Arduino Due port manipulation" will get you started, and one of the best threads is this http://forum.arduino.cc/index.php?topic=260731.0

For PORTC you will be using the bit masking with REG_PIOC_SODR to set the pins and REG_PIOC_CODR to clear the pins.

Arduino Due is based on 32 bit ARM (SAM3X8E) then the addressing of ports also should be in 32 bit. and also they use several other registers like PIO_PDR, PIO_IDR, PIO_ABSR etc. take a look at this page:

http://arduino.stackexchange.com/questions/9117/sam3x8e-arduino-due-pin-io-registers

it explains a lot. also take a close look on SAM3X8E datasheet. its boooooring but very useful and use like

0b000000000111100000001111111100

instead of

B00..

0x represents Hex, 0b represents binary. I'm also learning about Due. I'd be happy if it works out.

Sourav

Hi DSAFS2016,

To use a given port to output a binary sequence, (that incidently mimics how the older AVR ports work), it’s first necessary to set the bits in the port’s Output Write Enable Register (OWER). By default this is disabled. After setting the required port pins to be outputs using the Output Enable Register (OER), you can alter the Due’s output logic values by setting or clearing the bits in the port’s Output Data Status Register (ODSR), (as opposed to using the set (SODR) and and clear (CODR) data registers).

The following code shows how to set up a binary sequence on port D. It sets only the lowest four bits as outputs, then cycles through the sequence 0001, 0010, 0100 and 1000:

void setup() {
  REG_PIOD_OWER = 0xFFFFFFFF;     // Enable writes to whole of PortD's 32-bit, Output Data Status (ODSR) register: (B11111111111111111111111111111111)
  REG_PIOD_OER =  0x0000000F;     // Set the lowest 4-bits of PortD to outputs: (B00000000000000000000000000001111)
}

void loop() {   
  // Using the register definition: REG_PIOD_ODSR, could also use pointer to register contents: PORTD->PIO_ODSR
  REG_PIOD_ODSR = PIO_ODSR_P0;   // Set the output on P0 (digital pin 25) high, other outputs low: (B00000000000000000000000000000001)
  REG_PIOD_ODSR = PIO_ODSR_P1;   // Set the output on P1 (digital pin 26) high, other outputs low: (B00000000000000000000000000000010)
  REG_PIOD_ODSR = PIO_ODSR_P2;   // Set the output on P2 (digital pin 27) high, other outputs low: (B00000000000000000000000000000100)
  REG_PIOD_ODSR = PIO_ODSR_P3;   // Set the output on P3 (digital pin 28) high, other outputs low: (B00000000000000000000000000001000)
}

DSAFS2016: Hi All,

Having trouble working out how to manipulate Arduino Due ports, as they go higher than 8bit, so couldn't workout if there was a different way of dealing with that.

Looking at the Schematic of the Arduino Due, Port C has 31 pins (with bits 0-30). I have attached LEDs from pins 44-51 (bits 12 - 19 on Port C).

I want to manipulate them, so when a variable increases in number, it changes which LED is on. Currently I have...

     if (Variable == 0)
     {
      PORTC = B0000000000000000000000000000000;  //way of writing 1...
     }
     else if (Variable == 1)
     {
      PORTC = 0x0C;  //way of writing 2...
     }
     else if (Variable == 2)
     {
      PORTC = 0x0D;
     }
     //ETC... there are 8 LED's in total...

The problem I have is that there are potentially other components using pins on PORTC and I do not wish to influence them, just bits 12 - 19. How would I go about that?

Could I write something like:

PORTC = BXXXXXXXXXXXX00000100XXXXXXXXXXXX; //The X indicating leave that bit alone

or

PORTC 12-19 = B00000100;

Cheers!

Hello DSAFS2016,

Look at my post (#1) here for Arduino Due port manipulation example. http://forum.arduino.cc/index.php?topic=385385.msg2656310#msg2656310

Regards,

-p

The issue with using the SAM3X8E's set (SODR) and clear (CODR) data registers, is that they don't allow you to output a binary sequence in one write operation. You either have to set then clear, or clear then set.

Writing to the Output Data Status Register (ODSR), allows the Due to revert back to how the AVR microcontrollers' PORTx registers work, except that the ports are 32-bit. Provided the port pins are set as outputs, any binary sequence (containing 0s or 1s) written to this register, is output on the port in one write operation.