2019-06-12 08:35 AM
Hi guys,
Is it possible to read multiple gpio simultaneously? See part of my code below.
Thanks
while (1)
{
if ( (HAL_GPIO_ReadPin(IN_1_GPIO_Port, IN_1_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_2_GPIO_Port, IN_2_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_3_GPIO_Port, IN_3_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_4_GPIO_Port, IN_4_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_5_GPIO_Port, IN_5_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_6_GPIO_Port, IN_6_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_7_GPIO_Port, IN_7_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_8_GPIO_Port, IN_8_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_9_GPIO_Port, IN_9_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_10_GPIO_Port, IN_10_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_11_GPIO_Port, IN_11_Pin) == GPIO_PIN_SET)
|| (HAL_GPIO_ReadPin(IN_12_GPIO_Port, IN_12_Pin) == GPIO_PIN_SET))
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
}
else
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
}
...
Solved! Go to Solution.
2019-06-12 09:04 AM
Don't do like this. It will be very inefficient and possiblly generate more code to execute than needed.
GPIO registers are 16 bit wide, so PA0..PA15 bits are packed in a single register you can read in 1 shot.
GPIO input register is volatile, it changes over time from external events. take a snapshot, read the register once, put in a local variable then bit mask.
Don't re-rename things, you will make understanding of your code more indirect in a dialect code only you will understand.
Make your code intuitive with minimum dependency.
Digging the code, say you want to check if PA0, PA2, PA5, PA9 any one of these pin to be high level:
if(GPIO->IDR & 0b1000100101)
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
}
else
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
}
If the pins are from differnet ports, group them by port name. There maybe a HAL function to wrap read IDR, don't remember...
2019-06-12 08:58 AM
uint16_t foo = GPIOD->IDR; // bit 0 thru 15 reflect PD0 thru PD15
2019-06-12 09:04 AM
Don't do like this. It will be very inefficient and possiblly generate more code to execute than needed.
GPIO registers are 16 bit wide, so PA0..PA15 bits are packed in a single register you can read in 1 shot.
GPIO input register is volatile, it changes over time from external events. take a snapshot, read the register once, put in a local variable then bit mask.
Don't re-rename things, you will make understanding of your code more indirect in a dialect code only you will understand.
Make your code intuitive with minimum dependency.
Digging the code, say you want to check if PA0, PA2, PA5, PA9 any one of these pin to be high level:
if(GPIO->IDR & 0b1000100101)
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
}
else
{
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
}
If the pins are from differnet ports, group them by port name. There maybe a HAL function to wrap read IDR, don't remember...
2019-06-12 09:29 AM
In the particular case if you want to check if any pin of a set of pins of the same port is nonzero, you can use
if (HAL_GPIO_ReadPin(THE_COMMON_GPIO_Port, IN_1_Pin | IN_2_Pin | IN_3_Pin | IN_4_Pin) == GPIO_PIN_SET) {
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
} else {
HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
}
although it is not intended by Cube/HAL authors, and I wouldn't recommend this usage.
It will even pass the IS_GPIO_PIN() assertion, given how sloppily is it written.
JW
2019-06-13 12:19 AM
Hi guys,
Thank you all for your help. Your solution makes sense, and works perfectly.
Just to understand why it doesn't work like i thought at first, is it specific to HAL library or my first idea, reading multiple GPIO, was a terrible behaviour (poor code optimisation, etc.)?
Thanks again,
CS.