Skip to main content
parisa
Associate III
February 11, 2020
Question

STM32F103 is not fast enough

  • February 11, 2020
  • 7 replies
  • 2027 views

Hello,

Here is my code,

#include <stdio.h>
#include <string.h>
 
 
void GPIOSYS(void){
		GPIO_InitTypeDef GPIOSt;
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
		//GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
		GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
		GPIOSt.GPIO_Mode=GPIO_Mode_Out_PP;
		GPIOSt.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_0|GPIO_Pin_1;
		GPIOSt.GPIO_Speed=GPIO_Speed_50MHz;
		GPIO_Init(GPIOB,&GPIOSt);	
	
	
	
		GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		GPIOSt.GPIO_Mode=GPIO_Mode_Out_PP;
		GPIOSt.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;
		GPIOSt.GPIO_Speed=GPIO_Speed_50MHz;
		GPIO_Init(GPIOA,&GPIOSt);	
	
}
 
void CLOCK(void){
	RCC_HSEConfig(RCC_HSE_ON);
	while(RCC_WaitForHSEStartUp()==ERROR);
	
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,9);
	RCC_PLLCmd(ENABLE);
	
	while(RCC_GetFlagStatus( RCC_FLAG_PLLRDY)!=SET);
	
	RCC_ClockSecuritySystemCmd(ENABLE);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	
	while (RCC_GetSYSCLKSource() != 0x08);
	
}
 
void Delay(){
	int i,j;
	for(i=0;i<10000;i++)
	for(j=0;j<250;j++);
}
 
int main(void){
	CLOCK();
	GPIOSYS();
	
	while(1){
			GPIO_ResetBits(GPIOB,GPIO_Pin_6);
			GPIO_ResetBits(GPIOB,GPIO_Pin_7);
		
			GPIO_ResetBits(GPIOA,GPIO_Pin_2);
			GPIO_ResetBits(GPIOA,GPIO_Pin_3);
		
			//Delay();		
			GPIO_SetBits(GPIOB,GPIO_Pin_6);
			GPIO_SetBits(GPIOB,GPIO_Pin_7);			
		
			GPIO_SetBits(GPIOA,GPIO_Pin_2);
			GPIO_SetBits(GPIOA,GPIO_Pin_3);
			//Delay();
	}
	
}
 

I see a 500Khz pulse train on my oscilloscope which is below my expectations( for a 72Mhz MCU). Did I make a mistake or it is usual?

Thanks

This topic has been closed for replies.

7 replies

Ozone
Principal
February 11, 2020

> while(1){

> GPIO_ResetBits(GPIOB,GPIO_Pin_6);

> GPIO_ResetBits(GPIOB,GPIO_Pin_7);

>

> GPIO_ResetBits(GPIOA,GPIO_Pin_2);

> GPIO_ResetBits(GPIOA,GPIO_Pin_3);

>

> //Delay();

> GPIO_SetBits(GPIOB,GPIO_Pin_6);

> GPIO_SetBits(GPIOB,GPIO_Pin_7);

>

> GPIO_SetBits(GPIOA,GPIO_Pin_2);

> GPIO_SetBits(GPIOA,GPIO_Pin_3);

> //Delay();

> }

What do you want to achieve with that ???

Use a timer, and set it up for PWM.

Honestly, all Cortex M have semi-autonomous peripherals, the 8051/PIC18 busy-looping-pin-toggle code is not a use case they are designed for.

> I see a 500Khz pulse train on my oscilloscope which is below my expectations( for a 72Mhz MCU)

Peripheral clock is not core clock. Read the datasheet/reference manual.

Enable full compiler optimization, or code in assembler.

parisa
parisaAuthor
Associate III
February 11, 2020

Thank you so much for your comment.

I need to do bit-bang in order to send/receive bits from another source(Speed 1Mhz up to 2Mhz). I tried to do it with a timer but for 1us delay timers are not a good choice. By using a PWM source, I can't count the input/output bits correctly. what do you suggest?

Danish1
Lead III
February 11, 2020

What's the protocol? A USART might help. Or SPI. And what's the necessary speed?

If it's a more-complicated but bursty protocol, you can use DMA driven off a timer either to read a GPIO IDR or write to a GPIO BSRR. ST have given examples for emulating a UART on GPIO pins. You then just use your processor to set up or analyse what the DMA handles.

Hope this helps,

Danish

berendi
Principal
February 11, 2020

What kind of protocol is that? It might be possible to trick SPI into receiving, or use a timer DMA channel to read from GPIO.

parisa
parisaAuthor
Associate III
February 11, 2020

I really thank you for your comment and help.

I send data(20bits) bit by bit (MSB first) (such as a pulse train). In receiver (my stm32f103) I need to read them correctly(such as SPI I send clock and then read input bits). My problems by using the popular protocol are

1)For using USART/UART, data is between start and stop bits and is divided into 8-16 bits which interruptions for start/stop bits and also this separation is not acceptable in my transmission.

2)For SPI, data is divided into one or two bytes and between each bytes we have another delay(another interruption). Clock stay at a specific value for small amount of time.

So, in this transmission, I need to send a clock for reading each bit each 1us. A 1us timer paralyzed the CPU. DMA is a good way if it can do this scenario.

Ozone
Principal
February 11, 2020

> 2)For SPI, data is divided into one or two bytes and between each bytes we have another delay(another interruption). Clock stay at a specific value for small amount of time.

Most STM32 devices do not allow SPI transfer sizes which are not multiples of 8 (8, 16, 24).

Short of looking at other Cortex M families (outside the ST world ;-O) ), you might consider external hardware (standard logic / shift registers).

parisa
parisaAuthor
Associate III
February 11, 2020

Thank you for your comment.

I need to implement this kind of shift register under STM32 because I think that STM32 are a good choice to have this communication and also do some other functions

Ozone
Principal
February 11, 2020

The F103 is a relatively old M3 core.

You migth check newer STM32s, they use to have more flexible peripherals, perhaps you find one that can be tailored for your protocol (supposedly similar to SPI or I2S). More core performance included.

I lost track of the very latest cores, I stick to those one supported by the abandoned SPL lib, and ignore the ... Cube stuff.

> ...because I think that STM32 are a good choice to have this communication and also do some other functions

You can't really say unless you know alternatives.

My company uses whatever MCU is convenient for the purpose.

So do I for my private projects.

Piranha
Principal III
February 11, 2020

20 bits without pauses can be sent and received with SAI peripheral, which is present on F4, L4, G4 and higher series. :)

parisa
parisaAuthor
Associate III
February 11, 2020

Thank you so much.

I need to know there is no way to speed up setting ports more than 1Mhz on Stm32f103 because my board is fixed and I can't changed any hardware.

Ozone
Principal
February 11, 2020

GPIO input/output is filtered. Select a different (higher) speed maximum.

See the reference manual, sect. 9.1, Table 21 (output MODE bits).

Write directly to the BSRR register of the GPIO port (sect. 9.2.5, port set/reset register) of the reference manual.

https://www.st.com/resource/en/reference_manual/cd00171190.pdf

parisa
parisaAuthor
Associate III
February 11, 2020

Thank you very much, Did not I set the maximum speed? (GPIOSt.GPIO_Speed=GPIO_Speed_50MHz;) or it is something else?