cancel
Showing results for 
Search instead for 
Did you mean: 

F446 Bitwise operator MODER & PUPDR

HMSEdinburge
Associate II

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
}

 

13 REPLIES 13
Ozone
Principal

These bits are quite comprehensively explained in the reference manual :

Ozone_0-1747200877967.png

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:

Ozone_1-1747201014174.png

 



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? 

> 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 :

Ozone_0-1747208036801.png


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.

 

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?? 

 

> ...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.

 

@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.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

Great! to use  #include "stm32f4xx_hal.h" ... 

<< 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... 


@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

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.