5

I am using an STM32F4 discovery board and my intention is to set one of its GPIO pins at high impedance, which I have done as below:

GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;

From my understanding, in order to configure a pin at high impedance, it's mode is to be input. Am I right?

If I read the status of this pin, I get a value of 1. I am not sure if the pins at high impedance should return a 1 or 0. Could someone please help me understanding this.

smyslov
  • 185
  • 1
  • 2
  • 8
  • Is the pin connected to anything? – Roger Rowland Oct 28 '15 at 07:50
  • I have a transceiver connected to my discovery board. But even if I remove this and read the pin status, it still returns a 1. However another pin configured with the same configuration returns a 0 which surprises me. – smyslov Oct 28 '15 at 07:55
  • When I try flashing the same program on another board, it returns a 0. Does it mean that my board has an issue? @RogerRowland – smyslov Oct 28 '15 at 08:00
  • 2
    I'm not very familiar with the STM32F4 family, but a digital input pin that is left floating (unconnected) will typically act like a tiny antenna. It may swing high or low due to some localized static field nearby. Even putting your hand nearby may change the value. The important thing is if you ground the pin it reads 0 and if you pull it up to VCC, it reads 1. – Dan Laks Oct 28 '15 at 08:24
  • If I were to configure a pin to have high impedance, is the configuration that I have used right @DanLaks? – smyslov Oct 28 '15 at 08:32
  • Configuring an *unconnected* pin as high impedance [is a bad idea](http://electronics.stackexchange.com/q/7179/29811). – CL. Oct 28 '15 at 08:45

1 Answers1

7

You have configured your pin correctly. The pin is in high impedance mode and will just have the leakage current as input current (in the order of microamperes).

Reading the value of the pin will give you the logical value of the voltage applied to the pin. The voltage levels which correspond to a 0 or 1 are available in the devices datasheet.


For example for the STM32F401 a voltage of up to (maximum) 0.35*VDD-0.04 V will be considered low or 0.

A voltage of at least 0.4*VDD is considered high or 1.

So if you supply your device with 3.3V everything on the pin up to 1.115 V will be considered a 0 and everything over 1.32 V will be considered a 1.

However, to prevent the pin to toggle rapidly between the two states there is a hysteresis of 0.45*VDD+0.3 V. So in order to switch between the two states you need a larger voltage change than just the difference between 1.115 V and 1.32 V.


Now if you have an unconnected pin and read the value of the input register, the value is basically undefined. It could be either 0 or 1 depending on a lot of factors, adjacent pin voltages, EMI and others.

The pin and connected track basically act as an antenna. Thus it picks up all sorts of signals and as only a tiny charge is required to bring the voltage from 0 levels to 1 levels it will switch between them readily. This is dependent on the capacitance of the track and pin, without added capacitors it is in the range of some picofarads, which can easily be charged and influenced.

This makes your controller susceptible for external disturbances. This can lead to erratic behaviour in case of strong EMI (hold a calling mobile phone near your microcontroller), some devices react a lot more sensitive so even waving your hand over it might disturb it.

Because of that it is considered a best practice to have some form of active drive on each input pin. Either the external circuit makes sure that it has a defined level all the time, or a pull-up or pull-down resistor is used. Most microcontrollers have built-in resistors, so external components are not necessary.

To enable the pull-up or pull-down resistor on a pin, you can use the GPIO_InitStruct.Pull. Set it to GPIO_PULLUP or GPIO_PULLDOWN respectively. Which one is the correct one depends on your application, typically if you are waiting for a high signal you would enable the pull-down to make sure you don't get an accidental high signal. This would also provide a reliable reading if the pin is not connected.

Unused pins can also be configured as output if left unconnected to prevent the bad effects.

Note: If you want to make a pluggable design you should think about additional ESD protection for the pin.

Arsenal
  • 17,464
  • 1
  • 32
  • 59
  • Maybe add a bit more, after "Most microcontrollers have built-in resistors, so external components are not necessary." to be explicit? E.g. "Hence, you could configure that input pin to be pulled-up or pulled-down, which ever is convenient, by programming that part of the `GPIO_InitStruct` structure. That would remove a potential problem, and ensure it reads a consistent value." – gbulmer Oct 28 '15 at 12:11
  • @gbulmer done, not with your wording, but hopefully fine as well. – Arsenal Oct 28 '15 at 12:27
  • That's good! +1 Hopefully the OP's problem is solved, or they can explain any other constraints/issues. – gbulmer Oct 28 '15 at 12:38