2025-05-13 7:34 PM
Hello.. i m programming F446 using registers, and i found from F446 reference manual to configure PA1 as both input and pull-down mode. i don't understand , can anyone advise how could
1. MODER &= ~(3<<2) is to set MODER1 as 00 input?
2. PUPDR |= (1<<3); is to set as 10 pull-down mode?? isn't that mean bit 3 set to '1' ??
GPIOA->MODER &= ~(3<<2); // 7.4.1 Bits (3:2) = 0:0 --> PA1 in Input Mode
GPIOA->PUPDR |= (1<<3); // 7.4.4 Bits (3:2) = 1:0 --> PA1 is in Pull Down mode
}
2025-05-13 10:37 PM
These bits are quite comprehensively explained in the reference manual :
This example is for a similiar MCU (the F4x5/F4x7).
And second, I would highly recommend to use the constants defined in stm32f4xx.h, not magic numbers.
Like here:
2025-05-13 11:24 PM
yes, i know this as i read the rm of F446.. My question is how the bitwise operator shift left 2 from 3 ended up as selecting 00 as input for MODER1? and shift left 3 from 1 ended up as selecting 10 for PUPDR ??
1. MODER &= ~(3<<2) is to set MODER1 as 00 input?
2. PUPDR |= (1<<3); is to set as 10 pull-down mode?? isn't that mean bit 3 set to '1' ??
Anyone can kindly advise?
2025-05-14 12:41 AM
> 1. MODER &= ~(3<<2) is to set MODER1 as 00 input?
If you look at the RefManual description, two adjacent bits define the state of each GPIO.
Bits 0 & 1 for pin 0 (e.g. PA0), bits 2 & 3 for pin 1 (e.g. PA1), and so on ...
And the '~' operator clears those bits, thus they are reset to zero - which mean "input" according to the RefManual.
Thus this instruction sets PA1 to inputs.
The same goes for pull-up/pull-down settings :
Such reference manuals are quite dense, information-wise.
One needs to get used to read them.
Had the author (not you, I guess), used something like this, it would have been more clear:
MODER &= ~GPIO_MODER_MODER1
Even if it's your own code, you forget those details after a few weeks, and you will have a hard time decoding the number magick.
Speaking names and constants have definitely advantages.
2025-05-14 5:49 AM
Hi Ozone, thanks for the reply, this project that i m working on requires pure register programming, no HAL at all.
i can understand if you say (3<<2) refers to bit 2 to 3 and reset &~ to zero, that simply implies 00 i.e. input as you mention above.
but what about part2, does it means (1<<3) refer to bit 1 to 3 ? Which is not correct here...
2. PUPDR |= (1<<3);
anyone out there can advise??
2025-05-14 6:22 AM
> ...this project that i m working on requires pure register programming, no HAL at all.
What I suggested was to use the defines of the system header, which are purely constants. Nothing HAL yet.
And these headers I suggested do not imply HAL.
Here the relevant section from stm32f4xx.h:
#if defined (USE_HAL_DRIVER)
#include "stm32f4xx_hal.h"
#endif /* USE_HAL_DRIVER */
So, just don't define "USE_HAL_DRIVER", and no HAL code or headers are pulled in.
But you need to define your MCU variant in more detail, stm32f4xx.h will include a header for the respective specific variant. For e.g. the STM32F407, define "STM32F407xx" in your project settings (or make file), and it will pull in stm32f407xx.h.
These headers are found in ../STM32Cube_FW_F4_xxx/Drivers/CMSIS/Device/ST/STM32F4xx/Include/.
I suggest to browse briefly through these headers, and try to understand their structure.
> but what about part2, does it means (1<<3) refer to bit 1 to 3 ? Which is not correct here...
Similiar as the first one.
"(1<<3)" results in b1000 (0x20), setting the MSB of the two config bits for PA1.
And "10" (see second screenshot, PUPDR) is defined as pull-down.
This examples should get you started, I hope.
2025-05-14 6:43 AM
@HMSEdinburge wrote:i can understand if you say (3<<2) refers to bit 2 to 3 and reset &~ to zero, that simply implies 00 i.e. input as you mention above.
but what about part2, does it means (1<<3) refer to bit 1 to 3 ? Which is not correct here...
2. PUPDR |= (1<<3);
<< is the left shift operator. 1<<3 is a 1 shifted to bit 3 so 0b1000.
2025-05-14 7:04 AM
Great! to use #include "stm32f4xx_hal.h" ...
2025-05-14 7:09 AM
<< is the left shift operator. 1<<3 is a 1 shifted to bit 3 so 0b1000.
ok it sound correct, but how u relate 0b1000 to (10 : pull-down)? your 0b1000 has 4 bits, but reference manual only 2 bits i.e. 00--> no pull-up/ pull down, 01 --> pull up, 11 --> reserved and 10 --> pull-down
Please advise...
2025-05-14 7:43 AM
@HMSEdinburge wrote:your 0b1000 has 4 bits, but reference manual only 2 bits
No. Registers are 32-bit.
1<<3 is the same as 2<<2, so the value 2 in bits 2 and 3