Pages: [1]   Go Down
Author Topic: Is there another way to do a DigitalWrite?  (Read 838 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 74
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3470
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.arduino.cc/playground/Learning/PortManipulation
Logged

Check out my experiments http://blog.blinkenlight.net

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 524
Posts: 26440
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

"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:
PORTD = PORTD & B11110111;
SPI.transfer(0x03);
SPI.transfer(0xF0);
PORTD = PRTD | B00001000;
vs
Code:
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.
Logged

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.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
// 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 smiley-wink

Logged

Rob Tillaart

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

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 524
Posts: 26440
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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.

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 74
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

please post the whole code.
Logged

Rob Tillaart

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

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 74
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Lefty.

Your answer definitely helped out.

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

Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 792
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Pages: [1]   Go Up
Jump to: