cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 - common short questions ...

timbo2023
Associate III

Good Evening Ladies and Gentlemen,

 

A short introducing purpose of mine:

 

int main(void)
{
RCC->AHB1ENR |= 0xFC;             // ---> Here I would like to open the Port clock
RCC->APB1ENR |= 0xFC;             // ---> Here I would like to open the USART2 clock - in this context not relevant

GPIOA->MODER |= 0x55555555;       // ---> Here I define Port A as output
GPIOC->MODER |= 0x55555555;       // ---> Here I define Port C as output

GPIOA->ODR |= (1<<2);             // ---> Here I would like to set PA2 "high"

GPIOC->ODR |= (1<<13);            // ---> Here I would like to set the onboard LED (PC13) "high"

while(1) {
GPIOA->ODR |= (1<<0);             // Here I would like to "toggle" PA0 and PA6  
GPIOA->ODR |= (1<<6);
delayMs(50);                      // It only is a not relevant "delay" for this purpose

GPIOA->ODR &= ~(1<<0);
GPIOA->ODR &= ~(1<<6);
delayMs(50);
}
}

 

 

But something went wrong - it does not work - Do you have any suggestions especially regarding a simple "toggling"?

It should be a pre work for a stepper motor controlling.

 

Best regards

~TIMBO~

35 REPLIES 35

RMW is an abbreviation (acronym) from Read-Modify-Write.

For example, if you write

GPIOA->ODR |= (1<<0);

that is a Read-Modify-Write operation, because:

- first, the processor reads in content of GPIOA->ODR register into some of its internal working registers

- then the processor performs the bitwise-OR operation with (1 << 0), that's the modify part

- and finally, processor writes from internal register into GPIOA->ODR the modified value

JW

And that is only possible with a BSRR register?

 

In spite of it - I would like to set A2 and A6 as "high" - and toggle with the ODR register A0.

 

Could you write shortly the mode register setting, too?

 

 

Don't use "A0" etc. It's PA0, PA2 and PA6. "A0" may cause confusion with Arduino-connector signal marking.

For PA0 to be set as output, you have to set bits 0 and 1 of GPIOA_MODER to 0b01.

For PA2 to be set as output, you have to set bits 4 and 5 of GPIOA_MODER to 0b01.

For PA6 to be set as output, you have to set bits 12 and 13 of GPIOA_MODER to 0b01.

You may see a pattern and write macros/functions accordingly.

I recommend to try it without writing any program (maybe an infinite loop), by directly writing to registers in the debugger.

Then, to set pin PA0 high, write 1 into bit 0 of GPIOA_BSRR. This has to be a direct write, not a RMW with OR:

GPIOA->BSRR = (1 << 0);

To set pin PA2 high, write 1 into bit 2 of GPIOA_BSRR:

GPIOA->BSRR = (1 << 2);

To set pin PA6 high, write 1 into bit 6 of GPIOA_BSRR:

GPIOA->BSRR = (1 << 6);

To set pin PA0 to low, write 1 into bit 16 of GPIOA_BSRR:

GPIOA->BSRR = (1 << (0 + 16));

To set pin PA2 to low, write 1 into bit 18 of GPIOA_BSRR:

GPIOA->BSRR = (1 << (2 + 16));

To set pin PA6 to low, write 1 into bit 22 of GPIOA_BSRR:

GPIOA->BSRR = (1 << (6 + 16));

You may have spotted a pattern here, too; again, try to write a macro or a function.

You may want to read this intro.

JW

 

RCC->AHB1ENR |= (1<<0)|(1<<2);  // enable A and C port
RCC->APB1ENR |= (1<<17); // enable USART2

GPIOA->MODER |= (1<<0)|(1<<4)|(1<<12); // set A0, A2, A6 as output
GPIOC->MODER |= (1<<26); // set PC13 as output

GPIOA->BSRR = (1 << 2);
GPIOA->BSRR = (1 << 6);

GPIOC->BSRR = (1 << (13 + 16));

while (1)
{
	GPIOA->BSRR = (1 << 0);
	delayMs(50);

	GPIOA->BSRR = (1 << (0 + 16));
	delayMs(50);
}

 

Thank you for your answer.

 

Result:

PC13 is glowing

PA0 "toggled" - but the stepper motor does not drive... thank you in spite of it ...

Perhaps for interested people, my trial-stand for controlling a stepper motor ...

 

But the stepper motor does not drive at the moment ...