Go Down

Topic: Is there another way to do a DigitalWrite? (Read 1 time) previous topic - next topic

irethedo

I was wondering if instead of doing several digitalWrite commands to set individual output pin levels
on an Arduino (e.g. digitalWrite(D0, HIGH) - digitalWrite(D7, HIGH)) if there is a way to just write a
byte of data to set all output levels at once.

Also, is there a way to set all of the pinModes at once also... (like writing a value to a register for example)

thanks


wildbill

You can, as Udo Klein's link demonstrates, but unless you really need the speed or to save memory, why do you want to? Generally, code that doesn't use port manipulation is easier to read.

CrossRoads

"Generally, code that doesn't use port manipulation is easier to read."
Especially when there no comments explaining what is going in.

For example:
Code: [Select]

PORTD = PORTD & B11110111;
SPI.transfer(0x03);
SPI.transfer(0xF0);
PORTD = PRTD | B00001000;

vs
Code: [Select]

PORTD = PORTD & B11110111; // clear bit 3 (D4, as an example) to enable device X slave select
SPI.transfer(0x03);                  // send out address byte
SPI.transfer(0x03);                  // send out data byte
PORTD = PRTD | B00001000;    // set bit 3 to deselect device X

In the real world, comments like these ensure fixability by any member of the software team.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

robtillaart

meaningful names instead of constants do help too  - borrowing the code of CrossRoads

Code: [Select]

// define the magic numbers
#define ENABLE_X_SLAVE  B11110111
#define DISABLE_X_SLAVE B00001000
#define ADDRESS 0x03
...
uint8_t data = 0x03;

PORTD = PORTD & ENABLE_X_SLAVE ;
SPI.transfer(ADDRESS);                 
SPI.transfer(data);                 
PORTD = PORTD | DISABLE_X_SLAVE ;   

Good variable names can minimize the amount of comment you need to write,
the biggest benefit of that is that it is far easier to keep comments and code in sync (especially when there are no comments left ;)

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

dhenry

Quote
if there is a way to just write a
byte of data to set all output levels at once.


Yes, if those pins are on the same port.

CrossRoads

Commamds like

PORTD = some_value;
PORTC = some_value;
PORTB = some_value;

writes all the bits at the same time, if you have used pinMode ahead of that to set the pins as OUTPUT.
Not all port2 have 8 bit on an Uno.
And some might be in use as another function, such as Rx/Tx. So you have to pay a little attention when doing that.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

irethedo

I have another bit of code that is getting a compile error on the following line:

        PORTA = (PORTA ^ B00000001);

with a 'PORTA' was not declared in  this scope ' error.

I am using an atmel chip with the Uno bootloader and if I change the board type to a mega, it compiles without error.

How can I set this up to load on my Uno without an error?

thanks

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

retrolefty


I have another bit of code that is getting a compile error on the following line:

        PORTA = (PORTA ^ B00000001);

with a 'PORTA' was not declared in  this scope ' error.

I am using an atmel chip with the Uno bootloader and if I change the board type to a mega, it compiles without error.

How can I set this up to load on my Uno without an error?

thanks



Some arduino boards don't have a PORTA like a Uno, some do like a mega. You might want to review this document to understand the arduino pins Vs port assignments for the basic Uno and Mega boards.
https://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

Lefty

irethedo

Thanks Lefty.

Your answer definitely helped out.

This chip only has a PortB, PortC, & PortD.

Krupski


I was wondering if instead of doing several digitalWrite commands to set individual output pin levels
on an Arduino (e.g. digitalWrite(D0, HIGH) - digitalWrite(D7, HIGH)) if there is a way to just write a
byte of data to set all output levels at once.

Also, is there a way to set all of the pinModes at once also... (like writing a value to a register for example)

thanks


Sure. You can find out what port name and bit numbers are used on your particular board and program them directly.

For example, an an Arduino UNO:

Code: [Select]
pinMode(8, INPUT) == DDRB &= ~_BV(0)
pinMode(8, OUTPUT) == DDRB |= _BV(0)
digitalWrite(8, HIGH) == PORTB |= _BV(0)
digitalWrite(8, LOW) == PORTB &= ~_BV(0)
x = digitalRead(8) == x = PINB & _BV(0) ? 1 : 0

Set pinmode of pins 7 through 0 as outputs in one shot:
DDRD = 0b11111111;

As all inputs:
DDRD = 0b00000000;

Bits 0...3 as input, 4...7 as outputs:
DDRD = 0 | _BV(4) | _BV(5) | _BV(6) | _BV(7);
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Go Up