GPIO acts the opposite of what it supposed to

Status
Not open for further replies.

yefj

Advanced Member level 5
Joined
Sep 12, 2019
Messages
1,505
Helped
1
Reputation
2
Reaction score
5
Trophy points
38
Activity points
9,114
Hello,I had a phenomena where when i defined my LED they turned on by defualt as starting point.
I didnt want that, so i made sure the OUT in the GPIO_PinModeSet(LED_PORT_E,15,gpioModePushPull,0) is zero.
But the opposite happened and it turned them on by default.
When i made out=1 it turned it off on starting point,but when i did GPIO_PinOutSet(LED_PORT_E,15); it actualy turned off the LED instead of turning on.
the same thing happaned with
Code:
GPIO_PinOutClear(LED_PORT_E,15);
It turned on the led instead of turning it off.I tried to look at the GPIO API shown bellow.
Why it has this opposite behavior when i do in GPIO pinmodeset out=1?
The full code is shown bellow.
Thanks.

Code:
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_chip.h"

#include <stdint.h>
#include <stdbool.h>
#include "em_emu.h"
#include "bsp.h"
#include "bsp_trace.h"
#define LED_PORT_E    gpioPortE
#define LED_PIN_E     15

#define LED_PORT_A    gpioPortA
#define LED_PIN_A     15



#define BUFFER_SIZE 1
char buffer[BUFFER_SIZE];

volatile uint32_t msTicks; /* counts 1ms timeTicks */

void Delay(uint32_t dlyTicks);
void SysTick_Handler(void)
{
  msTicks++;       /* increment counter necessary in Delay()*/
}
void Delay(uint32_t dlyTicks)
{
  uint32_t curTicks;

  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks) ;
}

int main(void)
{

  // Chip errata
  CHIP_Init();

  // Enable oscillator to GPIO and USART1 modules
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART1, true);

// BSP_TraceProfilerSetup();

    /* Setup SysTick Timer for 1 msec interrupts  */
    if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) {
      while (1) ;
    }

    /* Initialize LED driver */



    GPIO_PinModeSet(LED_PORT_E,15,gpioModePushPull,1);
    GPIO_PinModeSet(LED_PORT_A,15,gpioModePushPull,1);

  // set pin modes for UART TX and RX pins
  GPIO_PinModeSet(gpioPortC, 1, gpioModeInput, 0);
  GPIO_PinModeSet(gpioPortC, 0, gpioModePushPull, 1);
  USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
  USART_InitAsync(USART1, &init);
  USART1->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN;



  while (1)
  {

//E-green
//A-red

      switch ( USART_Rx(USART1))
      {
           case 'g':

               GPIO_PinOutSet(LED_PORT_E,15);
              USART_Tx(USART1,'D');USART_Tx(USART1,'O');USART_Tx(USART1,'N');USART_Tx(USART1,'E');USART_Tx(USART1,'\n');
              break;
           case 'h':
              GPIO_PinOutClear(LED_PORT_E,15);
              USART_Tx(USART1,'D');USART_Tx(USART1,'O');USART_Tx(USART1,'N');USART_Tx(USART1,'E');USART_Tx(USART1,'\n');
          break;
           case 'r':

               GPIO_PinOutSet(LED_PORT_A,15);
                       USART_Tx(USART1,'D');USART_Tx(USART1,'O');USART_Tx(USART1,'N');USART_Tx(USART1,'E');USART_Tx(USART1,'\n');
           break;
           case 't':
               GPIO_PinOutSet(LED_PORT_A,15);
              GPIO_PinOutClear(LED_PORT_A,15);
                                 USART_Tx(USART1,'D');USART_Tx(USART1,'O');USART_Tx(USART1,'N');USART_Tx(USART1,'E');USART_Tx(USART1,'\n');
            break;

           default:
               USART_Tx(USART1,'N');USART_Tx(USART1,'O');USART_Tx(USART1,'N');USART_Tx(USART1,'E');USART_Tx(USART1,'\n');
               break;
         
      }//end switch
  }
}
 

Please provide the microprocessor you are using. On a PIC MCU, you need to set the TRIS register first and then to update the PORT. Its possible your circuit is holding the pin or you are using the wrong values for on and off. Please check the datasheet.

Normally LOW = 0, HIGH = 1. The TRIS has to be set as output for the pin, on a PIC MCU Output = 0, Input = 1.
 

    yefj

    Points: 2
    Helpful Answer Positive Rating
Is your LED connected via resistor to ground, or to supply +ve?

If the latter, then that would explain the behaviour that you see.
 

    yefj

    Points: 2
    Helpful Answer Positive Rating
my controller is EFM32LG , i have tried to look into the data sheet in the GPIO section on page 141.
but i could not see the relevant thing.
Where should i look?Also i have attached my LED connection in the schematics.
Thanks.


 

Hi,

you are operating your GPIO pins as push-pull outputs. Thus they can sink AND source current. By sourcing a current the GPIO pin voltage is HIGH e.g. 1.8 V, 3.3 V or 5 V depending on your MCU supply voltage.

So if you define the GPIO output level HIGH, the same voltage (Vcc) is applied to the anode and cathode of your LED . As there is no voltage difference, no current flows. By pulling the GPIO pin LOW (0 V), a voltage difference is applied across your LED and it lights up.

BR
 

    yefj

    Points: 2
    Helpful Answer Positive Rating
Your schematic indicates that a low output (0) will light each LED and a high output (1) will extinguish each LED.

Results are exactly as would be expected.
 

    yefj

    Points: 2
    Helpful Answer Positive Rating
There are some concepts that are only learned with a lot of practice which we should make clear first.

From page 16, 3.1.31 General Purpose Input/Output (GPIO) we see some of the options for the pins.
There is a difference between a pin set as input and a pin set as output. An input pin can be low and high, an output pin can be low and high. In your case you must set the pins as output. When you want the LED to be on you must set the pin as output low, when the LED is off, the pin is output high. LEDs only allow current in 1 direction, from the anode towards the cathode, or from the + to the -. In your case you are probably using a multimer to check the pin state, the multimeter is showing the voltage comming from VCC through the LEDs, but it creates a connection to ground.

The application note gives additional information on how to set the pins as output high or output low.

At the initialization of the MCU, all pins are set to their default values. If by default the pin is output, it will be an output on power on and reset. This is fixed by a pull down resistor to ground, which should fix your problem. However it also creates a connection to ground and will use electricity. 10kR should be too much and the LED should not be light.

After you add the pulldowns(you can try with pullups). You can set the pin as output low, which will turn on 1 of the LEDs. Then try switching a few times.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…