Tri-State

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I saw the code below, when i downloaded a library for a DOGM lcd screen:

 

  // Set SPI-Mode 3: CLK idle high, rising edge, MSB first    
  digitalWrite(p_clk, HIGH); //SCK = p_clk = Pin13 = PB5
  pinMode(p_clk, OUTPUT);

 The mcu uses SPI to send signals to the LCD. Why first give 5V to the pin(aka activate its pull-up), and then declare it as output? Isn't it the same if these two lines switched sides?

In the end, the pin will be output, giving 5V, and the pull-up resistor won't be activated.

 

I think this has something to do with the SPI library/ the way the SPI works, or something about tri-state function of the pins i do not know, like will the pull-up resistor still be activated after this code?.

 

Thanks

This topic has a solution.
Last Edited: Wed. Nov 13, 2019 - 12:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like Arduino code - so should be in the Arduino forum?

 

Does pinMode(x, OUTPUT) default to setting the pin low?

 

https://www.arduino.cc/en/Reference.PinMode  or the linked https://www.arduino.cc/reference/en/language/variables/constants/constants/ doesn't say

 

EDIT

 

Neither does the linked  https://www.arduino.cc/en/Tutorial/DigitalPins

 

EDIT 2

 

https://github.com/arduino/Ardui... suggests that pinMode(x, OUTPUT) does default to setting the pin low on an AVR ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Nov 8, 2019 - 01:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's no mystery about pinMode() or any of the Arduino code. All the source is open:

 

https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring_digital.c#L29

 

void pinMode(uint8_t pin, uint8_t mode)
{
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	volatile uint8_t *reg, *out;

	if (port == NOT_A_PIN) return;

	// JWS: can I let the optimizer do this?
	reg = portModeRegister(port);
	out = portOutputRegister(port);

	if (mode == INPUT) {
		uint8_t oldSREG = SREG;
                cli();
		*reg &= ~bit;
		*out &= ~bit;
		SREG = oldSREG;
	} else if (mode == INPUT_PULLUP) {
		uint8_t oldSREG = SREG;
                cli();
		*reg &= ~bit;
		*out |= bit;
		SREG = oldSREG;
	} else {
		uint8_t oldSREG = SREG;
                cli();
		*reg |= bit;
		SREG = oldSREG;
	}
}

 

So apart from all the pin number dereferencing stuff this is little more than DDR = (1 << n) for the "OUTPUT" case. (for INPUT/INPUT_PULL_UP it does write to both DDR and PORT which it calls, respectively, "reg" and "out")

 

So for the OUTPUT case this just inherits what is already in PORT.

 

The code posted in #1 does strike me as a little odd. Most code will set directions (and pull-ups if required) once in a setup phase and then only change the output state ongoing.

 

EDIT: just for completeness the code OP quotes in #1 lives here:

 

https://github.com/Saij/DOGL_Sample/blob/master/DOG_7565R/dog_7565R.cpp#L307

 

actually around line 332 in that function. The variables it is accessing (p_cs etc) are class members here:

 

https://github.com/Saij/DOGL_Sample/blob/master/DOG_7565R/dog_7565R.h#L38

Last Edited: Fri. Nov 8, 2019 - 01:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not interested in digging into Arduino source code!

 

You shouldn't have to go reverse-engineering the source code to answer basic questions like this - it should be clearly documented.

 

Especially considering the target audience of Arduino.

 

So for the OUTPUT case this just inherits what is already in PORT

Would that be zero if the port has not previously been used?

 

That seems to what the Github discussion was saying...

 

EDIT

 

I guess the OP code is just being "safe" and making sure that the PORT is in the required state before it enables the output ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Nov 8, 2019 - 03:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You shouldn't have to go reverse-engineering the source code to answer basic questions like this

The bane of developing software

....sort of like studying the compiler output to make sure it is doing what you want ,the way you expect it  (using cbi, sbi, grabbing high byte when dividing by 256, etc)

 

Too much back seat driving is inefficient.  Too little, and you end up in a ditch.   

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. I did not posted this on Arduino forum, because i took the Arduino library for the DOGM and converted it into AVR-C, to match the mcu i am using.

I changed those two lines i am referring to, into:
 

  PORTB |= (1 << PORTB5);
  DDRB |= (1 << DDB5);

And the library still works.
I mean, @ clawson  is right, it is just  DDR = (1 << n). But why are these the other way around?

 

I guess the OP code is just being "safe" and making sure that the PORT is in the required state before it enables the output ... ?
 

Maybe, thats what these lines are about i guess.
 

Ahh i will just put them the right way and will see if the lcd will work. If it does, there is no more reason for researching.

Thanks. 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Setting the pin high before making it an output ensures that it will be high logic (as a result of the pull-up resistor being on) when made an output.   There will be no low-logic glitch or quick low-level spike if the pin had previously been placed in logic low before being made an output.

Last Edited: Fri. Nov 8, 2019 - 11:53 PM