cancel
Showing results for 
Search instead for 
Did you mean: 

Use of the same port both input and output

fenice-6
Associate II
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?
8 REPLIES 8
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 Venmo Up vote any posts that you find helpful, it shows what's working..
fenice-6
Associate II
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?

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
Associate II
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
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 Venmo Up vote any posts that you find helpful, it shows what's working..
RomainR.
ST Employee
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
Associate II
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??
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 Venmo Up vote any posts that you find helpful, it shows what's working..