2
\$\begingroup\$

As per the datasheet of STM32F103C8T6, its GPIO pins has a hardware speed limitation of 50MHz. I need to achieve speed above 10MHz, but even with assembly codes I am getting only 7.99MHz.

It is running at the maximum recommended speed of 72MHz (8MHz Crystal + PLL).

Can anyone guide me ? Please check the following assembly language loop I am using for toggling the GPIO pins.

 asm(".equ GPIOB_ODR, 0x4001080C");
 asm("ldr r6, = GPIOB_ODR");

 asm("loop:");
 asm("mov r1, #0xFFFFFFFF");
 asm("strh r1, [r6]");
 asm("mov r1, #0x00000000");
 asm("strh r1, [r6]");
 asm("b loop");
\$\endgroup\$
8
  • \$\begingroup\$ You should use a timer. \$\endgroup\$
    – Jeroen3
    Commented Jul 21, 2017 at 10:49
  • 2
    \$\begingroup\$ Even if each one of those instructions took one cycle, you'd only get 12MHz. What are you trying to achieve with this? Are you simply wanting to produce a square wave? If so, you need to use a PWM. Using this method your processor would be doing nothing but being a square wave generator! \$\endgroup\$
    – DiBosco
    Commented Jul 21, 2017 at 10:52
  • \$\begingroup\$ Can you please explain the reason for the above behaviour ? If the above code is executing at 72MHz, GPIO output frequency has to be much higher right ? \$\endgroup\$ Commented Jul 21, 2017 at 10:52
  • 4
    \$\begingroup\$ Imagine if each instruction took once cycle (which they won't). That's 13.9ns per instruction. Six instructions would take 83.3ns which would give you 12MHz. Now go look up how many cycles each of these instructions actually takes and do the maths. \$\endgroup\$
    – DiBosco
    Commented Jul 21, 2017 at 10:54
  • 1
    \$\begingroup\$ The first question, what is that you want to do exactly with this GPIO? \$\endgroup\$ Commented Jul 21, 2017 at 11:41

3 Answers 3

4
\$\begingroup\$

You have a couple of better options for driving GPIO pins:

  • Timers. On this part, you have seven timers, most of which can be configured to set/reset/toggle pins on certain events (such as compare match and overflow).

  • DMA. Set up a DMA transfer to the GPIO bit-set/reset register and you can toggle bits at bus speed. Or you can hook it up to a timer to set bits at whatever rate you want.

  • Creative uses of other peripherals. USART and SPI/I2S seem like particularly likely candidates.

\$\endgroup\$
2
\$\begingroup\$

Your method:

:loop
MOV R1, #0xFFFFFFFF  ; 1 cycle
STRH R1, [R6]        ; 2 cycles
MOV R1, #0x00000000  ; 1 cycle
STRH R1, [R6]        ; 2 cycles
b loop               ; 3 cycles

The fastest the core can write registers:

MOV R3, #0xFFFFFFFF
MOV R4, #0x00000000
:loop
STRH R3, [R6]
STRH R4, [R6]
b loop

Note: GPIO is APB2, thus 36 MHz bus. You can never exceed 36 MHz.

A timer however can oscillate the pin at sysclk/2. (often 72/2 Mhz)

To get 10 MHz at an output you'd need to clock the core at a multiple of 10 with the PLL, since you can't divide the clock by 7.2 at the timers.

The datasheet number maximum Fmax(IO)out of 50 MHz is the hardware limit. The GPIO hardware cannot achieve a slope fast enough to go higher.
You can configure the slew rate of outputs, for example, it would be unnecessary to blink a led with slopes of 10 ns. But it would be necessary for high speed external memory.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you very much for the suggestion. With this I can achive 11.9MHz. I have one doubt. In the datasheet, I have seen that GPIO pins maximum output frequency is 50MHz. If it is not achievable, what is its use ? \$\endgroup\$ Commented Jul 21, 2017 at 12:16
  • \$\begingroup\$ @LigoGeorge The actual driving hardware is limited to 50 MHz. (I've added this to answer) \$\endgroup\$
    – Jeroen3
    Commented Jul 21, 2017 at 17:26
1
\$\begingroup\$
MOV R3, #0xFFFFFFFF
MOV R4, #0x00000000
:loop
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
STRH R3, [R6]
STRH R4, [R6]
b loop

do this to redude delay of loop

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.