cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405 - Change GPIO Direction Dynamically.

aadityadengle
Associate II
Posted on January 15, 2015 at 14:38

Hi,

Consider me a newbie in ARM. For last few days I am trying to control a set of GPIO pins dynamically. What I want to do is, to change the direction (Input to output or output to input),of the GPIO dynamically i.e. on the fly. All this is require to establish a 8 bit parallel bus to communicate with other hardware I have. I am using CoIDE, and dont want to use FSMC. Following is what I have done till now.


typedef 
enum
{

Data_INPUT,

Data_OUTPUT

}Data_Direction;


.

.

.

.

.


void
DataDirection(Data_Direction dtDirect){

switch
(dtDirect) {

DATA_PORT->BSRRH =DATA_BUS;

DATA_PORT->ODR = DATA_PORT->ODR & 0xffff0000;


case
Data_INPUT:

DATA_PORT->MODER = (DATA_PORT->MODER & 0xffff0000);

DATA_PORT->PUPDR = (DATA_PORT->PUPDR & 0xffff0000);

DATA_PORT->OTYPER =(DATA_PORT->OTYPER & 0xffffff00);

DATA_PORT->OSPEEDR = (DATA_PORT->OSPEEDR & 0xffff0000) | (uint16_t) 0xAAAA;

Delay(100);

break
;

case
Data_OUTPUT:

DATA_PORT->MODER = (DATA_PORT->MODER & 0xffff0000) | (uint16_t) 0x5555;

DATA_PORT->OTYPER =(DATA_PORT->OTYPER & 0xffffff00);

DATA_PORT->OSPEEDR =(DATA_PORT->OSPEEDR & 0xffff0000) | (uint16_t) 0xAAAA;

DATA_PORT->PUPDR = (DATA_PORT->PUPDR & 0xffff0000)|(uint16_t) 0x5555;

Delay(100);

break
;

}


.

.

.

.

.

I have to configure PortC's first 8 pins in this manner, remaining of it will always have output configuration and will not change dynamically. As a result of the the above code I have observed that when I shift the pins direction from Output to Input, the pin state is not getting low or in other words I cant read the pins for their true value. Please let me know how to implement the 8 bit dynamic parallel bus over GPIO.
1 REPLY 1
Danish1
Lead II
Posted on January 15, 2015 at 17:13

In your switch statement, under what circumstances are lines 14 and 15 executed?

I'm not sure you understand the action of port->BSRR.

What it actually does is a read-modify-write of port->ODR, setting any bits specified by the low 16 bits of what you write to BSRR and clearing any bits that are specified by the high 16 bits of what you write to BSRR. All the bits change at the same time and (more importantly) things don't get confused if there happens to be an interrupt between the read and the write of the type of code generated by line 15, even if the interrupt modifies ODR.

I don't like your use of constants such as 0xAAAA because I never remember what they mean (I think fast speed).

For output, you shouldn't need to set PUPDR unless your output is open-drain (line 28). I'd just leave it as all bits clear if that's what you want when in input mode.

What do you mean by pin state not getting low?

Do you mean the voltage on the pin, as measured by a voltmeter? If you are not driving the pin then it will remain at the voltage it was, unless driven by something else, or pulled low by a resistor (or e.g. the effective resistance of your voltmeter).

Or do you mean what appears in ODR? Because you have to read port->IDR not ODR.

Hope this helps,

Danish