Skip to main content
fenice-6
Associate II
August 6, 2015
Question

Use of the same port both input and output

  • August 6, 2015
  • 8 replies
  • 2904 views
Posted on August 06, 2015 at 13:19

Hello,

I need use a port both input and output. What should I do? Should I use something like this?

GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

Can I use GPIO_ReadInputData, GPIO_SetBits and GPIO_ResetBits now?
    This topic has been closed for replies.

    8 replies

    Tesla DeLorean
    Guru
    August 6, 2015
    Posted on August 06, 2015 at 14:22

    Well that would configure a pin for a peripheral, allowing for a push-pull driver.

    If you require a GPIO in push-pull mode, then it will only output until your reconfigure it as an input. If you use open-drain mode you can set the output high, and then be able to see if an external pin is driving it.

    Think a little about what you're interfacing too, and what the requirements are, and then think about the types of pin-driver you need.

    Look at the Reference Manual, and how to configure the GPIO registers, as using GPIO_Init() to turn the bus around isn't going to be very efficient.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    fenice-6
    fenice-6Author
    Associate II
    August 6, 2015
    Posted on August 06, 2015 at 17:22

    How can I change dynamically pin direction? ie input to output or output to input

    Should I initialize, deinitialize and reinitialize the port every time?

    craig239955_stm1_stmicro
    Associate
    August 6, 2015
    Posted on August 06, 2015 at 17:43

    lapiana,

    if you are using this to do something like bit bang out an SPI, I2C or dallas 1-wire you can use the same pin for I/O without toggling.  The input register will read the actual state of the input pin, not just the output register.  So configure the pin as open drain and with the pull-up resistor enabled if desired.  then just write to the pin.

    https://youtu.be/UR_cAvNjUZc

    fenice-6
    fenice-6Author
    Associate II
    August 10, 2015
    Posted on August 10, 2015 at 19:33

    I'm trying to use anHitachi 3 Axis AccelerometerH48C and I can only use a DIO port. I really only need to change an input port to output port and vice-versa.

    This is my code:

    void Pin_Mode(int direction, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    if (direction==INPUT)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    else
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
    }

    but it doesn't work. Can you give me an help?

    ________________

    Attachments :

    HitachiH48C3AxisAccelerometer-27464.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0aQ&d=%2Fa%2F0X0000000bao%2FxVLX_yO6p1KYmueYnqMdYnkD8HAJKwtN.sPA7VJgjqA&asPdf=false
    Tesla DeLorean
    Guru
    August 11, 2015
    Posted on August 11, 2015 at 04:35

    Doesn't look unreasonable.

    How isn't it working? Does it not Tri-State the pin?

    The protocol looks to involve sending 5 bits, clocking each out, and then setting the pin to input and clocking in 13 bits of data.

    You're going to need some routines to Initialize the CS, CLK, DIO pins as outputs. Drive the CS low, Drive a data output, Cycle the Clock High/Low as required, Change the data pin to input, Read the input, and Drive the CS high.

    Maybe you can present the framework as you have it now, so I can understand the pins you're using and I don't have to build an example from scratch.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    RomainR.
    ST Employee
    August 11, 2015
    Posted on August 11, 2015 at 11:49

    but it doesn't work. Can you give me an help?

    Could you try this:

    void
    Pin_Mode(
    int
    direction, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){ 
    GPIO_InitTypeDef GPIO_InitStructure; 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin; 
    /* Enable Clock for GPIO Peripheral */
    RCC_AHBxPeriphClockCmd(RCC_AHB2Periph_GPIOy, ENABLE); 
    // x & y must be replaced according RM of your device 
    GPIO_DeInit(GPIOy); 
    /* fill GPIO struct with default setting */
    GPIO_StructInit(&GPIO_InitStructure); 
    // very Important ! 
    if
    (direction==INPUT){ 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
    } 
    else
    { 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
    } 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOx, &GPIO_InitStructure); 
    }

    To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
    fenice-6
    fenice-6Author
    Associate II
    August 11, 2015
    Posted on August 11, 2015 at 18:17

    I'm trying to use this:http://playground.arduino.cc/Main/ParallaxH48C

    It works, i used with an other library. Part of my code is:

    #define DIO GPIO_Pin_5
    #define DIO_TYPE GPIOB 
    #define CLK GPIO_Pin_3
    #define CLK_TYPE GPIOB
    #define CS GPIO_Pin_10
    #define CS_TYPE GPIOB
    #define INPUT 1
    #define OUTPUT 0
    #define HIGH 1
    #define LOW 0
    #define xAxis 8
    #define yAxis 9
    #define zAxis 10
    #define vRaf 11
    void Pin_Mode(int direction, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
    /* Enable Clock for GPIO Peripheral */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 
    /* fill GPIO struct with default setting */
    GPIO_StructInit(&GPIO_InitStructure); 
    if (direction==INPUT){
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    }
    else{
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    }
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOx, &GPIO_InitStructure);
    }
    void StartBit(){
    Pin_Mode(OUTPUT,DIO_TYPE,DIO);
    GPIO_ResetBits(CS_TYPE, CS); // CS LOW
    GPIO_ResetBits(CLK_TYPE, CLK); // CLK LOW
    vTaskDelay((1/1000) / portTICK_PERIOD_MS);//wait 1 micorsecond
    GPIO_SetBits(DIO_TYPE, DIO);// DIO HIGH
    GPIO_SetBits(CLK_TYPE, CLK);// CLK HIGH
    vTaskDelay((1/1000) / portTICK_PERIOD_MS);//wait 1 micorsecond
    }
    void ShiftOutNibble(unsigned char DataOutNibble) {
    for(int i = 3; i >= 0; i--) { // i = 3 ... 2 ... 1 ... 0 
    GPIO_ResetBits(CLK_TYPE, CLK); // CLK LOW
    // set DIO first
    if ((DataOutNibble & (1 << 
    i
    )) == (1 << i)) { // DataOutNibble AND 1 x 2^i Equals 1 x 2^i ?
    GPIO_SetBits(DIO_TYPE, DIO); // DIO HIGH 
    }
    else {
    GPIO_ResetBits(DIO_TYPE, DIO); // DIO LOW
    }
    // with CLK rising edge the chip reads the DIO from arduino in
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH
    // data rate is f_clk 2.0 Mhz --> 0,5 micro seeconds 
    vTaskDelay((1/1000) / portTICK_PERIOD_MS); //wait 1 micorsecond
    }
    }
    void SampleIt(){
    GPIO_ResetBits(CLK_TYPE, CLK); //CLK LOW
    vTaskDelay((1/1000) / portTICK_PERIOD_MS); //wait 1 micorsecond
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH
    vTaskDelay((1/1000) / portTICK_PERIOD_MS); //wait 1 micorsecond
    Pin_Mode(INPUT,DIO_TYPE,DIO);
    GPIO_ResetBits(CLK_TYPE, CLK); // CLK LOW
    vTaskDelay((1/1000) / portTICK_PERIOD_MS); //wait 1 micorsecond
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH
    if (GPIO_ReadInputDataBit(DIO_TYPE,DIO)==LOW) {// Blink LED because ok
    }
    }
    unsigned char ShiftInNibble(){
    unsigned char resultNibble;
    resultNibble = 0;
    for(int i = 3 ; i >= 0; i--) { // from bit 3 to 0
    // The chip Shift out results on falling CLK 
    GPIO_ResetBits(CLK_TYPE, CLK); // CLK LOW
    vTaskDelay((1/1000) / portTICK_PERIOD_MS);//wait 1 micorsecond :-) just nothing 
    if( GPIO_ReadInputDataBit(DIO_TYPE,DIO) == HIGH) { // BIT set or not?
    resultNibble += 1 << i; // Store 1 x 2^i in our ResultNibble
    }
    else {
    resultNibble += 0 << i; // YES this is alway 0, just for symetry ;-)
    }
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH
    vTaskDelay((1/1000) / portTICK_PERIOD_MS); //wait 1 micorsecond :-) just nothing
    }
    return resultNibble;
    }
    void EndBit(){
    GPIO_SetBits(CS_TYPE, CS); // CS HIGH
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH
    }
    int GetValue(unsigned char Command){ // x = B1000, y = B1001, z = B1010
    int Result = 0;
    StartBit();
    ShiftOutNibble(Command);
    SampleIt();
    Result = 2048 - ((ShiftInNibble() << 8) + (ShiftInNibble() << 4) + ShiftInNibble());
    EndBit();
    return Result;
    }
    /* initialization in main*/
    GPIO_InitTypeDef GPIO_InitStructure;
    /* Enable the GPIO_DIO Clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    /* Configure the GPIO_DIO pin */
    GPIO_InitStructure.GPIO_Pin = DIO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DIO_TYPE, &GPIO_InitStructure); 
    /* Configure the GPIO_CLK pin */
    GPIO_InitStructure.GPIO_Pin = CLK;
    GPIO_Init(CLK_TYPE, &GPIO_InitStructure);
    /* Configure the GPIO_CS pin */
    GPIO_InitStructure.GPIO_Pin = CS;
    GPIO_Init(CS_TYPE, &GPIO_InitStructure);
    GPIO_ResetBits(CS_TYPE, CS); // CS LOW
    GPIO_ResetBits(CLK_TYPE, CLK); // CLK LOW
    vTaskDelay((1/1000) / portTICK_PERIOD_MS);//wait 1 micorsecond
    GPIO_SetBits(CS_TYPE, CS); // CS HIGH
    GPIO_SetBits(CLK_TYPE, CLK); // CLK HIGH

    Do you see any particular mistake??
    Tesla DeLorean
    Guru
    August 11, 2015
    Posted on August 11, 2015 at 18:43

    Unfortunately ''not working'' is a bit of a broad term, how exactly is the signalling on the pins different from the ''working'' vs ''not working'' situations? Have you reviewed the differences with a scope or logic analyzer?

    Do you have a data sheet for the actual part, Hitachi's, not Parallax's
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..