How to assign DDRC and PORTC in Arduino code?

image

Hi guys,
I am new in Arduino programming, as shown in the picture, I know DDRC will set pin as output when equals 0xFF and input when equals 0x00, but what does it mean when DDRC is equal to 0x3F, is that acceptable to use other values? Besides, PORTC will toggle between 0xAA and 0x55, which is 170 and 85 in decimal, but why the result is toggling between 42 and 85 in serial monitor?

Welcome to the forum

Your topic was MOVED to its current forum category as it is more suitable than the original as it does not relate specifically to version 2.0 of the IDE

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

Which Arduino board? I am going to assume an UNO.

You do not seem to understand what a PORT is. Each PORT has 8 bits. Each bit represents a PIN. PORTC represents PINS A0 to A5 (on the UNO), implying only 6 bits are used for PORTC. Setting DDRC (PORTC direction) to 0x3F (B00111111) sets all six pins to output.

0xAA = B10101010 and 0x55 = B01010101. Toggling between the two will alternatively toggle all PORTC pins. I would think you should rather toggle between 0x2A and 0x15 since bits 6 and 7 do not represent any I/O pins in PORTC (bit 6 is the RESET pin and will always read back 0. I think bit 7 will also always read back 0).

Hope that helps.

1 Like

Yes. TBC each bit in any DDRx (data direction register) sets, for the corresponding pin on the port, whether that pin is to be used as an input (0s) or output (1s) pin.

You can learn about direct port manipulation, google

 Arduino direct port manipulation 

and poke around. You can also read the code for good old digitalRead and digitslWrite, here's digitslWrite

void digitalWrite(uint8_t pin, uint8_t val)
{
	uint8_t timer = digitalPinToTimer(pin);
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	volatile uint8_t *out;

	if (port == NOT_A_PIN) return;

	// If the pin that support PWM output, we need to turn it off
	// before doing a digital write.
	if (timer != NOT_ON_TIMER) turnOffPWM(timer);

	out = portOutputRegister(port);

	uint8_t oldSREG = SREG;
	cli();

	if (val == LOW) {
		*out &= ~bit;
	} else {
		*out |= bit;
	}

	SREG = oldSREG;
}

The interesting part is

	if (val == LOW) {
		*out &= ~bit;
	} else {
		*out |= bit;
	}

where the bit in the port is either set or cleared but leaving the 7 other bits in the PORTx register unaffected.

HTH

a7

1 Like

Yes, it's Arduino UNO, thanks for your help!

You can write what you what to bit 6 of PORTC and you will read what was written. The value is only overridden by fuses and not visible at the pin when PC6 is used as Reset. Bit 7 always read as 0 which explains why OP reads 42 (0x2A) form PORTC after writing 0xAA. The same is true for DDC6. I am not sure what is read from PINC6 with reset pin enabled. Probably 1 since the pin value is 1.

EDIT: the Datasheet says you are right and PORTC6, PINC6 and DDC6 all should read 0 when external reset is enabled. But that means (PORTC==0x55) should be always false and the PORTC should not change with the code shown in OP. That does not match the description. Do I understand it wrong? Or is there an error in the DS?

1 Like

Yes, I quoted the datasheet on the pin 6 read value. However, as you rightfully state, it does seem as we are getting a 1 from pin 6.

The 85 return implies pin 6 returned a 1. The 42 value is as expected with pin 7 a zero.

1 Like

It seems the DS is really wrong and the PORT and DD values are not masked. However PIN is masked.
Test sketch:

#define testRegister(X) X=0; Serial.print(#X); Serial.print(": 0 -> "); Serial.print(X,HEX); X=0xFF; Serial.print(", 0xFF -> "); Serial.println(X,HEX)

void setup() {
  Serial.begin(115200);
  testRegister(DDRC);
  testRegister(PORTC);
  Serial.print("PINC: ");
  Serial.println(PINC,HEX);  
  testRegister(DDRB);
  testRegister(PORTB);
  Serial.print("PINB: ");
  Serial.println(PINB,HEX);  
}

void loop(){}

Result on Arduino Nano:

DDRC: 0 -> 0, 0xFF -> 7F
PORTC: 0 -> 0, 0xFF -> 7F
PINC: 3F
DDRB: 0 -> 0, 0xFF -> FF
PORTB: 0 -> 0, 0xFF -> FF
PINB: 3F

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.